mirror of
https://github.com/Ukendio/jecs.git
synced 2026-02-04 15:15:21 +00:00
Fix entities with pairs of non delete policies
* fix world_delete clearing archetype entities before proper cleanup * make changes
This commit is contained in:
parent
e494c35b78
commit
1e7d957a5b
1 changed files with 64 additions and 16 deletions
|
|
@ -3485,10 +3485,14 @@ local function world_new(DEBUG: boolean?)
|
||||||
end
|
end
|
||||||
if idr_t then
|
if idr_t then
|
||||||
local archetype_ids = idr_t.records
|
local archetype_ids = idr_t.records
|
||||||
|
local to_remove = {}:: { [i53]: componentrecord}
|
||||||
|
|
||||||
for archetype_id in archetype_ids do
|
for archetype_id in archetype_ids do
|
||||||
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 entities = idr_t_archetype.entities
|
local entities = idr_t_archetype.entities
|
||||||
|
local deleted_any = false
|
||||||
|
local remove_count = 0
|
||||||
|
|
||||||
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
|
||||||
|
|
@ -3503,27 +3507,71 @@ local function world_new(DEBUG: boolean?)
|
||||||
local flags = id_record.flags
|
local flags = id_record.flags
|
||||||
local flags_delete_mask = bit32.btest(flags, ECS_ID_DELETE)
|
local flags_delete_mask = bit32.btest(flags, ECS_ID_DELETE)
|
||||||
if flags_delete_mask then
|
if flags_delete_mask then
|
||||||
for i = #entities, 1, -1 do
|
for i = #entities, 1, -1 do
|
||||||
local child = entities[i]
|
local child = entities[i]
|
||||||
world_delete(world, child)
|
world_delete(world, child)
|
||||||
end
|
end
|
||||||
|
deleted_any = true
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
local on_remove = id_record.on_remove
|
to_remove[id] = id_record
|
||||||
|
remove_count += 1
|
||||||
local to = archetype_traverse_remove(world, id, idr_t_archetype)
|
|
||||||
for i = #entities, 1, -1 do
|
|
||||||
local child = entities[i]
|
|
||||||
if on_remove then
|
|
||||||
on_remove(child, id)
|
|
||||||
end
|
|
||||||
|
|
||||||
local r = entity_index_try_get_unsafe(child) :: record
|
|
||||||
inner_entity_move(child, r, to)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if deleted_any then
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
if remove_count == 1 then
|
||||||
|
local id, id_record = next(to_remove)
|
||||||
|
local to_u = archetype_traverse_remove(world, id :: i53, idr_t_archetype)
|
||||||
|
local on_remove = id_record.on_remove
|
||||||
|
for i = #entities, 1, -1 do
|
||||||
|
local child = entities[i]
|
||||||
|
local r = entity_index_try_get_unsafe(child) :: record
|
||||||
|
local to = to_u
|
||||||
|
if on_remove then
|
||||||
|
on_remove(child, id :: i53)
|
||||||
|
local src = r.archetype
|
||||||
|
if src ~= idr_t_archetype then
|
||||||
|
to = archetype_traverse_remove(world, id::i53, src)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
inner_entity_move(child, r, to)
|
||||||
|
end
|
||||||
|
elseif remove_count > 1 then
|
||||||
|
local dst_types = table.clone(idr_t_types)
|
||||||
|
for id, component_record in to_remove do
|
||||||
|
table.remove(dst_types, table.find(dst_types, id))
|
||||||
|
end
|
||||||
|
|
||||||
|
local to_u = archetype_ensure(world, dst_types)
|
||||||
|
for i = #entities, 1, -1 do
|
||||||
|
local child = entities[i]
|
||||||
|
local r = entity_index_try_get_unsafe(child) :: record
|
||||||
|
|
||||||
|
local to = to_u
|
||||||
|
for id, component_record in to_remove do
|
||||||
|
local on_remove = component_record.on_remove
|
||||||
|
if on_remove then
|
||||||
|
-- NOTE(marcus): We could be smarter with this and
|
||||||
|
-- assume hooks are deterministic and that they will
|
||||||
|
-- move to the same archetype. However users often are not reasonable people.
|
||||||
|
on_remove(child, id)
|
||||||
|
local src = r.archetype
|
||||||
|
if src ~= idr_t_archetype then
|
||||||
|
to = archetype_traverse_remove(world, id, src)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
inner_entity_move(child, r, to)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.clear(to_remove)
|
||||||
archetype_destroy(world, idr_t_archetype)
|
archetype_destroy(world, idr_t_archetype)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue