summaryrefslogtreecommitdiff
path: root/honey/ecs.lua
diff options
context:
space:
mode:
Diffstat (limited to 'honey/ecs.lua')
-rw-r--r--honey/ecs.lua93
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