Optimize removal path (#248)

* Optimize removal path

* Replace eindex_get implementation
This commit is contained in:
Marcus 2025-06-30 01:06:31 +02:00 committed by GitHub
parent 3c7f3b4eb3
commit d6e720f200
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2146,31 +2146,20 @@ local function world_new()
return r return r
end end
-- local function entity_index_try_get_safe(entity: number): Record?
-- local r = entity_index_try_get_any_fast(entity_index, entity)
-- if r then
-- local r_dense = r.dense
-- if r_dense > entity_index.alive_count then
-- return nil
-- end
-- if entity_index.dense_array[r_dense] ~= entity then
-- return nil
-- end
-- end
-- return r
-- end
local function inner_entity_index_try_get(entity: number): Record? local function inner_entity_index_try_get(entity: number): Record?
local r = eindex_sparse_array[ECS_ENTITY_T_LO(entity)] local r = inner_entity_index_try_get_any(entity)
if r then if r then
if eindex_dense_array[r.dense] ~= entity then local r_dense = r.dense
if r_dense > entity_index.alive_count then
return nil
end
if eindex_dense_array[r_dense] ~= entity then
return nil return nil
end end
end end
return r return r
end end
local function inner_world_add<T, a>( local function inner_world_add<T, a>(
world: World, world: World,
entity: Entity<T>, entity: Entity<T>,
@ -2582,15 +2571,41 @@ local function world_new()
archetype_destroy(world, idr_archetype) archetype_destroy(world, idr_archetype)
end end
else else
for archetype_id in idr.records do local on_remove = idr.hooks.on_remove
local idr_archetype = archetypes[archetype_id] if on_remove then
local entities = idr_archetype.entities for archetype_id in idr.records do
local n = #entities local idr_archetype = archetypes[archetype_id]
for i = n, 1, -1 do local to = archetype_traverse_remove(world, entity, idr_archetype)
inner_world_remove(world, entities[i], entity) local entities = idr_archetype.entities
end local n = #entities
for i = n, 1, -1 do
local e = entities[i]
on_remove(e, entity)
local r = eindex_sparse_array[ECS_ID(e :: number)]
local from = r.archetype
if from ~= idr_archetype then
-- unfortunately the on_remove hook allows a window where `e` can have changed archetype
-- this is hypothetically not that expensive of an operation anyways
to = archetype_traverse_remove(world, entity, from)
end
entity_move(entity_index, e, r, to)
end
archetype_destroy(world, idr_archetype) archetype_destroy(world, idr_archetype)
end
else
for archetype_id in idr.records do
local idr_archetype = archetypes[archetype_id]
local to = archetype_traverse_remove(world, entity, idr_archetype)
local entities = idr_archetype.entities
local n = #entities
for i = n, 1, -1 do
local e = entities[i]
entity_move(entity_index, e, eindex_sparse_array[ECS_ID(e :: number)], to)
end
archetype_destroy(world, idr_archetype)
end
end end
end end
end end