Fix cycles (#129)

This commit is contained in:
Marcus 2024-09-20 21:58:18 +02:00 committed by GitHub
parent 2ed869ba93
commit b3da0745bc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 126 additions and 129 deletions

View file

@ -992,12 +992,32 @@ do
else
archetype_fast_delete(columns, column_count, row, types, delete)
end
end
function world_delete(world: World, entity: i53, destruct: boolean?)
local entityIndex = world.entityIndex
local record = entityIndex.sparse[entity]
if not record then
return
end
local archetype = record.archetype
local row = record.row
if archetype then
-- In the future should have a destruct mode for
-- deleting archetypes themselves. Maybe requires recycling
archetype_delete(world, archetype, row, destruct)
end
local delete = entity
local component_index = world.componentIndex
local archetypes = world.archetypes
local tgt = ECS_PAIR(EcsWildcard, delete)
local idr_t = component_index[tgt]
local idr = component_index[delete]
if idr then
local children = {}
for archetype_id in idr.cache do
@ -1019,38 +1039,11 @@ do
end
end
end
-- TODO: iterate each linked record.
-- local r = ECS_PAIR(delete, EcsWildcard)
-- local idr_r = component_index[r]
-- if idr_r then
-- -- Doesn't work for relations atm
-- for archetype_id in idr_o.cache do
-- local children = {}
-- local idr_r_archetype = archetypes[archetype_id]
-- local idr_r_types = idr_r_archetype.types
-- for _, child in idr_r_archetype.entities do
-- table.insert(children, child)
-- end
-- for _, id in idr_r_types do
-- local relation = ECS_ENTITY_T_HI(id)
-- if world_target(world, child, relation) == delete then
-- world_remove(world, child, ECS_PAIR(relation, delete))
-- end
-- end
-- end
-- end
local o = ECS_PAIR(EcsWildcard, delete)
local idr_o = component_index[o]
if idr_o then
for archetype_id in idr_o.cache do
if idr_t then
for archetype_id in idr_t.cache do
local children = {}
local idr_o_archetype = archetypes[archetype_id]
-- In the future, this needs to be optimized to only
-- look for linked records instead of doing this linearly
local idr_o_types = idr_o_archetype.types
@ -1084,24 +1077,6 @@ do
end
end
end
end
function world_delete(world: World, entity: i53, destruct: boolean?)
local entityIndex = world.entityIndex
local record = entityIndex.sparse[entity]
if not record then
return
end
local archetype = record.archetype
local row = record.row
if archetype then
-- In the future should have a destruct mode for
-- deleting archetypes themselves. Maybe requires recycling
archetype_delete(world, archetype, row, destruct)
end
record.archetype = nil :: any
entityIndex.sparse[entity] = nil

View file

@ -67,6 +67,10 @@ local function debug_world_inspect(world)
}
end
local function name(world, e)
return world:get(e, jecs.Name)
end
TEST("world:entity()", function()
do CASE "unique IDs"
local world = jecs.World.new()
@ -254,7 +258,6 @@ TEST("world:query()", function()
for x in q:iter() do
counter += 1
end
print(counter)
CHECK(counter == 2)
end
do CASE "tag"
@ -820,6 +823,25 @@ TEST("world:component()", function()
end)
TEST("world:delete", function()
do CASE "bug: Empty entity does not respect cleanup policy"
local world = world_new()
local parent = world:entity()
local tag = world:entity()
local child = world:entity()
world:add(child, jecs.pair(jecs.ChildOf, parent))
world:delete(parent)
CHECK(not world:contains(parent))
CHECK(not world:contains(child))
local entity = world:entity()
world:add(entity, tag)
world:delete(tag)
CHECK(world:contains(entity))
CHECK(not world:contains(tag))
CHECK(not world:has(entity, tag)) -- => true
end
do CASE("should allow deleting components")
local world = jecs.World.new()
@ -918,7 +940,7 @@ TEST("world:delete", function()
end)
for i, friend in friends do
CHECK(not world:has(friends, pair(jecs.ChildOf, e)))
CHECK(not world:has(friend, pair(FriendsWith, e)))
CHECK(world:has(friend, Health))
end
end