Inline into world:add

This commit is contained in:
Ukendio 2025-07-04 00:10:28 +02:00
parent 7dc8bb5759
commit a40bfab47b
2 changed files with 87 additions and 45 deletions

128
jecs.luau
View file

@ -929,18 +929,6 @@ local function find_archetype_with(world: World, id: Id, from: Archetype): Arche
local id_types = from.types local id_types = from.types
local dst = table.clone(id_types) local dst = table.clone(id_types)
if ECS_IS_PAIR(id::number) then
local first = ECS_PAIR_FIRST(id::number)
local idr = world.component_index[ECS_PAIR(first, EcsWildcard)]
if idr and bit32.btest(idr.flags, EcsExclusive) then
local cr = idr.records[from.id]
if cr then
dst[cr] = id
return archetype_ensure(world, dst)
end
end
end
local at = find_insert(id_types :: { number } , id :: number) local at = find_insert(id_types :: { number } , id :: number)
table.insert(dst, at, id) table.insert(dst, at, id)
@ -2204,6 +2192,90 @@ local function world_new()
return r return r
end end
local function inner_world_add<T, a>(
world: World,
entity: Entity<T>,
id: Id<a>
): ()
local entity_index = world.entity_index
local record = inner_entity_index_try_get_unsafe(entity :: number)
if not record then
return
end
local from = 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 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
if from == to then
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 on_add = idr.hooks.on_add
if on_add then
on_add(entity, id)
end
return
end
local to = archetype_traverse_add(world, id, from)
if from == to then
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 idr = world.component_index[id]
local on_add = idr.hooks.on_add
if on_add then
on_add(entity, id)
end
end
local function inner_world_get(world: World, entity: Entity, local function inner_world_get(world: World, entity: Entity,
a: Id, b: Id?, c: Id?, d: Id?, e: Id?): ...any a: Id, b: Id?, c: Id?, d: Id?, e: Id?): ...any
@ -2319,38 +2391,6 @@ local function world_new()
return to return to
end end
local function inner_world_add<T, a>(
world: World,
entity: Entity<T>,
id: Id<a>
): ()
local entity_index = world.entity_index
local record = inner_entity_index_try_get_unsafe(entity :: number)
if not record then
return
end
local from = record.archetype
local to = archetype_traverse_add(world, id, from)
if from == to then
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 idr = world.component_index[id]
local on_add = idr.hooks.on_add
if on_add then
on_add(entity, id)
end
end
local function inner_world_set<T, a>(world: World, entity: Entity<T>, id: Id<a>, data: a): () local function inner_world_set<T, a>(world: World, entity: Entity<T>, id: Id<a>, data: a): ()
local record = inner_entity_index_try_get_unsafe(entity :: number) local record = inner_entity_index_try_get_unsafe(entity :: number)
if not record then if not record then

View file

@ -159,7 +159,6 @@ TEST("repro", function()
end) end)
TEST("world:add()", function() TEST("world:add()", function()
print("-----")
do CASE "idempotent" do CASE "idempotent"
local world = jecs.world() local world = jecs.world()
local d = dwi(world) local d = dwi(world)
@ -211,6 +210,9 @@ TEST("world:children()", function()
local e3 = world:entity() local e3 = world:entity()
world:add(e3, pair(ChildOf, e1)) world:add(e3, pair(ChildOf, e1))
CHECK(world:has(e2, pair(ChildOf, e1)))
CHECK(world:has(e3, pair(ChildOf, e1)))
local count = 0 local count = 0
for entity in world:children(e1) do for entity in world:children(e1) do
count += 1 count += 1