mirror of
https://github.com/Ukendio/jecs.git
synced 2025-07-08 23:59:17 +00:00
Remove second loop in archetype destroy
This commit is contained in:
parent
8fd32978b4
commit
29305cac5d
1 changed files with 73 additions and 105 deletions
178
jecs.luau
178
jecs.luau
|
@ -42,14 +42,12 @@ export type Iter<T...> = (query: Query<T...>) -> () -> (Entity, T...)
|
||||||
export type Query<T...> = typeof(setmetatable(
|
export type Query<T...> = typeof(setmetatable(
|
||||||
{} :: {
|
{} :: {
|
||||||
iter: Iter<T...>,
|
iter: Iter<T...>,
|
||||||
with:
|
with: (<a>(Query<T...>, Id<a>) -> Query<T...>)
|
||||||
(<a>(Query<T...>, Id<a>) -> Query<T...>)
|
|
||||||
& (<a, b>(Query<T...>, Id<a>, Id<b>) -> 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>(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...>),
|
& (<a, b, c, d>(Query<T...>, Id<a>, Id<b>, Id<c>, Id) -> Query<T...>),
|
||||||
without:
|
without: (<a>(Query<T...>, Id<a>) -> Query<T...>)
|
||||||
(<a>(Query<T...>, Id<a>) -> Query<T...>)
|
|
||||||
& (<a, b>(Query<T...>, Id<a>, Id<b>) -> 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>(Query<T...>, Id<a>, Id<b>, Id<c>) -> Query<T...>)
|
& (<a, b, c>(Query<T...>, Id<a>, Id<b>, Id<c>) -> Query<T...>)
|
||||||
|
@ -196,10 +194,10 @@ local ECS_ENTITY_MASK = bit32.lshift(1, 24)
|
||||||
local ECS_GENERATION_MASK = bit32.lshift(1, 16)
|
local ECS_GENERATION_MASK = bit32.lshift(1, 16)
|
||||||
local ECS_PAIR_OFFSET = 2^48
|
local ECS_PAIR_OFFSET = 2^48
|
||||||
|
|
||||||
local ECS_ID_DELETE = 0b0001
|
local ECS_ID_DELETE = 0b0001
|
||||||
local ECS_ID_IS_TAG = 0b0010
|
local ECS_ID_IS_TAG = 0b0010
|
||||||
local ECS_ID_IS_EXCLUSIVE = 0b0100
|
local ECS_ID_IS_EXCLUSIVE = 0b0100
|
||||||
local ECS_ID_MASK = 0b0000
|
local ECS_ID_MASK = 0b0000
|
||||||
|
|
||||||
local HI_COMPONENT_ID = 256
|
local HI_COMPONENT_ID = 256
|
||||||
local EcsOnAdd = HI_COMPONENT_ID + 1
|
local EcsOnAdd = HI_COMPONENT_ID + 1
|
||||||
|
@ -1065,6 +1063,13 @@ local function archetype_destroy(world: World, archetype: Archetype)
|
||||||
local columns_map = archetype.columns_map
|
local columns_map = archetype.columns_map
|
||||||
|
|
||||||
for id in columns_map do
|
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)
|
local observer_list = find_observers(world, EcsOnArchetypeDelete, id)
|
||||||
if not observer_list then
|
if not observer_list then
|
||||||
continue
|
continue
|
||||||
|
@ -1075,16 +1080,6 @@ local function archetype_destroy(world: World, archetype: Archetype)
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
local function NOOP() end
|
local function NOOP() end
|
||||||
|
@ -2422,80 +2417,11 @@ local function world_new()
|
||||||
end
|
end
|
||||||
|
|
||||||
local from: Archetype = record.archetype
|
local from: Archetype = record.archetype
|
||||||
if ECS_IS_PAIR(id::number) then
|
local src = from or ROOT_ARCHETYPE
|
||||||
local src = from or ROOT_ARCHETYPE
|
local column = src.columns_map[id]
|
||||||
local edge = archetype_edges[src.id]
|
if column then
|
||||||
local to = edge[id]
|
local idr = component_index[id]
|
||||||
local idr: ComponentRecord
|
|
||||||
if not to then
|
|
||||||
local first = ECS_PAIR_FIRST(id::number)
|
|
||||||
local wc = ECS_PAIR(first, EcsWildcard)
|
|
||||||
idr = component_index[wc]
|
|
||||||
if idr and bit32.btest(idr.flags, ECS_ID_IS_EXCLUSIVE) then
|
|
||||||
local cr = idr.records[src.id]
|
|
||||||
if cr then
|
|
||||||
local on_remove = idr.hooks.on_remove
|
|
||||||
local id_types = src.types
|
|
||||||
if on_remove then
|
|
||||||
on_remove(entity, id_types[cr])
|
|
||||||
src = record.archetype
|
|
||||||
id_types = src.types
|
|
||||||
cr = idr.records[src.id]
|
|
||||||
end
|
|
||||||
local dst = table.clone(id_types)
|
|
||||||
dst[cr] = id
|
|
||||||
to = archetype_ensure(world, dst)
|
|
||||||
else
|
|
||||||
to = find_archetype_with(world, id, src)
|
|
||||||
idr = component_index[id]
|
|
||||||
end
|
|
||||||
else
|
|
||||||
to = find_archetype_with(world, id, src)
|
|
||||||
idr = component_index[id]
|
|
||||||
end
|
|
||||||
edge[id] = to
|
|
||||||
else
|
|
||||||
idr = component_index[id]
|
|
||||||
end
|
|
||||||
local idr_hooks = idr.hooks
|
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)
|
|
||||||
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
|
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
|
||||||
|
@ -2504,22 +2430,64 @@ local function world_new()
|
||||||
if on_change then
|
if on_change then
|
||||||
on_change(entity, id, data)
|
on_change(entity, id, data)
|
||||||
end
|
end
|
||||||
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if from then
|
|
||||||
-- If there was a previous archetype, then the entity needs to move the archetype
|
|
||||||
entity_move(entity_index, entity, record, to)
|
|
||||||
else
|
else
|
||||||
new_entity(entity, record, to)
|
local to: Archetype
|
||||||
end
|
local idr: ComponentRecord
|
||||||
local column = to.columns_map[id]
|
local idr_hooks
|
||||||
column[record.row] = data
|
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)
|
||||||
|
idr = component_index[wc]
|
||||||
|
if idr and bit32.btest(idr.flags, ECS_ID_IS_EXCLUSIVE) then
|
||||||
|
local cr = idr.records[src.id]
|
||||||
|
if cr then
|
||||||
|
local on_remove = idr.hooks.on_remove
|
||||||
|
local id_types = src.types
|
||||||
|
if on_remove then
|
||||||
|
on_remove(entity, id_types[cr])
|
||||||
|
src = record.archetype
|
||||||
|
id_types = src.types
|
||||||
|
cr = idr.records[src.id]
|
||||||
|
end
|
||||||
|
local dst = table.clone(id_types)
|
||||||
|
dst[cr] = id
|
||||||
|
to = archetype_ensure(world, dst)
|
||||||
|
else
|
||||||
|
to = find_archetype_with(world, id, src)
|
||||||
|
idr = component_index[id]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
to = find_archetype_with(world, id, src)
|
||||||
|
idr = component_index[id]
|
||||||
|
end
|
||||||
|
edge[id] = to
|
||||||
|
else
|
||||||
|
idr = component_index[id]
|
||||||
|
end
|
||||||
|
idr_hooks = idr.hooks
|
||||||
|
else
|
||||||
|
to = inner_archetype_traverse_add(id, from)
|
||||||
|
idr = component_index[id]
|
||||||
|
end
|
||||||
|
|
||||||
local on_add = idr_hooks.on_add
|
if from then
|
||||||
if on_add then
|
-- If there was a previous archetype, then the entity needs to move the archetype
|
||||||
on_add(entity, id, data)
|
entity_move(entity_index, entity, record, to)
|
||||||
|
else
|
||||||
|
new_entity(entity, record, to)
|
||||||
|
end
|
||||||
|
|
||||||
|
idr_hooks = idr.hooks
|
||||||
|
column = to.columns_map[id]
|
||||||
|
column[record.row] = data
|
||||||
|
|
||||||
|
local on_add = idr_hooks.on_add
|
||||||
|
if on_add then
|
||||||
|
on_add(entity, id, data)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue