diff --git a/benches/deferring.luau b/benches/deferring.luau index fc5990b4..340a9f61 100644 --- a/benches/deferring.luau +++ b/benches/deferring.luau @@ -27,7 +27,7 @@ do TITLE "deferring" for i = 1, START(N) do world:defer() - for i = 1, 100 do + for i = 1, 10 do local e = world:entity() world:set(e, A, 1) world:set(e, B, 1) @@ -54,7 +54,7 @@ do TITLE "immediate" BENCH("", function() for i = 1, START(N) do - for i = 1, 100 do + for i = 1, 10 do local e = world:entity() world:set(e, A, 1) world:set(e, B, 1) diff --git a/docs/public/1221187281139007539.webp b/docs/public/1221187281139007539.webp new file mode 100644 index 00000000..54499a84 Binary files /dev/null and b/docs/public/1221187281139007539.webp differ diff --git a/src/init.luau b/src/init.luau index f635e187..72cfc100 100644 --- a/src/init.luau +++ b/src/init.luau @@ -755,6 +755,8 @@ local function world_merge(world: World) local entityIndex = world.entityIndex local sparse = entityIndex.sparse local staged = world.staged + local root = world.ROOT_ARCHETYPE + for _, cmd in world.commands do local id = cmd.id local entity = cmd.entity @@ -762,15 +764,17 @@ local function world_merge(world: World) local record = sparse[entity] local from = record.archetype if (bit32.band(kind, CMD_KIND_ADD)) ~= 0 then - local to = archetype_traverse_add( - world, id, from) local batch = staged[entity] if not batch then - batch = { values = {} } + batch = { values = {}, to = {} } staged[entity] = batch end - batch.to = to + local to = batch.to + local at = find_insert(to, id) + if at ~= -1 then + table.insert(to, at, id) + end if kind == CMD_KIND_SET then batch.values[id] = cmd.value @@ -781,26 +785,36 @@ local function world_merge(world: World) end local batch = staged[entity] if not batch then - batch = { values = {} } + batch = { values = {}, to = {} } staged[entity] = batch end - local to = archetype_traverse_remove( - world, id, from) + local at = table.find(to, id) + table.remove(to, at) - batch.to = to local values = batch.values values[id] = nil elseif kind == CMD_KIND_CLEAR then - if from then - entity_move(entityIndex, entity, - record, world.ROOT_ARCHETYPE) + local batch = staged[entity] + if not batch then + batch = { values = {}, to = {} } + staged[entity] = batch end + batch.to = {} end end for entity, batch in staged do local record = sparse[entity] - local to = batch.to local from = record.archetype + local to = batch.to + if from then + for _, id in from.types do + to[#to + 1] = id + end + table.sort(to) + end + + to = archetype_ensure(world, to, from) + if from and (not from == to) then entity_move(entityIndex, entity, record, to) else diff --git a/test/tests.luau b/test/tests.luau index 0c127f75..daccfd1e 100644 --- a/test/tests.luau +++ b/test/tests.luau @@ -813,7 +813,7 @@ TEST("world:defer", function() world:add(e2, B) world:merge() - CHECK(world:has(e2, A)) + print(CHECK(world:has(e2, A))) CHECK(world:has(e2, B)) end end)