From a45f73c7388b3f5a5901bfcc66fd2d1df58d3001 Mon Sep 17 00:00:00 2001 From: sanine Date: Wed, 22 Mar 2023 10:02:47 -0500 Subject: add update function system --- honey/ecs.lua | 68 ++++++++++++++++++++++++++++++++++------------------------- main.lua | 43 +++++++++++++++++++------------------ 2 files changed, 61 insertions(+), 50 deletions(-) diff --git a/honey/ecs.lua b/honey/ecs.lua index 3bdf850..4eee343 100644 --- a/honey/ecs.lua +++ b/honey/ecs.lua @@ -98,25 +98,26 @@ function Filter.checkNOR(self, entity) end ---===== worlds =====-- +--===== levels =====-- -World = {} -World.__index = World +Level = {} +Level.__index = Level -function World.new(_) +function Level.new(_) local self = {} self.systems = {} self.entities = {} - setmetatable(self, World) + self.nextId = 1 + setmetatable(self, Level) return self end -setmetatable(World, {__call=World.new}) +setmetatable(Level, {__call=Level.new}) local function systemLt(a, b) return (a.priority or 50) < (b.priority or 50) end -function World.addSystem(self, system) +function Level.addSystem(self, system) assert(system.update, "systems must have an 'update' key") assert(system.filter, "systems must have a 'filter' key") system.entities = {} @@ -125,67 +126,76 @@ function World.addSystem(self, system) end -local function addEntityToSystem(system, entity) +local function addEntityToSystem(system, id, entity) -- check if entity is already present - if system.entities[entity] then return end + if system.entities[id] then return end if system.onAddEntity then - system.onAddEntity(entity) + system.onAddEntity(id, entity) end - system.entities[entity] = true + system.entities[id] = true end -local function removeEntityFromSystem(system, entity) +local function removeEntityFromSystem(system, id, entity) -- check if entity is already absent - if not system.entities[entity] then return end + if not system.entities[id] then return end if system.onRemoveEntity then - system.onRemoveEntity(entity) + system.onRemoveEntity(id, entity) end - system.entities[entity] = nil + system.entities[id] = nil end -function World.addEntity(self, entity) - self.entities[entity] = true +function Level.addEntity(self, entity) + table.insert(self.entities, entity) + local id = self.nextId + self.nextId = id + 1 + for _, system in ipairs(self.systems) do if system.filter(entity) then - addEntityToSystem(system, entity) + addEntityToSystem(system, id, entity) end end + + return id end -function World.reconfigureEntity(self, entity) +function Level.reconfigureEntity(self, id) + local entity = self.entities[id] + for _, system in ipairs(self.systems) do if system.filter(entity) then - addEntityToSystem(system, entity) + addEntityToSystem(system, id, entity) else - removeEntityFromSystem(system, entity) + removeEntityFromSystem(system, id, entity) end end end -function World.removeEntity(self, entity) - self.entities[entity] = nil +function Level.removeEntity(self, id) + local entity = self.entities[id] for _, system in ipairs(self.systems) do - removeEntityFromSystem(system, entity) + removeEntityFromSystem(system, id, entity) end + self.entities[id] = nil end -function World.reconfigureAllEntities(self) - for entity in pairs(self.entities) do - self:reconfigureEntity(entity) +function Level.reconfigureAllEntities(self) + for id in ipairs(self.entities) do + self:reconfigureEntity(id) end end -function World.update(self, dt) +function Level.update(self, dt) for _, system in ipairs(self.systems) do - for entity in pairs(system.entities) do + for id in pairs(system.entities) do + local entity = self.entities[id] system.update(entity, dt) end end diff --git a/main.lua b/main.lua index c9b1733..251f466 100644 --- a/main.lua +++ b/main.lua @@ -34,16 +34,16 @@ function recursiveComputeTransform(entity) return entity._transform end -local world = ecs.World() +local level = ecs.Level() -- update transforms -world:addSystem{ +level:addSystem{ filter=ecs.Filter.AND{"transform", "parent"}, update=function(entity, dt) recursiveComputeTransform(entity) end, priority=1, } -world:addSystem{ +level:addSystem{ filter=ecs.Filter.AND{"transform", "parent"}, update=function(entity, dt) entity._transform = nil @@ -53,7 +53,7 @@ world:addSystem{ } -- render objects -world:addSystem{ +level:addSystem{ filter=ecs.Filter.AND{"mesh", "shader", "transform"}, update=function(entity, dt) entity.shader:use() @@ -69,7 +69,14 @@ world:addSystem{ priority=99, } - +-- run custom scripts +level:addSystem{ + filter=ecs.Filter.AND{"update"}, + update=function(entity, dt) + entity.update(entity, dt) + end, + priority=50, +} @@ -132,6 +139,12 @@ local dodeca = honey.mesh.loadFile("assets/dodecahedron.obj")[1] local icosa = honey.mesh.loadFile("assets/icosahedron.obj")[1] +function updateTransform(self, dt) + self.transform:rotateY(0.3 * math.pi * dt) + self.transform:rotateX(0.1 * math.pi * dt) +end + + function growLine(prev, depth) if depth == 0 then return prev end @@ -139,10 +152,11 @@ function growLine(prev, depth) transform=Mat4.Identity(), mesh=octa, shader=shader, + update=updateTransform, } entity.transform:translate(Vec3{2, 0, 0}) prev.parent = entity - world:addEntity(prev) + level:addEntity(prev) return growLine(entity, depth-1) end @@ -154,18 +168,7 @@ local leaf = { } local root = growLine(leaf, 24) root.parent = false -world:addEntity(root) - - -function updateTransforms(dt) - local entity = leaf - while entity ~= false do - entity.transform:rotateY(0.3 * math.pi * dt) - entity.transform:rotateX(0.1 * math.pi * dt) - entity = entity.parent - end -end - +level:addEntity(root) window:setKeyCallback(function(_, key) @@ -182,12 +185,10 @@ while not window:shouldClose() do local dt = time - prevTime prevTime = time - updateTransforms(dt) - gl.ClearColor(0.2, 0.4, 1.0, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT + gl.DEPTH_BUFFER_BIT) - world:update(dt) + level:update(dt) window:swapBuffers() glfw.PollEvents() -- cgit v1.2.1