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
-- with default Entities and Systems.
function tiny.world(...)
local ret = {
local ret = setmetatable({
-- List of Entities to add
entitiesToAdd = {},
@ -370,13 +370,13 @@ function tiny.world(...)
-- List of Systems
systems = {}
}
}, worldMetaTable)
tiny_add(ret, ...)
tiny_manageSystems(ret)
tiny_manageEntities(ret)
return setmetatable(ret, worldMetaTable), ...
return ret, ...
end
--- 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.
function tiny_manageSystems(world)
local s2a, s2r = world.systemsToAdd, world.systemsToRemove
local s2a, s2r = world.systemsToAdd, world.systemsToRemove
-- Early exit
if #s2a == 0 and #s2r == 0 then
return
end
-- Early exit
if #s2a == 0 and #s2r == 0 then
return
end
local entities = world.entities
local systems = world.systems
local system, index, filter
local entityList, entityIndices, entityIndex, onRemove, onAdd
world.systemsToAdd = {}
world.systemsToRemove = {}
-- Remove Systems
for i = 1, #s2r do
system = s2r[i]
index = system.index
if system.world == world then
onRemove = system.onRemove
if onRemove then
entityList = system.entities
for j = 1, #entityList do
onRemove(system, entityList[j])
end
end
tremove(systems, index)
for j = index, #systems do
systems[j].index = j
local entities = world.entities
local systems = world.systems
local system, index, filter
local entityList, entityIndices, entityIndex, onRemove, onAdd
-- Remove Systems
for i = 1, #s2r do
system = s2r[i]
index = system.index
if system.world == world then
onRemove = system.onRemove
if onRemove then
entityList = system.entities
for j = 1, #entityList do
onRemove(system, entityList[j])
end
end
s2r[i] = nil
-- Clean up System
system.world = nil
system.entities = nil
system.indices = nil
system.index = nil
tremove(systems, index)
for j = index, #systems do
systems[j].index = j
end
end
s2r[i] = nil
-- Add Systems
for i = 1, #s2a do
system = s2a[i]
if systems[system.index] ~= system then
entityList = {}
entityIndices = {}
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
-- Clean up System
system.world = nil
system.entities = nil
system.indices = nil
system.index = nil
end
-- 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
-- Add Systems
for i = 1, #s2a do
system = s2a[i]
if systems[system.index] ~= system then
entityList = {}
entityIndices = {}
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
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
s2a[i] = nil
end
s2a[i] = nil
end
end
-- Adds and removes Entities that have been marked.
function tiny_manageEntities(world)
local e2a, e2r = world.entitiesToAdd, world.entitiesToRemove
-- Early exit
@ -538,6 +542,9 @@ function tiny_manageEntities(world)
return
end
world.entitiesToAdd = {}
world.entitiesToRemove = {}
local entities = world.entities
local systems = world.systems
local entityCount = world.entityCount
@ -696,9 +703,7 @@ end
--- 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
-- processed first. If 'index' < 0, then sets 'index' relative to the last 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.
-- processed first. Returns the old system.index.
function tiny.setSystemIndex(world, system, index)
local oldIndex = system.index
local systems = world.systems
@ -734,7 +739,10 @@ worldMetaTable = {
getSystemCount = tiny.getSystemCount,
getSystemIndex = tiny.getSystemIndex,
setSystemIndex = tiny.setSystemIndex
}
},
__tostring = function(self)
return "tiny-ecs_World"
end
}
return tiny