Compare commits

...

6 commits

Author SHA1 Message Date
lolmanurfunny
311f274b0b
Merge 03666c9b61 into 263544d77c 2025-03-11 19:39:41 +00:00
lolmanurfunny
03666c9b61 test case 2025-03-11 15:39:30 -04:00
lolmanurfunny
e2ea71a7fe add fix for #207 2025-03-11 15:39:04 -04:00
lolmanurfunny
870823f9fc shorten loop 2025-03-07 23:17:43 -05:00
lolmanurfunny
fa4df24ada undo variable changes 2025-03-07 19:56:40 -05:00
lolmanurfunny
3a560393f1 Optimize deletion logic 2025-03-07 05:45:55 -05:00
2 changed files with 45 additions and 26 deletions

View file

@ -1152,44 +1152,43 @@ do
if idr_t then if idr_t then
for archetype_id in idr_t.columns do for archetype_id in idr_t.columns do
local children = {}
local idr_t_archetype = archetypes[archetype_id] local idr_t_archetype = archetypes[archetype_id]
local idr_t_types = idr_t_archetype.types local idr_t_types = idr_t_archetype.types
local to = idr_t_archetype
for _, child in idr_t_archetype.entities do local children = table.clone(idr_t_archetype.entities)
table.insert(children, child)
end
local n = #children local n = #children
for _, id in idr_t_types do for _, id in idr_t_types do
if not ECS_IS_PAIR(id) then if not ECS_IS_PAIR(id) then
continue continue
end end
local object = ecs_pair_second(world, id) local object = ecs_pair_second(world, id)
if object == delete then if object ~= delete then
local id_record = component_index[id] continue
local flags = id_record.flags end
local flags_delete_mask: number = bit32.band(flags, ECS_ID_DELETE)
if flags_delete_mask ~= 0 then local id_record = component_index[id]
for i = n, 1, -1 do local flags = id_record.flags
world_delete(world, children[i]) local flags_delete_mask: number = bit32.band(flags, ECS_ID_DELETE)
if flags_delete_mask ~= 0 then
for i = n, 1, -1 do
world_delete(world, children[i])
end
break
else
local on_remove = id_record.hooks.on_remove
to = archetype_traverse_remove(world, id, to)
local empty = #to.types == 0
for i = n, 1, -1 do
local child = children[i]
if on_remove then
on_remove(child)
end end
break if not empty then
else
local on_remove = id_record.hooks.on_remove
local to = archetype_traverse_remove(world, id, idr_t_archetype)
local empty = #to.types == 0
for i = n, 1, -1 do
local child = children[i]
if on_remove then
on_remove(child)
end
local r = sparse_array[ECS_ENTITY_T_LO(child)] local r = sparse_array[ECS_ENTITY_T_LO(child)]
if not empty then entity_move(entity_index, child, r, to)
entity_move(entity_index, child, r, to)
end
end end
end end
end end

View file

@ -1333,6 +1333,26 @@ TEST("world:target", function()
CHECK(i == 10) CHECK(i == 10)
end end
do CASE("should return correct targets after deletion") -- ISSUE #207
local world = jecs.World.new()
local Attacks = world:component()
local Eats = world:component()
local a = world:entity()
local b = world:entity()
local c = world:entity()
world:add(a, jecs.pair(Attacks, b))
world:add(a, jecs.pair(Attacks, c))
world:add(a, jecs.pair(Eats, c))
world:add(a, jecs.pair(Eats, b))
world:delete(c)
CHECK(world:target(a, Attacks, 0) == b)
CHECK(not world:target(a, Attacks, 1))
CHECK(not world:target(a, Attacks, 2))
end
end) end)
TEST("world:contains", function() TEST("world:contains", function()