Remove second loop in archetype destroy

This commit is contained in:
Ukendio 2025-07-05 21:26:05 +02:00
parent 8fd32978b4
commit 29305cac5d

100
jecs.luau
View file

@ -42,14 +42,12 @@ export type Iter<T...> = (query: Query<T...>) -> () -> (Entity, T...)
export type Query<T...> = typeof(setmetatable(
{} :: {
iter: Iter<T...>,
with:
(<a>(Query<T...>, Id<a>) -> Query<T...>)
with: (<a>(Query<T...>, Id<a>) -> Query<T...>)
& (<a, b>(Query<T...>, Id<a>, Id<b>) -> Query<T...>)
& (<a, b, c>(Query<T...>, Id<a>, Id<b>, Id<c>) -> Query<T...>)
& (<a, b, c>(Query<T...>, Id<a>, Id<b>, Id<c>) -> Query<T...>)
& (<a, b, c, d>(Query<T...>, Id<a>, Id<b>, Id<c>, Id) -> Query<T...>),
without:
(<a>(Query<T...>, Id<a>) -> Query<T...>)
without: (<a>(Query<T...>, Id<a>) -> Query<T...>)
& (<a, b>(Query<T...>, Id<a>, Id<b>) -> Query<T...>)
& (<a, b, c>(Query<T...>, Id<a>, Id<b>, Id<c>) -> Query<T...>)
& (<a, b, c>(Query<T...>, Id<a>, Id<b>, Id<c>) -> Query<T...>)
@ -1065,6 +1063,13 @@ local function archetype_destroy(world: World, archetype: Archetype)
local columns_map = archetype.columns_map
for id in columns_map do
local idr = component_index[id]
idr.records[archetype_id] = nil :: any
idr.counts[archetype_id] = nil
idr.size -= 1
if idr.size == 0 then
component_index[id] = nil :: any
end
local observer_list = find_observers(world, EcsOnArchetypeDelete, id)
if not observer_list then
continue
@ -1075,16 +1080,6 @@ local function archetype_destroy(world: World, archetype: Archetype)
end
end
end
for id in columns_map do
local idr = component_index[id]
idr.records[archetype_id] = nil :: any
idr.counts[archetype_id] = nil
idr.size -= 1
if idr.size == 0 then
component_index[id] = nil :: any
end
end
end
local function NOOP() end
@ -2422,11 +2417,26 @@ local function world_new()
end
local from: Archetype = record.archetype
if ECS_IS_PAIR(id::number) then
local src = from or ROOT_ARCHETYPE
local edge = archetype_edges[src.id]
local to = edge[id]
local column = src.columns_map[id]
if column then
local idr = component_index[id]
local idr_hooks = idr.hooks
column[record.row] = data
-- If the archetypes are the same it can avoid moving the entity
-- and just set the data directly.
local on_change = idr_hooks.on_change
if on_change then
on_change(entity, id, data)
end
else
local to: Archetype
local idr: ComponentRecord
local idr_hooks
if ECS_IS_PAIR(id::number) then
local edge = archetype_edges[src.id]
to = edge[id]
if not to then
local first = ECS_PAIR_FIRST(id::number)
local wc = ECS_PAIR(first, EcsWildcard)
@ -2457,55 +2467,10 @@ local function world_new()
else
idr = component_index[id]
end
local idr_hooks = idr.hooks
if from == to then
local column = to.columns_map[id]
column[record.row] = data
-- If the archetypes are the same it can avoid moving the entity
-- and just set the data directly.
local on_change = idr_hooks.on_change
if on_change then
on_change(entity, id, data)
end
return
end
if from then
entity_move(entity_index, entity, record, to)
idr_hooks = idr.hooks
else
if #to.types > 0 then
new_entity(entity, record, to)
end
end
local column = to.columns_map[id]
column[record.row] = data
local on_add = idr.hooks.on_add
if on_add then
on_add(entity, id)
end
return
end
local to: Archetype = inner_archetype_traverse_add(id, from)
local idr = component_index[id]
local idr_hooks = idr.hooks
if from == to then
local column = to.columns_map[id]
column[record.row] = data
-- If the archetypes are the same it can avoid moving the entity
-- and just set the data directly.
local on_change = idr_hooks.on_change
if on_change then
on_change(entity, id, data)
end
return
to = inner_archetype_traverse_add(id, from)
idr = component_index[id]
end
if from then
@ -2514,7 +2479,9 @@ local function world_new()
else
new_entity(entity, record, to)
end
local column = to.columns_map[id]
idr_hooks = idr.hooks
column = to.columns_map[id]
column[record.row] = data
local on_add = idr_hooks.on_add
@ -2522,6 +2489,7 @@ local function world_new()
on_add(entity, id, data)
end
end
end
local function inner_world_entity<T>(world: World, entity: Entity<T>?): Entity<T>
if entity then