diff --git a/develop/unbench.lua b/develop/unbench.lua index eba4aaa..b7016cd 100644 --- a/develop/unbench.lua +++ b/develop/unbench.lua @@ -610,28 +610,6 @@ basics.describe_bench(string.format('create and destroy %d entities with 5 compo print '----------------------------------------' -basics.describe_bench(string.format('create and destroy %d entities / spawn_at', N), - ---@param entities evolved.id[] - function(entities) - local destroy = evo.destroy - local spawn_at = evo.spawn_at - - local fragments = {} - local components = {} - - local chunk = nil - - for i = 1, N do - entities[i] = spawn_at(chunk, fragments, components) - end - - for i = #entities, 1, -1 do - destroy(entities[i]) - end - end, function() - return {} - end) - basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn_at', N), ---@param entities evolved.id[] function(entities) @@ -729,26 +707,103 @@ basics.describe_bench(string.format('create and destroy %d entities with 5 compo print '----------------------------------------' -basics.describe_bench(string.format('create and destroy %d entities / spawn_with', N), +basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn_as', N), ---@param entities evolved.id[] function(entities) - local destroy = evo.destroy - local spawn_with = evo.spawn_with + local spawn_as = evo.spawn_as - local fragments = {} - local components = {} + local fragments = { F1 } + local components = { true } + + local prefab = evo.spawn_with(fragments, components) for i = 1, N do - entities[i] = spawn_with(fragments, components) + entities[i] = spawn_as(prefab, fragments, components) end - for i = #entities, 1, -1 do - destroy(entities[i]) - end + evo.batch_destroy(Q1) end, function() return {} end) +basics.describe_bench(string.format('create and destroy %d entities with 2 components / spawn_as', N), + ---@param entities evolved.id[] + function(entities) + local spawn_as = evo.spawn_as + + local fragments = { F1, F2 } + local components = { true, true } + + local prefab = evo.spawn_with(fragments, components) + + for i = 1, N do + entities[i] = spawn_as(prefab, fragments, components) + end + + evo.batch_destroy(Q1) + end, function() + return {} + end) + +basics.describe_bench(string.format('create and destroy %d entities with 3 components / spawn_as', N), + ---@param entities evolved.id[] + function(entities) + local spawn_as = evo.spawn_as + + local fragments = { F1, F2, F3 } + local components = { true, true, true } + + local prefab = evo.spawn_with(fragments, components) + + for i = 1, N do + entities[i] = spawn_as(prefab, fragments, components) + end + + evo.batch_destroy(Q1) + end, function() + return {} + end) + +basics.describe_bench(string.format('create and destroy %d entities with 4 components / spawn_as', N), + ---@param entities evolved.id[] + function(entities) + local spawn_as = evo.spawn_as + + local fragments = { F1, F2, F3, F4 } + local components = { true, true, true, true } + + local prefab = evo.spawn_with(fragments, components) + + for i = 1, N do + entities[i] = spawn_as(prefab, fragments, components) + end + + evo.batch_destroy(Q1) + end, function() + return {} + end) + +basics.describe_bench(string.format('create and destroy %d entities with 5 components / spawn_as', N), + ---@param entities evolved.id[] + function(entities) + local spawn_as = evo.spawn_as + + local fragments = { F1, F2, F3, F4, F5 } + local components = { true, true, true, true, true } + + local prefab = evo.spawn_with(fragments, components) + + for i = 1, N do + entities[i] = spawn_as(prefab, fragments, components) + end + + evo.batch_destroy(Q1) + end, function() + return {} + end) + +print '----------------------------------------' + basics.describe_bench(string.format('create and destroy %d entities with 1 components / spawn_with', N), ---@param entities evolved.id[] function(entities) diff --git a/evolved.lua b/evolved.lua index 3d2db58..e6b05f4 100644 --- a/evolved.lua +++ b/evolved.lua @@ -2224,6 +2224,23 @@ local function __purge_chunk(chunk) chunk.__unreachable_or_collected = true end +---@param chunk_list evolved.chunk[] +---@param chunk_count integer +local function __clear_chunk_list(chunk_list, chunk_count) + if __defer_depth <= 0 then + __error_fmt('this operation should be deferred') + end + + if chunk_count == 0 then + return + end + + for i = 1, chunk_count do + local chunk = chunk_list[i] + __chunk_clear(chunk) + end +end + ---@param entity_list evolved.entity[] ---@param entity_count integer local function __destroy_entity_list(entity_list, entity_count) @@ -5711,6 +5728,9 @@ __evolved_batch_destroy = function(...) __evolved_defer() do + local clearing_chunk_list = __acquire_table(__table_pool_tag.chunk_stack) + local clearing_chunk_count = 0 + local purging_entity_list = __acquire_table(__table_pool_tag.entity_list) local purging_entity_count = 0 @@ -5725,7 +5745,10 @@ __evolved_batch_destroy = function(...) if __freelist_ids[query_index] ~= query then -- this query is not alive, nothing to destroy else - for _, entity_list, entity_count in __evolved_execute(query) do + for chunk, entity_list, entity_count in __evolved_execute(query) do + clearing_chunk_count = clearing_chunk_count + 1 + clearing_chunk_list[clearing_chunk_count] = chunk + for i = 1, entity_count do local entity = entity_list[i] @@ -5741,19 +5764,26 @@ __evolved_batch_destroy = function(...) end end - if purging_entity_count > 0 then - __destroy_entity_list(purging_entity_list, purging_entity_count) - __release_table(__table_pool_tag.entity_list, purging_entity_list) - else - __release_table(__table_pool_tag.entity_list, purging_entity_list, true) - end - if purging_fragment_count > 0 then __destroy_fragment_list(purging_fragment_list, purging_fragment_count) __release_table(__table_pool_tag.fragment_list, purging_fragment_list) else __release_table(__table_pool_tag.fragment_list, purging_fragment_list, true) end + + if clearing_chunk_count > 0 then + __clear_chunk_list(clearing_chunk_list, clearing_chunk_count) + __release_table(__table_pool_tag.chunk_stack, clearing_chunk_list) + else + __release_table(__table_pool_tag.chunk_stack, clearing_chunk_list, true) + end + + if purging_entity_count > 0 then + __destroy_entity_list(purging_entity_list, purging_entity_count) + __release_table(__table_pool_tag.entity_list, purging_entity_list) + else + __release_table(__table_pool_tag.entity_list, purging_entity_list, true) + end end __evolved_commit()