From ecb3c2db7e3f911f16924be26e94ff08ce596381 Mon Sep 17 00:00:00 2001 From: Tjakka5 Date: Sun, 22 Dec 2019 21:00:53 +0100 Subject: [PATCH] Cache added and removed components --- main.lua | 13 +++++++++---- src/component.lua | 5 ++++- src/entity.lua | 46 +++++++++++++++++++++++++++++++++++++++++----- src/world.lua | 21 +++++++++++++-------- 4 files changed, 67 insertions(+), 18 deletions(-) diff --git a/main.lua b/main.lua index 392a4f0..6b9f293 100644 --- a/main.lua +++ b/main.lua @@ -35,11 +35,12 @@ end) local test_system = System("test_system", {Components.test_comp_1}) -local function onEntityAdded(e) -- luacheck: ignore - print("Added") +local function onEntityAdded(pool, e) -- luacheck: ignore + local test_comp = e:get(Components.test_comp_1) + print(test_comp.x) end -local function onEntityRemoved(e) -- luacheck: ignore +local function onEntityRemoved(pool, e) -- luacheck: ignore print("Removed") end @@ -64,7 +65,11 @@ end local world = World("testWorld") local entity = Entity() -entity:give(Components.test_comp_1, 100, 100) +entity +:give(Components.test_comp_1, 100, 100) +:remove(Components.test_comp_1) +:give(Components.test_comp_1, 200, 100) + Worlds.testWorld:addEntity(entity) diff --git a/src/component.lua b/src/component.lua index e7b3d90..e1ef5aa 100644 --- a/src/component.lua +++ b/src/component.lua @@ -38,7 +38,10 @@ end -- @return A new initialized Bag function Component:__initialize(...) if self.__populate then - local bag = setmetatable({}, self) + local bag = setmetatable({ + __baseComponent = self, + }, self) + self.__populate(bag, ...) return bag diff --git a/src/entity.lua b/src/entity.lua index 14619cf..5bfc88e 100644 --- a/src/entity.lua +++ b/src/entity.lua @@ -13,9 +13,13 @@ function Entity.new() local e = setmetatable({ world = nil, + __addedComponents = {}, + __removedComponents = {}, + __operations = {}, + __components = {}, - __isDirty = true, + __isDirty = false, __wasAdded = false, __wasRemoved = false, @@ -25,18 +29,30 @@ function Entity.new() return e end -local function give(e, baseComponent, ...) - local component = baseComponent:__initialize(...) +local function giveOperation(e, component) + local baseComponent = component.__baseComponent e[baseComponent] = component e.__components[baseComponent] = component +end + +local function removeOperation(e, baseComponent) + e[baseComponent] = nil + e.__components[baseComponent] = nil +end + +local function give(e, baseComponent, ...) + local component = baseComponent:__initialize(...) + + e.__addedComponents[#e.__addedComponents + 1] = component + e.__operations[#e.__operations + 1] = giveOperation e.__isDirty = true end local function remove(e, baseComponent) - e[baseComponent] = nil - e.__components[baseComponent] = nil + e.__removedComponents[#e.__removedComponents + 1] = baseComponent + e.__operations[#e.__operations + 1] = removeOperation e.__isDirty = true end @@ -92,6 +108,26 @@ function Entity:assemble(assemblage, ...) return self end +function Entity:flush() + local addi, removei = 1, 1 + + for i = 1, #self.__operations do + local operation = self.__operations[i] + + if (operation == giveOperation) then + operation(self, self.__addedComponents[addi]) + self.__addedComponents[addi] = nil + addi = addi + 1 + elseif (operation == removeOperation) then + operation(self, self.__removedComponents[removei]) + self.__removedComponents[removei] = nil + removei = removei + 1 + end + + self.__operations[i] = nil + end +end + --- Destroys the Entity. -- @return self function Entity:destroy() diff --git a/src/world.lua b/src/world.lua index 50377d7..8a47aea 100644 --- a/src/world.lua +++ b/src/world.lua @@ -75,9 +75,20 @@ function World:flush() for i = 1, self.entities.size do e = self.entities:get(i) + if e.__isDirty then + e:flush() + + if (not e.__wasAdded) then -- The __wasAdded check below will handle this instead + for j = 1, self.systems.size do + self.systems:get(j):__evaluate(e) + end + end + + e.__isDirty = false + end + if e.__wasAdded then e.__wasAdded = false - e.__isDirty = false for j = 1, self.systems.size do self.systems:get(j):__evaluate(e) @@ -95,14 +106,8 @@ function World:flush() end e.__wasRemoved = false - end - if e.__isDirty then - for j = 1, self.systems.size do - self.systems:get(j):__evaluate(e) - end - - e.__isDirty = false + self:onEntityRemoved(e) end end