fix multi_set/insert/remove with duplicate fragments

This commit is contained in:
BlackMATov
2025-01-09 17:35:45 +07:00
parent 255e66dba6
commit a440a2995d
2 changed files with 128 additions and 6 deletions

View File

@@ -2452,6 +2452,27 @@ do
end
end
do
local f1, f2 = evo.id(2)
do
local e = evo.entity()
:set(f1, 41)
:set(f2, 42)
:build()
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
end
do
local e = evo.entity()
:set(f1, 11)
:set(f1, 41)
:build()
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
end
end
do
local f1 = evo.fragment():default(41):build()
local f2 = evo.fragment():construct(function() return 42 end):build()
@@ -2578,7 +2599,7 @@ do
assert(evo.commit())
assert(evo.has(e1, f1) and evo.get(e1, f1) == 41)
assert(evo.has(e1, f2) and evo.get(e1, f2) == 42)
assert(evo.has(e2, f2) and evo.get(e2, f2) == 44)
assert(evo.has(e2, f2) and evo.get(e2, f2) == 43)
end
end
@@ -2942,3 +2963,86 @@ do
assert(last_insert_entity == e and last_insert_component == 42)
end
end
do
local f1 = evo.id()
local assign_entity_sum = 0
local assign_component_sum = 0
local insert_entity_sum = 0
local insert_component_sum = 0
local remove_entity_sum = 0
local remove_component_sum = 0
evo.set(f1, evo.ON_ASSIGN, function(e, f, c)
assert(f == f1)
assign_entity_sum = assign_entity_sum + e
assign_component_sum = assign_component_sum + c
end)
evo.set(f1, evo.ON_INSERT, function(e, f, c)
assert(f == f1)
insert_entity_sum = insert_entity_sum + e
insert_component_sum = insert_component_sum + c
end)
evo.set(f1, evo.ON_REMOVE, function(e, f, c)
assert(f == f1)
remove_entity_sum = remove_entity_sum + e
remove_component_sum = remove_component_sum + c
end)
do
assign_entity_sum, assign_component_sum = 0, 0
insert_entity_sum, insert_component_sum = 0, 0
local e = evo.id()
assert(evo.multi_set(e, { f1, f1 }, { 41, 42 }))
assert(assign_entity_sum == e and assign_component_sum == 42)
assert(insert_entity_sum == e and insert_component_sum == 41)
end
do
assign_entity_sum, assign_component_sum = 0, 0
insert_entity_sum, insert_component_sum = 0, 0
local e = evo.id()
assert(evo.multi_set(e, { f1, f1, f1 }, { 41, 42, 43 }))
assert(assign_entity_sum == e + e and assign_component_sum == 42 + 43)
assert(insert_entity_sum == e and insert_component_sum == 41)
end
do
assign_entity_sum, assign_component_sum = 0, 0
insert_entity_sum, insert_component_sum = 0, 0
local e = evo.id()
assert(evo.insert(e, f1, 41))
assert(evo.multi_assign(e, { f1, f1 }, { 42, 43 }))
assert(assign_entity_sum == e + e and assign_component_sum == 42 + 43)
assert(insert_entity_sum == e and insert_component_sum == 41)
end
do
assign_entity_sum, assign_component_sum = 0, 0
insert_entity_sum, insert_component_sum = 0, 0
local e = evo.id()
assert(evo.multi_insert(e, { f1, f1 }, { 41, 42 }))
assert(insert_entity_sum == e and insert_component_sum == 41)
end
do
remove_entity_sum, remove_component_sum = 0, 0
local e = evo.id()
assert(evo.insert(e, f1, 41))
assert(evo.multi_remove(e, { f1, f1 }))
assert(remove_entity_sum == e and remove_component_sum == 41)
end
end

View File

@@ -212,14 +212,17 @@ end
---| `__TABLE_POOL_TAG__CHUNK_LIST`
---| `__TABLE_POOL_TAG__EACH_STATE`
---| `__TABLE_POOL_TAG__EXECUTE_STATE`
---| `__TABLE_POOL_TAG__FRAGMENT_SET`
---| `__TABLE_POOL_TAG__FRAGMENT_LIST`
---| `__TABLE_POOL_TAG__COMPONENT_LIST`
local __TABLE_POOL_TAG__BYTECODE = 1
local __TABLE_POOL_TAG__CHUNK_LIST = 2
local __TABLE_POOL_TAG__EACH_STATE = 3
local __TABLE_POOL_TAG__EXECUTE_STATE = 4
local __TABLE_POOL_TAG__FRAGMENT_LIST = 5
local __TABLE_POOL_TAG__COMPONENT_LIST = 6
local __TABLE_POOL_TAG__FRAGMENT_SET = 5
local __TABLE_POOL_TAG__FRAGMENT_LIST = 7
local __TABLE_POOL_TAG__COMPONENT_LIST = 8
---@type table<evolved.table_pool_tag, table[]>
local __tagged_table_pools = __table_new(6, 0)
@@ -2561,9 +2564,11 @@ function evolved.multi_set(entity, fragments, components)
__detach_entity(entity)
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 old_fragment_set[fragment] then
if inserted_set[fragment] or old_fragment_set[fragment] then
local new_component_index = new_component_indices[fragment]
if new_component_index then
@@ -2597,6 +2602,8 @@ function evolved.multi_set(entity, fragments, components)
end
end
else
inserted_set[fragment] = true
local new_component_index = new_component_indices[fragment]
if new_component_index then
@@ -2631,6 +2638,8 @@ function evolved.multi_set(entity, fragments, components)
end
end
__release_table(__TABLE_POOL_TAG__FRAGMENT_SET, inserted_set)
__entity_chunks[entity_index] = new_chunk
__entity_places[entity_index] = new_place
@@ -2790,9 +2799,13 @@ function evolved.multi_insert(entity, fragments, components)
__detach_entity(entity)
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 old_fragment_set[fragment] then
if not inserted_set[fragment] and not old_fragment_set[fragment] then
inserted_set[fragment] = true
local new_component_index = new_component_indices[fragment]
if new_component_index then
@@ -2876,9 +2889,12 @@ function evolved.multi_remove(entity, fragments)
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 old_fragment_set[fragment] then
if not removed_set[fragment] and old_fragment_set[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]
@@ -2889,6 +2905,8 @@ function evolved.multi_remove(entity, fragments)
end
end
end
__release_table(__TABLE_POOL_TAG__FRAGMENT_SET, removed_set)
end
if new_chunk then