diff options
author | sanine <sanine.not@pm.me> | 2023-03-16 12:12:39 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-03-16 12:12:39 -0500 |
commit | d94d9fb122e42264eca20bb037fe8a82290bd3e2 (patch) | |
tree | 7cb5b0ffd657ba69e193b4f2af6f1ddd3ec75ed2 /honey/ecs.lua | |
parent | 7516044247663dabccc7db110703cfcf8545d95f (diff) |
implement ecs node cascading
Diffstat (limited to 'honey/ecs.lua')
-rw-r--r-- | honey/ecs.lua | 97 |
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 |