summaryrefslogtreecommitdiff
path: root/honey/ecs.lua
diff options
context:
space:
mode:
Diffstat (limited to 'honey/ecs.lua')
-rw-r--r--honey/ecs.lua97
1 files changed, 96 insertions, 1 deletions
diff --git a/honey/ecs.lua b/honey/ecs.lua
index ef682b5..3bdf850 100644
--- a/honey/ecs.lua
+++ b/honey/ecs.lua
@@ -23,7 +23,8 @@ function Filter.new(_, operation, tbl)
end
end
- return function(entity)
+ return function(entity, _self)
+ local entity = _self or entity -- able to call as . or :
return Filter.check(self, entity)
end
end
@@ -97,4 +98,98 @@ function Filter.checkNOR(self, entity)
end
+--===== worlds =====--
+
+World = {}
+World.__index = World
+
+function World.new(_)
+ local self = {}
+ self.systems = {}
+ self.entities = {}
+ setmetatable(self, World)
+ return self
+end
+setmetatable(World, {__call=World.new})
+
+
+local function systemLt(a, b)
+ return (a.priority or 50) < (b.priority or 50)
+end
+function World.addSystem(self, system)
+ assert(system.update, "systems must have an 'update' key")
+ assert(system.filter, "systems must have a 'filter' key")
+ system.entities = {}
+ table.insert(self.systems, system)
+ table.sort(self.systems, systemLt)
+end
+
+
+local function addEntityToSystem(system, entity)
+ -- check if entity is already present
+ if system.entities[entity] then return end
+
+ if system.onAddEntity then
+ system.onAddEntity(entity)
+ end
+ system.entities[entity] = true
+end
+
+
+local function removeEntityFromSystem(system, entity)
+ -- check if entity is already absent
+ if not system.entities[entity] then return end
+
+ if system.onRemoveEntity then
+ system.onRemoveEntity(entity)
+ end
+ system.entities[entity] = nil
+end
+
+
+function World.addEntity(self, entity)
+ self.entities[entity] = true
+ for _, system in ipairs(self.systems) do
+ if system.filter(entity) then
+ addEntityToSystem(system, entity)
+ end
+ end
+end
+
+
+function World.reconfigureEntity(self, entity)
+ for _, system in ipairs(self.systems) do
+ if system.filter(entity) then
+ addEntityToSystem(system, entity)
+ else
+ removeEntityFromSystem(system, entity)
+ end
+ end
+end
+
+
+function World.removeEntity(self, entity)
+ self.entities[entity] = nil
+ for _, system in ipairs(self.systems) do
+ removeEntityFromSystem(system, entity)
+ end
+end
+
+
+function World.reconfigureAllEntities(self)
+ for entity in pairs(self.entities) do
+ self:reconfigureEntity(entity)
+ end
+end
+
+
+function World.update(self, dt)
+ for _, system in ipairs(self.systems) do
+ for entity in pairs(system.entities) do
+ system.update(entity, dt)
+ end
+ end
+end
+
+
return module