Fix Adding systems and items to the world inside a call to system:onAdd()

This commit is contained in:
bakpakin 2015-08-24 12:52:11 -04:00
parent a5af4b6ecd
commit 9834dfa9d6

142
tiny.lua
View File

@ -348,7 +348,7 @@ local worldMetaTable
-- Can optionally add default Systems and Entities. Returns the new World along -- Can optionally add default Systems and Entities. Returns the new World along
-- with default Entities and Systems. -- with default Entities and Systems.
function tiny.world(...) function tiny.world(...)
local ret = { local ret = setmetatable({
-- List of Entities to add -- List of Entities to add
entitiesToAdd = {}, entitiesToAdd = {},
@ -370,13 +370,13 @@ function tiny.world(...)
-- List of Systems -- List of Systems
systems = {} systems = {}
} }, worldMetaTable)
tiny_add(ret, ...) tiny_add(ret, ...)
tiny_manageSystems(ret) tiny_manageSystems(ret)
tiny_manageEntities(ret) tiny_manageEntities(ret)
return setmetatable(ret, worldMetaTable), ... return ret, ...
end end
--- Adds an Entity to the world. --- Adds an Entity to the world.
@ -454,83 +454,87 @@ tiny_remove = tiny.remove
-- Adds and removes Systems that have been marked from the World. -- Adds and removes Systems that have been marked from the World.
function tiny_manageSystems(world) function tiny_manageSystems(world)
local s2a, s2r = world.systemsToAdd, world.systemsToRemove local s2a, s2r = world.systemsToAdd, world.systemsToRemove
-- Early exit -- Early exit
if #s2a == 0 and #s2r == 0 then if #s2a == 0 and #s2r == 0 then
return return
end end
local entities = world.entities world.systemsToAdd = {}
local systems = world.systems world.systemsToRemove = {}
local system, index, filter
local entityList, entityIndices, entityIndex, onRemove, onAdd
-- Remove Systems local entities = world.entities
for i = 1, #s2r do local systems = world.systems
system = s2r[i] local system, index, filter
index = system.index local entityList, entityIndices, entityIndex, onRemove, onAdd
if system.world == world then
onRemove = system.onRemove -- Remove Systems
if onRemove then for i = 1, #s2r do
entityList = system.entities system = s2r[i]
for j = 1, #entityList do index = system.index
onRemove(system, entityList[j]) if system.world == world then
end onRemove = system.onRemove
end if onRemove then
tremove(systems, index) entityList = system.entities
for j = index, #systems do for j = 1, #entityList do
systems[j].index = j onRemove(system, entityList[j])
end end
end end
s2r[i] = nil tremove(systems, index)
for j = index, #systems do
-- Clean up System systems[j].index = j
system.world = nil end
system.entities = nil
system.indices = nil
system.index = nil
end end
s2r[i] = nil
-- Add Systems -- Clean up System
for i = 1, #s2a do system.world = nil
system = s2a[i] system.entities = nil
if systems[system.index] ~= system then system.indices = nil
entityList = {} system.index = nil
entityIndices = {} end
system.entities = entityList
system.indices = entityIndices
if system.active == nil then
system.active = true
end
system.modified = true
system.world = world
index = #systems + 1
system.index = index
systems[index] = system
-- Try to add Entities -- Add Systems
onAdd = system.onAdd for i = 1, #s2a do
filter = system.filter system = s2a[i]
if filter then if systems[system.index] ~= system then
for entity in pairs(entities) do entityList = {}
if filter(system, entity) then entityIndices = {}
entityIndex = #entityList + 1 system.entities = entityList
entityList[entityIndex] = entity system.indices = entityIndices
entityIndices[entity] = entityIndex if system.active == nil then
if onAdd then system.active = true
onAdd(system, entity) end
end system.modified = true
system.world = world
index = #systems + 1
system.index = index
systems[index] = system
-- Try to add Entities
onAdd = system.onAdd
filter = system.filter
if filter then
for entity in pairs(entities) do
if filter(system, entity) then
entityIndex = #entityList + 1
entityList[entityIndex] = entity
entityIndices[entity] = entityIndex
if onAdd then
onAdd(system, entity)
end end
end end
end end
end end
s2a[i] = nil
end end
s2a[i] = nil
end
end end
-- Adds and removes Entities that have been marked. -- Adds and removes Entities that have been marked.
function tiny_manageEntities(world) function tiny_manageEntities(world)
local e2a, e2r = world.entitiesToAdd, world.entitiesToRemove local e2a, e2r = world.entitiesToAdd, world.entitiesToRemove
-- Early exit -- Early exit
@ -538,6 +542,9 @@ function tiny_manageEntities(world)
return return
end end
world.entitiesToAdd = {}
world.entitiesToRemove = {}
local entities = world.entities local entities = world.entities
local systems = world.systems local systems = world.systems
local entityCount = world.entityCount local entityCount = world.entityCount
@ -696,9 +703,7 @@ end
--- Sets the index of a System in the World, and returns the old index. Changes --- Sets the index of a System in the World, and returns the old index. Changes
-- the order in which they Systems processed, because lower indexed Systems are -- the order in which they Systems processed, because lower indexed Systems are
-- processed first. If 'index' < 0, then sets 'index' relative to the last index -- processed first. Returns the old system.index.
-- in the World; -1 is the index of the last System, -2 is the second to last,
-- and so on. Returns the old system.index.
function tiny.setSystemIndex(world, system, index) function tiny.setSystemIndex(world, system, index)
local oldIndex = system.index local oldIndex = system.index
local systems = world.systems local systems = world.systems
@ -734,7 +739,10 @@ worldMetaTable = {
getSystemCount = tiny.getSystemCount, getSystemCount = tiny.getSystemCount,
getSystemIndex = tiny.getSystemIndex, getSystemIndex = tiny.getSystemIndex,
setSystemIndex = tiny.setSystemIndex setSystemIndex = tiny.setSystemIndex
} },
__tostring = function(self)
return "tiny-ecs_World"
end
} }
return tiny return tiny