mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-15 04:15:28 +07:00
batch-multi-api: batch_multi_insert impl
This commit is contained in:
@@ -4084,3 +4084,258 @@ do
|
||||
assert(last_assign_old_component == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
|
||||
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_insert(q, {}) == 0)
|
||||
assert(evo.batch_multi_insert(q, { f1 }) == 0)
|
||||
end
|
||||
|
||||
do
|
||||
local q = evo.query():include(f3):build()
|
||||
|
||||
assert(evo.batch_multi_insert(q, { f4 }) == 1)
|
||||
assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 33 and evo.get(e3, f4) == true)
|
||||
assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == 43 and evo.get(e4, f4) == 44)
|
||||
|
||||
do
|
||||
local c123, c123_es = evo.chunk(f1, f2, f3)
|
||||
assert(c123 and #c123_es == 0)
|
||||
assert(#evo.select(c123, f1) == 0)
|
||||
assert(#evo.select(c123, f2) == 0)
|
||||
assert(#evo.select(c123, f3) == 0)
|
||||
|
||||
local c1234, c1234_es = evo.chunk(f1, f2, f3, f4)
|
||||
assert(c1234 and #c1234_es == 2)
|
||||
assert(#evo.select(c1234, f1) == 2)
|
||||
assert(#evo.select(c1234, f2) == 2)
|
||||
assert(#evo.select(c1234, f3) == 2)
|
||||
assert(#evo.select(c1234, f4) == 2)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local q = evo.query():include(f1):build()
|
||||
|
||||
assert(evo.batch_multi_insert(q, { f3, f4 }, { 53, 54 }) == 2)
|
||||
assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == 53 and evo.get(e1, f4) == 54)
|
||||
assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == 53 and evo.get(e2, f4) == 54)
|
||||
assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 33 and evo.get(e3, f4) == true)
|
||||
assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == 43 and evo.get(e4, f4) == 44)
|
||||
|
||||
do
|
||||
local c1, c1_es = evo.chunk(f1)
|
||||
assert(c1 and #c1_es == 0)
|
||||
assert(#evo.select(c1, f1) == 0)
|
||||
end
|
||||
|
||||
do
|
||||
local c12, c12_es = evo.chunk(f1, f2)
|
||||
assert(c12 and #c12_es == 0)
|
||||
assert(#evo.select(c12, f1) == 0)
|
||||
assert(#evo.select(c12, f2) == 0)
|
||||
end
|
||||
|
||||
do
|
||||
local c134, c134_es = evo.chunk(f1, f3, f4)
|
||||
assert(c134 and #c134_es == 1)
|
||||
assert(#evo.select(c134, f1) == 1)
|
||||
assert(#evo.select(c134, f3) == 1)
|
||||
assert(#evo.select(c134, f4) == 1)
|
||||
end
|
||||
|
||||
do
|
||||
local c1234, c1234_es = evo.chunk(f1, f2, f3, f4)
|
||||
assert(c1234 and #c1234_es == 3)
|
||||
assert(#evo.select(c1234, f1) == 3)
|
||||
assert(#evo.select(c1234, f2) == 3)
|
||||
assert(#evo.select(c1234, f3) == 3)
|
||||
assert(#evo.select(c1234, f4) == 3)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
|
||||
evo.set(f2, evo.DEFAULT, 41)
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
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()
|
||||
|
||||
assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil)
|
||||
assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil)
|
||||
assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil)
|
||||
assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil and evo.get(e4, f4) == 44)
|
||||
|
||||
do
|
||||
local q = evo.query():include(f1):build()
|
||||
assert(evo.batch_multi_insert(q, {}) == 0)
|
||||
end
|
||||
|
||||
do
|
||||
local q = evo.query():include(f1):build()
|
||||
assert(evo.batch_multi_insert(q, { f2 }) == 1)
|
||||
|
||||
assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == 41 and evo.get(e1, f3) == nil)
|
||||
assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil)
|
||||
assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil)
|
||||
assert(evo.get(e4, f1) == 41 and evo.get(e4, f2) == 42 and evo.get(e4, f3) == nil and evo.get(e4, f4) == 44)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4, f5 = evo.id(5)
|
||||
|
||||
evo.set(f2, evo.DEFAULT, 42)
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
local sum_entity = 0
|
||||
local last_insert_entity = 0
|
||||
local last_insert_component = 0
|
||||
|
||||
evo.set(f1, evo.ON_INSERT, function(e, f, c)
|
||||
assert(f == f1)
|
||||
sum_entity = sum_entity + e
|
||||
last_insert_entity = e
|
||||
last_insert_component = c
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_INSERT, function(e, f, c)
|
||||
assert(f == f2)
|
||||
sum_entity = sum_entity + e
|
||||
last_insert_entity = e
|
||||
last_insert_component = c
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_INSERT, function(e, f, c)
|
||||
assert(f == f3)
|
||||
sum_entity = sum_entity + e
|
||||
last_insert_entity = e
|
||||
last_insert_component = c
|
||||
end)
|
||||
|
||||
evo.set(f4, evo.ON_INSERT, function(e, f, c)
|
||||
assert(f == f4)
|
||||
sum_entity = sum_entity + e
|
||||
last_insert_entity = e
|
||||
last_insert_component = c
|
||||
end)
|
||||
|
||||
evo.set(f5, evo.ON_INSERT, function(e, f, c)
|
||||
assert(f == f5)
|
||||
sum_entity = sum_entity + e
|
||||
last_insert_entity = e
|
||||
last_insert_component = c
|
||||
end)
|
||||
|
||||
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()
|
||||
|
||||
do
|
||||
local q = evo.query():include(f1):build()
|
||||
|
||||
sum_entity = 0
|
||||
last_insert_entity = 0
|
||||
last_insert_component = 0
|
||||
|
||||
assert(evo.batch_multi_insert(q, { f2 }) == 1)
|
||||
assert(sum_entity == e1)
|
||||
assert(last_insert_entity == e1)
|
||||
assert(last_insert_component == 42)
|
||||
assert(evo.has(e1, f1) and evo.has(e1, f2) and not evo.has(e1, f3))
|
||||
assert(evo.has(e2, f1) and evo.has(e2, f2) and not evo.has(e2, f3))
|
||||
assert(evo.has(e3, f1) and evo.has(e3, f2) and evo.has(e3, f3))
|
||||
assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == 42 and evo.get(e1, f3) == nil)
|
||||
assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil)
|
||||
assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local q = evo.query():include(f2):build()
|
||||
|
||||
sum_entity = 0
|
||||
last_insert_entity = 0
|
||||
last_insert_component = 0
|
||||
|
||||
assert(evo.batch_multi_insert(q, { f3 }) == 2)
|
||||
assert(sum_entity == e1 + e2)
|
||||
assert(last_insert_entity == e1)
|
||||
assert(last_insert_component == nil)
|
||||
assert(evo.has(e1, f1) and evo.has(e1, f2) and evo.has(e1, f3))
|
||||
assert(evo.has(e2, f1) and evo.has(e2, f2) and evo.has(e2, f3))
|
||||
assert(evo.has(e3, f1) and evo.has(e3, f2) and evo.has(e3, f3))
|
||||
assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == 42 and evo.get(e1, f3) == nil)
|
||||
assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil)
|
||||
assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local q = evo.query():include(f1, f2, f3):build()
|
||||
|
||||
sum_entity = 0
|
||||
last_insert_entity = 0
|
||||
last_insert_component = 0
|
||||
|
||||
assert(evo.batch_multi_insert(q, { f3, f4, f5, f5 }, { 53, 54, 55, 65 }) == 3)
|
||||
assert(sum_entity == e1 + e2 + e3 + e1 + e2 + e3)
|
||||
assert(last_insert_entity == e1)
|
||||
assert(last_insert_component == 55)
|
||||
assert(evo.has_all(e1, f1, f2, f3, f4, f5))
|
||||
assert(evo.has_all(e2, f1, f2, f3, f4, f5))
|
||||
assert(evo.has_all(e3, f1, f2, f3, f4, f5))
|
||||
assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == 42 and evo.get(e1, f3) == nil)
|
||||
assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil)
|
||||
assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == nil)
|
||||
assert(evo.get(e1, f4) == 54 and evo.get(e1, f5) == 55)
|
||||
assert(evo.get(e2, f4) == 54 and evo.get(e2, f5) == 55)
|
||||
assert(evo.get(e3, f4) == 54 and evo.get(e3, f5) == 55)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
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()
|
||||
|
||||
assert(evo.defer())
|
||||
do
|
||||
local q = evo.query():include(f1):build()
|
||||
do
|
||||
local n, d = evo.batch_multi_insert(q, { f2 }, { 42 })
|
||||
assert(n == 0 and d == true)
|
||||
end
|
||||
do
|
||||
local n, d = evo.batch_multi_assign(q, { f3 }, { 43 })
|
||||
assert(n == 0 and d == true)
|
||||
end
|
||||
do
|
||||
local n, d = evo.batch_multi_remove(q, { f1 })
|
||||
assert(n == 0 and d == true)
|
||||
end
|
||||
assert(evo.get(e1, f1) == 11 and evo.get(e1, f2) == nil and evo.get(e1, f3) == nil)
|
||||
assert(evo.get(e2, f1) == 21 and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil)
|
||||
assert(evo.get(e3, f1) == 31 and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 33)
|
||||
end
|
||||
assert(evo.commit())
|
||||
do
|
||||
assert(evo.get(e1, f1) == nil and evo.get(e1, f2) == 42 and evo.get(e1, f3) == nil)
|
||||
assert(evo.get(e2, f1) == nil and evo.get(e2, f2) == 22 and evo.get(e2, f3) == nil)
|
||||
assert(evo.get(e3, f1) == nil and evo.get(e3, f2) == 32 and evo.get(e3, f3) == 43)
|
||||
end
|
||||
end
|
||||
|
||||
147
evolved.lua
147
evolved.lua
@@ -1473,7 +1473,152 @@ end
|
||||
---@param components evolved.component[]
|
||||
---@return integer inserted_count
|
||||
local function __chunk_multi_insert(chunk, fragments, components)
|
||||
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_with_fragment_list(chunk, fragments)
|
||||
|
||||
if not new_chunk or 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_storages = old_chunk.__component_storages
|
||||
local old_component_fragments = old_chunk.__component_fragments
|
||||
|
||||
local new_entities = new_chunk.__entities
|
||||
local new_size = #new_entities
|
||||
|
||||
local new_component_indices = new_chunk.__component_indices
|
||||
local new_component_storages = new_chunk.__component_storages
|
||||
|
||||
do
|
||||
__table_move(
|
||||
old_entities, 1, old_size,
|
||||
new_size + 1, new_entities)
|
||||
|
||||
for i = 1, #old_component_fragments do
|
||||
local old_f = old_component_fragments[i]
|
||||
local old_cs = old_component_storages[i]
|
||||
local new_ci = new_component_indices[old_f]
|
||||
if new_ci then
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
__table_move(old_cs, 1, old_size, new_size + 1, new_cs)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local inserted_set = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_SET, 0, fragment_count)
|
||||
|
||||
for i = 1, fragment_count do
|
||||
local fragment = fragments[i]
|
||||
if not inserted_set[fragment] and not old_fragment_set[fragment] then
|
||||
inserted_set[fragment] = true
|
||||
if new_chunk.__has_set_or_insert_hooks and __fragment_has_set_or_insert_hooks(fragment) then
|
||||
local new_component_index = new_component_indices[fragment]
|
||||
if new_component_index then
|
||||
local new_component_storage = new_component_storages[new_component_index]
|
||||
if new_chunk.__has_defaults_or_constructs and __fragment_has_default_or_construct(fragment) then
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then
|
||||
new_component = evolved.get(fragment, evolved.DEFAULT)
|
||||
end
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
for new_place = new_size + 1, new_size + old_size do
|
||||
local entity = new_entities[new_place]
|
||||
new_component_storage[new_place] = new_component
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment, new_component)
|
||||
end
|
||||
else
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
for new_place = new_size + 1, new_size + old_size do
|
||||
local entity = new_entities[new_place]
|
||||
new_component_storage[new_place] = new_component
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment, new_component)
|
||||
end
|
||||
end
|
||||
else
|
||||
for new_place = new_size + 1, new_size + old_size do
|
||||
local entity = new_entities[new_place]
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment)
|
||||
end
|
||||
end
|
||||
else
|
||||
local new_component_index = new_component_indices[fragment]
|
||||
if new_component_index then
|
||||
local new_component_storage = new_component_storages[new_component_index]
|
||||
if new_chunk.__has_defaults_or_constructs and __fragment_has_default_or_construct(fragment) then
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then
|
||||
new_component = evolved.get(fragment, evolved.DEFAULT)
|
||||
end
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
for new_place = new_size + 1, new_size + old_size do
|
||||
new_component_storage[new_place] = new_component
|
||||
end
|
||||
else
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
for new_place = new_size + 1, new_size + old_size do
|
||||
new_component_storage[new_place] = new_component
|
||||
end
|
||||
end
|
||||
else
|
||||
-- nothing
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_SET, inserted_set)
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
---@param chunk evolved.chunk
|
||||
|
||||
Reference in New Issue
Block a user