diff options
Diffstat (limited to 'honey/ecs.lua')
-rw-r--r-- | honey/ecs.lua | 93 |
1 files changed, 87 insertions, 6 deletions
diff --git a/honey/ecs.lua b/honey/ecs.lua index 8aa5c5c..72cc41d 100644 --- a/honey/ecs.lua +++ b/honey/ecs.lua @@ -84,6 +84,7 @@ end setmetatable(EntityDb, {__call=EntityDb.new}) +-- check if a given entity id is legitimate function EntityDb.checkIsValid(self, id) if not self.entities[id] then error(string.format("invalid entity id: %s", tostring(id))) @@ -91,22 +92,29 @@ function EntityDb.checkIsValid(self, id) end -local function uid() - local template ='xxxx:xxxx:xxxx' - return string.gsub(template, 'x', function (c) - local v = math.random(0, 0xf) +local random = math.random +local function uuid() + local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' + return string.gsub(template, '[xy]', function (c) + local v = (c == 'x') and random(0, 0xf) or random(8, 0xb) return string.format('%x', v) end) end -function EntityDb.createEntity(self) - local id = uid() + + +-- create a new entity +function EntityDb.createEntity(self, id) + local id = id or uuid() -- allow inserting entities at preset ids for loading self.entities[id] = true return id end +-- add a component to an entity function EntityDb.addComponent(self, id, name, value) self:checkIsValid(id) + + -- create the relevant component table if it doesn't exist if not self.components[name] then self.components[name] = { count=0 } end @@ -124,6 +132,7 @@ local function shallowCopy(tbl) end +-- get all entities with a given component function EntityDb.queryComponent(self, name) local query = shallowCopy(self.components[name]) query.count = nil @@ -131,6 +140,7 @@ function EntityDb.queryComponent(self, name) end +-- get all components associated with an entity function EntityDb.queryEntity(self, id) self:checkIsValid(id) local query = {} @@ -141,6 +151,14 @@ function EntityDb.queryEntity(self, id) end +-- get a specific component from an entity +function EntityDb.getComponent(self, id, name) + self:checkIsValid(id) + return self.components[name][id] +end + + +-- remove a component from an entity function EntityDb.removeComponent(self, id, name) self:checkIsValid(id) local component = self.components[name] @@ -154,6 +172,7 @@ function EntityDb.removeComponent(self, id, name) end +-- remove an entity from the db function EntityDb.deleteEntity(self, id) self:checkIsValid(id) for name in pairs(self.components) do @@ -162,4 +181,66 @@ function EntityDb.deleteEntity(self, id) self.entities[id] = nil end + +--===== SystemDb =====-- + +SystemDb = {} +SystemDb.__index = SystemDb + + +function SystemDb.new(_) + local self = { + systems = {}, + sorted = {}, + } + setmetatable(self, SystemDb) + return self +end +setmetatable(SystemDb, {__call=SystemDb.new}) + + +local function systemId() + local template = "xx:xx:xx" + return string.gsub(template, "x", function(c) + return string.format("%x", random(0, 0xf)) + end) +end + + +function SystemDb.addSystem(self, systemFunc, params) + local system + if type(systemFunc) == "table" then + system = systemFunc + else + system = systemFunc(params) + end + + local id = systemId() + self.systems[id] = system + table.insert(self.sorted, id) + self:sort() + return id +end + + +function SystemDb.sort(self) + table.sort(self.sorted, function(a, b) return (self.systems[a].priority or 100) < (self.systems[b].priority or 100) end) +end + + +function SystemDb.update(self, dt) + for _, system in ipairs(self.sorted) do + self.systems[system]:update(dt) + end +end + + +function SystemDb.removeSystem(self, id) + self.systems[id] = nil + for i=#self.sorted,1,-1 do + if self.sorted[i] == id then table.remove(self.sorted, i) end + end +end + + return module |