mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-16 14:11:16 +07:00
batch-multi-api: batch_multi_remove impl
This commit is contained in:
@@ -3710,3 +3710,152 @@ do
|
||||
assert(evo.has(e2, f4) and evo.get(e2, f4) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4, f5 = evo.id(5)
|
||||
|
||||
local e1 = evo.entity():set(f1, 11):build()
|
||||
local e2 = evo.entity():set(f1, 21):set(f2, 22):build()
|
||||
local e3 = evo.entity():set(f1, 31):set(f2, 32):set(f3, 33):build()
|
||||
local e4 = evo.entity():set(f1, 41):set(f2, 42):set(f3, 43):set(f4, 44):build()
|
||||
|
||||
do
|
||||
local q = evo.query():include(f1):build()
|
||||
assert(evo.batch_multi_remove(q, {}) == 0)
|
||||
assert(evo.batch_multi_remove(q, { f5 }) == 0)
|
||||
end
|
||||
|
||||
do
|
||||
local q = evo.query():include(f3):build()
|
||||
|
||||
assert(evo.batch_multi_remove(q, { f4 }) == 1)
|
||||
assert(evo.has_all(e4, f1, f2, f3) and not evo.has(e4, f4))
|
||||
assert(evo.get(e4, f1) == 41)
|
||||
assert(evo.get(e4, f2) == 42)
|
||||
assert(evo.get(e4, f3) == 43)
|
||||
assert(evo.get(e4, f4) == nil)
|
||||
|
||||
for chunk in evo.execute(q) do
|
||||
assert(next(evo.select(chunk, f4)) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local chunk, entities = evo.chunk(f1, f2, f3)
|
||||
assert(chunk and entities)
|
||||
assert(#entities == 2)
|
||||
assert(entities[1] == e3, entities[2] == e4)
|
||||
assert(evo.select(chunk, f3)[1] == 33)
|
||||
assert(evo.select(chunk, f3)[2] == 43)
|
||||
end
|
||||
|
||||
do
|
||||
local chunk, entities = evo.chunk(f1, f2, f3, f4)
|
||||
assert(chunk)
|
||||
assert(next(evo.select(chunk, f4)) == nil)
|
||||
assert(#entities == 0)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local q = evo.query():include(f2):build()
|
||||
|
||||
assert(evo.batch_multi_remove(q, { f1 }) == 3)
|
||||
assert(evo.has_all(e1, f1) and not evo.has_any(e1, f2, f3, f4))
|
||||
assert(evo.has_all(e2, f2) and not evo.has_any(e2, f1, f3, f4))
|
||||
assert(evo.has_all(e3, f2, f3) and not evo.has_any(e3, f1, f4))
|
||||
assert(evo.has_all(e4, f2, f3) and not evo.has_any(e4, f1, f4))
|
||||
|
||||
for chunk in evo.execute(q) do
|
||||
assert(next(evo.select(chunk, f1)) == nil)
|
||||
end
|
||||
|
||||
assert(evo.batch_multi_remove(q, { f2, f3 }) == 3)
|
||||
assert(evo.has_all(e1, f1) and not evo.has_any(e1, f2, f3, f4))
|
||||
assert(not evo.has_any(e2, f1, f2, f3, f4))
|
||||
assert(not evo.has_any(e3, f1, f2, f3, f4))
|
||||
assert(not evo.has_any(e4, f1, f2, f3, f4))
|
||||
|
||||
for chunk in evo.execute(q) do
|
||||
assert(next(evo.select(chunk, f2)) == nil)
|
||||
assert(next(evo.select(chunk, f3)) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local chunk, entities = evo.chunk(f1, f2)
|
||||
assert(chunk)
|
||||
assert(next(evo.select(chunk, f1)) == nil)
|
||||
assert(next(evo.select(chunk, f2)) == nil)
|
||||
assert(#entities == 0)
|
||||
end
|
||||
|
||||
do
|
||||
local chunk, entities = evo.chunk(f1, f2, f3)
|
||||
assert(chunk)
|
||||
assert(next(evo.select(chunk, f1)) == nil)
|
||||
assert(next(evo.select(chunk, f2)) == nil)
|
||||
assert(next(evo.select(chunk, f3)) == nil)
|
||||
assert(#entities == 0)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local q = evo.query():include(f1):build()
|
||||
|
||||
assert(evo.defer())
|
||||
assert(evo.batch_multi_remove(q, { f1 }) == 0)
|
||||
assert(evo.has(e1, f1))
|
||||
assert(evo.commit())
|
||||
assert(not evo.has(e1, f1))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
evo.set(f2, evo.TAG)
|
||||
|
||||
local last_remove_entity = 0
|
||||
local last_remove_component = 0
|
||||
local sum_removed_components = 0
|
||||
|
||||
evo.set(f1, evo.ON_REMOVE, function(e, f, c)
|
||||
assert(f == f1)
|
||||
last_remove_entity = e
|
||||
last_remove_component = c
|
||||
sum_removed_components = sum_removed_components + c
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_REMOVE, function(e, f, c)
|
||||
assert(f == f2)
|
||||
last_remove_entity = e
|
||||
last_remove_component = c
|
||||
end)
|
||||
|
||||
local _ = evo.spawn_with({ f1 }, { 11 })
|
||||
local e2 = evo.spawn_with({ f1, f2 }, { 21, 22 })
|
||||
assert(last_remove_entity == 0 and last_remove_component == 0)
|
||||
|
||||
do
|
||||
last_remove_entity = 0
|
||||
last_remove_component = 0
|
||||
sum_removed_components = 0
|
||||
|
||||
local q = evo.query():include(f1):build()
|
||||
|
||||
assert(evo.batch_multi_remove(q, { f1, f1 }) == 2)
|
||||
assert(last_remove_entity == e2 and last_remove_component == 21)
|
||||
assert(sum_removed_components == 11 + 21)
|
||||
end
|
||||
|
||||
do
|
||||
last_remove_entity = 0
|
||||
last_remove_component = 0
|
||||
sum_removed_components = 0
|
||||
|
||||
local q = evo.query():include(f2):build()
|
||||
|
||||
assert(evo.batch_multi_remove(q, { f2 }) == 1)
|
||||
assert(last_remove_entity == e2 and last_remove_component == nil)
|
||||
assert(sum_removed_components == 0)
|
||||
end
|
||||
end
|
||||
|
||||
100
evolved.lua
100
evolved.lua
@@ -1377,7 +1377,105 @@ end
|
||||
---@param fragments evolved.fragment[]
|
||||
---@return integer removed_count
|
||||
local function __chunk_multi_remove(chunk, fragments)
|
||||
error('not implemented yet', 2)
|
||||
if __defer_depth <= 0 then
|
||||
error('batched chunk operations should be deferred', 2)
|
||||
end
|
||||
|
||||
local fragment_count = #fragments
|
||||
|
||||
if fragment_count == 0 then
|
||||
return 0
|
||||
end
|
||||
|
||||
local old_chunk = chunk
|
||||
local new_chunk = __chunk_without_fragment_list(chunk, fragments)
|
||||
|
||||
if old_chunk == new_chunk then
|
||||
return 0
|
||||
end
|
||||
|
||||
local old_entities = old_chunk.__entities
|
||||
local old_size = #old_entities
|
||||
|
||||
local old_fragment_set = old_chunk.__fragment_set
|
||||
local old_component_indices = old_chunk.__component_indices
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
|
||||
if old_chunk.__has_remove_hooks then
|
||||
local removed_set = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_SET, 0, fragment_count)
|
||||
|
||||
for i = 1, fragment_count do
|
||||
local fragment = fragments[i]
|
||||
|
||||
if not removed_set[fragment] and old_fragment_set[fragment] and __fragment_has_remove_hook(fragment) then
|
||||
removed_set[fragment] = true
|
||||
|
||||
local old_component_index = old_component_indices[fragment]
|
||||
|
||||
if old_component_index then
|
||||
local old_component_storage = old_component_storages[old_component_index]
|
||||
|
||||
for old_place = 1, old_size do
|
||||
local entity = old_entities[old_place]
|
||||
local old_component = old_component_storage[old_place]
|
||||
__fragment_call_remove_hook(entity, fragment, old_component)
|
||||
end
|
||||
else
|
||||
for place = 1, old_size do
|
||||
local entity = old_entities[place]
|
||||
__fragment_call_remove_hook(entity, fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if new_chunk then
|
||||
local new_entities = new_chunk.__entities
|
||||
local new_size = #new_entities
|
||||
|
||||
local new_component_storages = new_chunk.__component_storages
|
||||
local new_component_fragments = new_chunk.__component_fragments
|
||||
|
||||
__table_move(
|
||||
old_entities, 1, old_size,
|
||||
new_size + 1, new_entities)
|
||||
|
||||
for i = 1, #new_component_fragments do
|
||||
local new_f = new_component_fragments[i]
|
||||
local new_cs = new_component_storages[i]
|
||||
local old_ci = old_component_indices[new_f]
|
||||
if old_ci then
|
||||
local old_cs = old_component_storages[old_ci]
|
||||
__table_move(old_cs, 1, old_size, new_size + 1, new_cs)
|
||||
end
|
||||
end
|
||||
|
||||
for new_place = new_size + 1, new_size + old_size do
|
||||
local entity = new_entities[new_place]
|
||||
local entity_index = entity % 0x100000
|
||||
__entity_chunks[entity_index] = new_chunk
|
||||
__entity_places[entity_index] = new_place
|
||||
end
|
||||
else
|
||||
for old_place = 1, old_size do
|
||||
local entity = old_entities[old_place]
|
||||
local entity_index = entity % 0x100000
|
||||
__entity_chunks[entity_index] = nil
|
||||
__entity_places[entity_index] = nil
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
old_chunk.__entities = {}
|
||||
|
||||
for i = 1, #old_component_storages do
|
||||
old_component_storages[i] = {}
|
||||
end
|
||||
end
|
||||
|
||||
__structural_changes = __structural_changes + old_size
|
||||
return old_size
|
||||
end
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user