mirror of
https://github.com/Ukendio/jecs.git
synced 2025-07-09 08:09:18 +00:00
Move only once during removal of invalidated pair
Some checks are pending
Some checks are pending
This commit is contained in:
parent
29305cac5d
commit
6053038cc1
2 changed files with 151 additions and 109 deletions
|
@ -169,7 +169,7 @@ local function observers_add(world: jecs.World): PatchedWorld
|
||||||
|
|
||||||
local idr = world.component_index[component]
|
local idr = world.component_index[component]
|
||||||
if idr then
|
if idr then
|
||||||
idr.hooks.on_add = on_add
|
idr.on_add = on_add
|
||||||
else
|
else
|
||||||
world:set(component, jecs.OnAdd, on_add)
|
world:set(component, jecs.OnAdd, on_add)
|
||||||
end
|
end
|
||||||
|
@ -203,7 +203,7 @@ local function observers_add(world: jecs.World): PatchedWorld
|
||||||
end
|
end
|
||||||
local idr = world.component_index[component]
|
local idr = world.component_index[component]
|
||||||
if idr then
|
if idr then
|
||||||
idr.hooks.on_change = on_change
|
idr.on_change = on_change
|
||||||
else
|
else
|
||||||
world:set(component, jecs.OnChange, on_change)
|
world:set(component, jecs.OnChange, on_change)
|
||||||
end
|
end
|
||||||
|
@ -238,7 +238,7 @@ local function observers_add(world: jecs.World): PatchedWorld
|
||||||
|
|
||||||
local idr = world.component_index[component]
|
local idr = world.component_index[component]
|
||||||
if idr then
|
if idr then
|
||||||
idr.hooks.on_remove = on_remove
|
idr.on_remove = on_remove
|
||||||
else
|
else
|
||||||
world:set(component, jecs.OnRemove, on_remove)
|
world:set(component, jecs.OnRemove, on_remove)
|
||||||
end
|
end
|
||||||
|
|
238
jecs.luau
238
jecs.luau
|
@ -170,11 +170,10 @@ export type ComponentRecord = {
|
||||||
counts: { [Id]: number },
|
counts: { [Id]: number },
|
||||||
flags: number,
|
flags: number,
|
||||||
size: number,
|
size: number,
|
||||||
hooks: {
|
|
||||||
on_add: (<T>(entity: Entity, id: Entity<T>, value: T?) -> ())?,
|
on_add: (<T>(entity: Entity, id: Entity<T>, value: T?) -> ())?,
|
||||||
on_change: (<T>(entity: Entity, id: Entity<T>, value: T) -> ())?,
|
on_change: (<T>(entity: Entity, id: Entity<T>, value: T) -> ())?,
|
||||||
on_remove: ((entity: Entity, id: Entity) -> ())?,
|
on_remove: ((entity: Entity, id: Entity) -> ())?,
|
||||||
},
|
|
||||||
}
|
}
|
||||||
export type ComponentIndex = Map<Id, ComponentRecord>
|
export type ComponentIndex = Map<Id, ComponentRecord>
|
||||||
export type Archetypes = { [Id]: Archetype }
|
export type Archetypes = { [Id]: Archetype }
|
||||||
|
@ -746,11 +745,10 @@ local function id_record_ensure(world: World, id: Entity): ComponentRecord
|
||||||
records = {},
|
records = {},
|
||||||
counts = {},
|
counts = {},
|
||||||
flags = flags,
|
flags = flags,
|
||||||
hooks = {
|
|
||||||
on_add = on_add,
|
on_add = on_add,
|
||||||
on_change = on_change,
|
on_change = on_change,
|
||||||
on_remove = on_remove,
|
on_remove = on_remove,
|
||||||
},
|
|
||||||
} :: ComponentRecord
|
} :: ComponentRecord
|
||||||
|
|
||||||
component_index[id] = idr
|
component_index[id] = idr
|
||||||
|
@ -1029,7 +1027,7 @@ local function archetype_delete(world: World, archetype: Archetype, row: number)
|
||||||
|
|
||||||
for _, id in id_types do
|
for _, id in id_types do
|
||||||
local idr = component_index[id]
|
local idr = component_index[id]
|
||||||
local on_remove = idr.hooks.on_remove
|
local on_remove = idr.on_remove
|
||||||
if on_remove then
|
if on_remove then
|
||||||
on_remove(delete, id)
|
on_remove(delete, id)
|
||||||
end
|
end
|
||||||
|
@ -2025,7 +2023,7 @@ local function ecs_bulk_insert(world: World, entity: Entity, ids: { Entity }, va
|
||||||
local value = values[i]
|
local value = values[i]
|
||||||
local cdr = component_index[id]
|
local cdr = component_index[id]
|
||||||
|
|
||||||
local on_add = cdr.hooks.on_add
|
local on_add = cdr.on_add
|
||||||
if value then
|
if value then
|
||||||
columns_map[id][row] = value
|
columns_map[id][row] = value
|
||||||
if on_add then
|
if on_add then
|
||||||
|
@ -2070,11 +2068,11 @@ local function ecs_bulk_insert(world: World, entity: Entity, ids: { Entity }, va
|
||||||
|
|
||||||
local value = values[i] :: any
|
local value = values[i] :: any
|
||||||
|
|
||||||
local on_add = idr.hooks.on_add
|
local on_add = idr.on_add
|
||||||
|
|
||||||
if value ~= nil then
|
if value ~= nil then
|
||||||
columns_map[id][row] = value
|
columns_map[id][row] = value
|
||||||
local on_change = idr.hooks.on_change
|
local on_change = idr.on_change
|
||||||
local hook = if set then on_change else on_add
|
local hook = if set then on_change else on_add
|
||||||
if hook then
|
if hook then
|
||||||
hook(entity, id, value :: any)
|
hook(entity, id, value :: any)
|
||||||
|
@ -2109,7 +2107,7 @@ local function ecs_bulk_remove(world: World, entity: Entity, ids: { Entity })
|
||||||
remove[id] = true
|
remove[id] = true
|
||||||
local idr = component_index[id]
|
local idr = component_index[id]
|
||||||
|
|
||||||
local on_remove = idr.hooks.on_remove
|
local on_remove = idr.on_remove
|
||||||
if on_remove then
|
if on_remove then
|
||||||
on_remove(entity, id)
|
on_remove(entity, id)
|
||||||
end
|
end
|
||||||
|
@ -2183,6 +2181,76 @@ local function world_new()
|
||||||
return r
|
return r
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function inner_archetype_move(
|
||||||
|
entity: Entity,
|
||||||
|
to: Archetype,
|
||||||
|
dst_row: i24,
|
||||||
|
from: Archetype,
|
||||||
|
src_row: i24
|
||||||
|
)
|
||||||
|
local src_columns = from.columns
|
||||||
|
local dst_entities = to.entities
|
||||||
|
local src_entities = from.entities
|
||||||
|
|
||||||
|
local last = #src_entities
|
||||||
|
local id_types = from.types
|
||||||
|
local columns_map = to.columns_map
|
||||||
|
|
||||||
|
if src_row ~= last then
|
||||||
|
for i, column in src_columns do
|
||||||
|
if column == NULL_ARRAY then
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
local dst_column = columns_map[id_types[i]]
|
||||||
|
|
||||||
|
if dst_column then
|
||||||
|
dst_column[dst_row] = column[src_row]
|
||||||
|
end
|
||||||
|
|
||||||
|
column[src_row] = column[last]
|
||||||
|
column[last] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local e2 = src_entities[last]
|
||||||
|
src_entities[src_row] = e2
|
||||||
|
|
||||||
|
local record2 = eindex_sparse_array[ECS_ENTITY_T_LO(e2 :: number)]
|
||||||
|
record2.row = src_row
|
||||||
|
else
|
||||||
|
for i, column in src_columns do
|
||||||
|
if column == NULL_ARRAY then
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
-- Retrieves the new column index from the source archetype's record from each component
|
||||||
|
-- We have to do this because the columns are tightly packed and indexes may not correspond to each other.
|
||||||
|
local dst_column = columns_map[id_types[i]]
|
||||||
|
|
||||||
|
-- Sometimes target column may not exist, e.g. when you remove a component.
|
||||||
|
if dst_column then
|
||||||
|
dst_column[dst_row] = column[src_row]
|
||||||
|
end
|
||||||
|
|
||||||
|
column[last] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
src_entities[last] = nil :: any
|
||||||
|
dst_entities[dst_row] = entity
|
||||||
|
end
|
||||||
|
|
||||||
|
local function inner_entity_move(
|
||||||
|
entity_index: EntityIndex,
|
||||||
|
entity: Entity,
|
||||||
|
record: Record,
|
||||||
|
to: Archetype
|
||||||
|
)
|
||||||
|
local sourceRow = record.row
|
||||||
|
local from = record.archetype
|
||||||
|
local dst_row = archetype_append(entity, to)
|
||||||
|
inner_archetype_move(entity, to, dst_row, from, sourceRow)
|
||||||
|
record.archetype = to
|
||||||
|
record.row = dst_row
|
||||||
|
end
|
||||||
|
|
||||||
-- local function inner_entity_index_try_get(entity: number): Record?
|
-- local function inner_entity_index_try_get(entity: number): Record?
|
||||||
-- local r = inner_entity_index_try_get_any(entity)
|
-- local r = inner_entity_index_try_get_any(entity)
|
||||||
-- if r then
|
-- if r then
|
||||||
|
@ -2235,7 +2303,7 @@ local function world_new()
|
||||||
if idr and bit32.btest(idr.flags, ECS_ID_IS_EXCLUSIVE) then
|
if idr and bit32.btest(idr.flags, ECS_ID_IS_EXCLUSIVE) then
|
||||||
local cr = idr.records[src.id]
|
local cr = idr.records[src.id]
|
||||||
if cr then
|
if cr then
|
||||||
local on_remove = idr.hooks.on_remove
|
local on_remove = idr.on_remove
|
||||||
local id_types = src.types
|
local id_types = src.types
|
||||||
if on_remove then
|
if on_remove then
|
||||||
on_remove(entity, id_types[cr])
|
on_remove(entity, id_types[cr])
|
||||||
|
@ -2262,14 +2330,14 @@ local function world_new()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if from then
|
if from then
|
||||||
entity_move(entity_index, entity, record, to)
|
inner_entity_move(entity_index, entity, record, to)
|
||||||
else
|
else
|
||||||
if #to.types > 0 then
|
if #to.types > 0 then
|
||||||
new_entity(entity, record, to)
|
new_entity(entity, record, to)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local on_add = idr.hooks.on_add
|
local on_add = idr.on_add
|
||||||
|
|
||||||
if on_add then
|
if on_add then
|
||||||
on_add(entity, id)
|
on_add(entity, id)
|
||||||
|
@ -2281,7 +2349,7 @@ local function world_new()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if from then
|
if from then
|
||||||
entity_move(entity_index, entity, record, to)
|
inner_entity_move(entity_index, entity, record, to)
|
||||||
else
|
else
|
||||||
if #to.types > 0 then
|
if #to.types > 0 then
|
||||||
new_entity(entity, record, to)
|
new_entity(entity, record, to)
|
||||||
|
@ -2289,7 +2357,7 @@ local function world_new()
|
||||||
end
|
end
|
||||||
|
|
||||||
local idr = component_index[id]
|
local idr = component_index[id]
|
||||||
local on_add = idr.hooks.on_add
|
local on_add = idr.on_add
|
||||||
|
|
||||||
if on_add then
|
if on_add then
|
||||||
on_add(entity, id)
|
on_add(entity, id)
|
||||||
|
@ -2421,19 +2489,17 @@ local function world_new()
|
||||||
local column = src.columns_map[id]
|
local column = src.columns_map[id]
|
||||||
if column then
|
if column then
|
||||||
local idr = component_index[id]
|
local idr = component_index[id]
|
||||||
local idr_hooks = idr.hooks
|
|
||||||
column[record.row] = data
|
column[record.row] = data
|
||||||
|
|
||||||
-- If the archetypes are the same it can avoid moving the entity
|
-- If the archetypes are the same it can avoid moving the entity
|
||||||
-- and just set the data directly.
|
-- and just set the data directly.
|
||||||
local on_change = idr_hooks.on_change
|
local on_change = idr.on_change
|
||||||
if on_change then
|
if on_change then
|
||||||
on_change(entity, id, data)
|
on_change(entity, id, data)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local to: Archetype
|
local to: Archetype
|
||||||
local idr: ComponentRecord
|
local idr: ComponentRecord
|
||||||
local idr_hooks
|
|
||||||
if ECS_IS_PAIR(id::number) then
|
if ECS_IS_PAIR(id::number) then
|
||||||
local edge = archetype_edges[src.id]
|
local edge = archetype_edges[src.id]
|
||||||
to = edge[id]
|
to = edge[id]
|
||||||
|
@ -2444,7 +2510,7 @@ local function world_new()
|
||||||
if idr and bit32.btest(idr.flags, ECS_ID_IS_EXCLUSIVE) then
|
if idr and bit32.btest(idr.flags, ECS_ID_IS_EXCLUSIVE) then
|
||||||
local cr = idr.records[src.id]
|
local cr = idr.records[src.id]
|
||||||
if cr then
|
if cr then
|
||||||
local on_remove = idr.hooks.on_remove
|
local on_remove = idr.on_remove
|
||||||
local id_types = src.types
|
local id_types = src.types
|
||||||
if on_remove then
|
if on_remove then
|
||||||
on_remove(entity, id_types[cr])
|
on_remove(entity, id_types[cr])
|
||||||
|
@ -2467,7 +2533,6 @@ local function world_new()
|
||||||
else
|
else
|
||||||
idr = component_index[id]
|
idr = component_index[id]
|
||||||
end
|
end
|
||||||
idr_hooks = idr.hooks
|
|
||||||
else
|
else
|
||||||
to = inner_archetype_traverse_add(id, from)
|
to = inner_archetype_traverse_add(id, from)
|
||||||
idr = component_index[id]
|
idr = component_index[id]
|
||||||
|
@ -2475,16 +2540,15 @@ local function world_new()
|
||||||
|
|
||||||
if from then
|
if from then
|
||||||
-- If there was a previous archetype, then the entity needs to move the archetype
|
-- If there was a previous archetype, then the entity needs to move the archetype
|
||||||
entity_move(entity_index, entity, record, to)
|
inner_entity_move(entity_index, entity, record, to)
|
||||||
else
|
else
|
||||||
new_entity(entity, record, to)
|
new_entity(entity, record, to)
|
||||||
end
|
end
|
||||||
|
|
||||||
idr_hooks = idr.hooks
|
|
||||||
column = to.columns_map[id]
|
column = to.columns_map[id]
|
||||||
column[record.row] = data
|
column[record.row] = data
|
||||||
|
|
||||||
local on_add = idr_hooks.on_add
|
local on_add = idr.on_add
|
||||||
if on_add then
|
if on_add then
|
||||||
on_add(entity, id, data)
|
on_add(entity, id, data)
|
||||||
end
|
end
|
||||||
|
@ -2565,14 +2629,14 @@ local function world_new()
|
||||||
|
|
||||||
if from.columns_map[id] then
|
if from.columns_map[id] then
|
||||||
local idr = world.component_index[id]
|
local idr = world.component_index[id]
|
||||||
local on_remove = idr.hooks.on_remove
|
local on_remove = idr.on_remove
|
||||||
if on_remove then
|
if on_remove then
|
||||||
on_remove(entity, id)
|
on_remove(entity, id)
|
||||||
end
|
end
|
||||||
|
|
||||||
local to = archetype_traverse_remove(world, id, record.archetype)
|
local to = archetype_traverse_remove(world, id, record.archetype)
|
||||||
|
|
||||||
entity_move(entity_index, entity, record, to)
|
inner_entity_move(entity_index, entity, record, to)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2599,16 +2663,13 @@ local function world_new()
|
||||||
end
|
end
|
||||||
|
|
||||||
if idr_t then
|
if idr_t then
|
||||||
local queue: { i53 }
|
|
||||||
local ids: Map<i53, boolean>
|
|
||||||
|
|
||||||
local count = 0
|
|
||||||
local archetype_ids = idr_t.records
|
local archetype_ids = idr_t.records
|
||||||
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 removal_queued = false
|
|
||||||
|
local node = idr_t_archetype
|
||||||
|
|
||||||
for _, id in idr_t_types do
|
for _, id in idr_t_types do
|
||||||
if not ECS_IS_PAIR(id::number) then
|
if not ECS_IS_PAIR(id::number) then
|
||||||
|
@ -2619,57 +2680,48 @@ local function world_new()
|
||||||
if object ~= entity then
|
if object ~= entity then
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
if not ids then
|
node = archetype_traverse_remove(world, id, node)
|
||||||
ids = {} :: { [i53]: boolean }
|
local on_remove = component_index[id].on_remove
|
||||||
|
if on_remove then
|
||||||
|
for _, entity in entities do
|
||||||
|
on_remove(entity, id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
ids[id] = true
|
|
||||||
removal_queued = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if not removal_queued then
|
for i = #entities, 1, -1 do
|
||||||
continue
|
local e = entities[i]
|
||||||
end
|
local r = inner_entity_index_try_get_unsafe(e::number) :: Record
|
||||||
|
inner_entity_move(entity_index, e, r, node)
|
||||||
if not queue then
|
|
||||||
queue = {} :: { i53 }
|
|
||||||
end
|
|
||||||
|
|
||||||
local n = #entities
|
|
||||||
table.move(entities, 1, n, count + 1, queue)
|
|
||||||
count += n
|
|
||||||
end
|
|
||||||
|
|
||||||
for id in ids do
|
|
||||||
for _, child in queue do
|
|
||||||
inner_world_remove(world, child, id)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if idr_r then
|
if idr_r then
|
||||||
local count = 0
|
|
||||||
local archetype_ids = idr_r.records
|
local archetype_ids = idr_r.records
|
||||||
local ids = {}
|
|
||||||
local queue = {}
|
|
||||||
local records = idr_r.records
|
local records = idr_r.records
|
||||||
local counts = idr_r.counts
|
local counts = idr_r.counts
|
||||||
for archetype_id in archetype_ids do
|
for archetype_id in archetype_ids do
|
||||||
local idr_r_archetype = archetypes[archetype_id]
|
local idr_r_archetype = archetypes[archetype_id]
|
||||||
|
local node = idr_r_archetype
|
||||||
local entities = idr_r_archetype.entities
|
local entities = idr_r_archetype.entities
|
||||||
local tr = records[archetype_id]
|
local tr = records[archetype_id]
|
||||||
local tr_count = counts[archetype_id]
|
local tr_count = counts[archetype_id]
|
||||||
local types = idr_r_archetype.types
|
local types = idr_r_archetype.types
|
||||||
for i = tr, tr + tr_count - 1 do
|
for i = tr, tr + tr_count - 1 do
|
||||||
ids[types[i]] = true
|
local id = types[i]
|
||||||
|
node = archetype_traverse_remove(world, id, idr_r_archetype)
|
||||||
|
local on_remove = component_index[id].on_remove
|
||||||
|
if on_remove then
|
||||||
|
for _, entity in entities do
|
||||||
|
on_remove(entity, id)
|
||||||
end
|
end
|
||||||
local n = #entities
|
|
||||||
table.move(entities, 1, n, count + 1, queue)
|
|
||||||
count += n
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
for _, e in queue do
|
for i = #entities, 1, -1 do
|
||||||
for id in ids do
|
local e = entities[i]
|
||||||
inner_world_remove(world, e, id)
|
local r = inner_entity_index_try_get_unsafe(e::number) :: Record
|
||||||
|
inner_entity_move(entity_index, e, r, node)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2715,7 +2767,7 @@ local function world_new()
|
||||||
archetype_destroy(world, idr_archetype)
|
archetype_destroy(world, idr_archetype)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local on_remove = idr.hooks.on_remove
|
local on_remove = idr.on_remove
|
||||||
if on_remove then
|
if on_remove then
|
||||||
for archetype_id in idr.records do
|
for archetype_id in idr.records do
|
||||||
local idr_archetype = archetypes[archetype_id]
|
local idr_archetype = archetypes[archetype_id]
|
||||||
|
@ -2732,7 +2784,7 @@ local function world_new()
|
||||||
-- this is hypothetically not that expensive of an operation anyways
|
-- this is hypothetically not that expensive of an operation anyways
|
||||||
to = archetype_traverse_remove(world, entity, from)
|
to = archetype_traverse_remove(world, entity, from)
|
||||||
end
|
end
|
||||||
entity_move(entity_index, e, r, to)
|
inner_entity_move(entity_index, e, r, to)
|
||||||
end
|
end
|
||||||
|
|
||||||
archetype_destroy(world, idr_archetype)
|
archetype_destroy(world, idr_archetype)
|
||||||
|
@ -2753,19 +2805,15 @@ local function world_new()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if idr_t then
|
if idr_t then
|
||||||
local children: { i53 }
|
|
||||||
local ids: Map<i53, boolean>
|
|
||||||
|
|
||||||
local count = 0
|
|
||||||
local archetype_ids = idr_t.records
|
local archetype_ids = idr_t.records
|
||||||
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 node = idr_t_archetype
|
||||||
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 removal_queued = false
|
|
||||||
|
|
||||||
|
local deleted = false
|
||||||
for _, id in idr_t_types do
|
for _, id in idr_t_types do
|
||||||
if not ECS_IS_PAIR(id::number) then
|
if not ECS_IS_PAIR(id::number) then
|
||||||
continue
|
continue
|
||||||
|
@ -2783,31 +2831,24 @@ local function world_new()
|
||||||
local child = entities[i]
|
local child = entities[i]
|
||||||
inner_world_delete(world, child)
|
inner_world_delete(world, child)
|
||||||
end
|
end
|
||||||
|
deleted = true
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
if not ids then
|
node = archetype_traverse_remove(world, id, node)
|
||||||
ids = {} :: { [i53]: boolean }
|
local on_remove = component_index[id].on_remove
|
||||||
|
if on_remove then
|
||||||
|
for _, entity in entities do
|
||||||
|
on_remove(entity, id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
ids[id] = true
|
|
||||||
removal_queued = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not removal_queued then
|
if not deleted then
|
||||||
continue
|
for i = #entities, 1, -1 do
|
||||||
end
|
local e = entities[i]
|
||||||
if not children then
|
local r = inner_entity_index_try_get_unsafe(e::number) :: Record
|
||||||
children = {} :: { i53 }
|
inner_entity_move(entity_index, e, r, node)
|
||||||
end
|
|
||||||
local n = #entities
|
|
||||||
table.move(entities, 1, n, count + 1, children)
|
|
||||||
count += n
|
|
||||||
end
|
|
||||||
|
|
||||||
if ids then
|
|
||||||
for _, child in children do
|
|
||||||
for id in ids do
|
|
||||||
inner_world_remove(world, child, id)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2831,28 +2872,29 @@ local function world_new()
|
||||||
archetype_destroy(world, idr_r_archetype)
|
archetype_destroy(world, idr_r_archetype)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local children = {}
|
|
||||||
local count = 0
|
|
||||||
local ids = {}
|
|
||||||
local counts = idr_r.counts
|
local counts = idr_r.counts
|
||||||
local records = idr_r.records
|
local records = idr_r.records
|
||||||
for archetype_id in archetype_ids do
|
for archetype_id in archetype_ids do
|
||||||
local idr_r_archetype = archetypes[archetype_id]
|
local idr_r_archetype = archetypes[archetype_id]
|
||||||
|
local node = idr_r_archetype
|
||||||
local entities = idr_r_archetype.entities
|
local entities = idr_r_archetype.entities
|
||||||
local tr = records[archetype_id]
|
local tr = records[archetype_id]
|
||||||
local tr_count = counts[archetype_id]
|
local tr_count = counts[archetype_id]
|
||||||
local types = idr_r_archetype.types
|
local types = idr_r_archetype.types
|
||||||
for i = tr, tr + tr_count - 1 do
|
for i = tr, tr + tr_count - 1 do
|
||||||
ids[types[i]] = true
|
local id = types[i]
|
||||||
|
node = archetype_traverse_remove(world, id, node)
|
||||||
|
local on_remove = component_index[id].on_remove
|
||||||
|
if on_remove then
|
||||||
|
for _, entity in entities do
|
||||||
|
on_remove(entity, id)
|
||||||
end
|
end
|
||||||
|
|
||||||
local n = #entities
|
|
||||||
table.move(entities, 1, n, count + 1, children)
|
|
||||||
count += n
|
|
||||||
end
|
end
|
||||||
for _, child in children do
|
end
|
||||||
for id in ids do
|
for i = #entities, 1, -1 do
|
||||||
inner_world_remove(world, child, id)
|
local e = entities[i]
|
||||||
|
local r = inner_entity_index_try_get_unsafe(e::number) :: Record
|
||||||
|
inner_entity_move(entity_index, e, r, node)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue