Merge branch 'feature/builders' into feature/benches

This commit is contained in:
BlackMATov
2025-01-09 19:05:47 +07:00
2 changed files with 272 additions and 27 deletions

View File

@@ -2453,6 +2453,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()
@@ -2579,7 +2600,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
@@ -2943,3 +2964,185 @@ 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
do
local f1, f2 = evo.id(2)
local qb = evo.query()
do
local q = qb:build()
local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES)
assert(includes == nil)
assert(excludes == nil)
end
do
local q = qb:include(f1):build()
local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES)
assert(#includes == 1 and includes[1] == f1)
assert(excludes == nil)
end
do
local q = qb:include(f1, f2):build()
local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES)
assert(#includes == 2 and includes[1] == f1 and includes[2] == f2)
assert(excludes == nil)
end
do
local q = qb:include(f1):include(f2):build()
local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES)
assert(#includes == 2 and includes[1] == f1 and includes[2] == f2)
assert(excludes == nil)
end
do
local q = qb:exclude(f1):build()
local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES)
assert(includes == nil)
assert(#excludes == 1 and excludes[1] == f1)
end
do
local q = qb:exclude(f1, f2):build()
local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES)
assert(includes == nil)
assert(#excludes == 2 and excludes[1] == f1 and excludes[2] == f2)
end
do
local q = qb:exclude(f1):exclude(f2):build()
local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES)
assert(includes == nil)
assert(#excludes == 2 and excludes[1] == f1 and excludes[2] == f2)
end
do
qb:include(f1)
qb:exclude(f2)
local q = qb:build()
local includes, excludes = evo.get(q, evo.INCLUDES, evo.EXCLUDES)
assert(#includes == 1 and includes[1] == f1)
assert(#excludes == 1 and excludes[1] == f2)
end
end
do
local f1, f2 = evo.id(2)
local eb = evo.entity()
do
local e = eb:build()
assert(evo.is_alive(e) and evo.is_empty(e))
end
do
local e = eb:set(f1, 41):build()
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
assert(not evo.has(e, f2) and evo.get(e, f2) == nil)
end
do
local e = eb: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 = eb:build()
assert(evo.is_alive(e) and evo.is_empty(e))
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
@@ -3411,8 +3429,8 @@ evolved_entity_builder.__index = evolved_entity_builder
function evolved.entity()
---@type evolved.__entity_builder
local builder = {
__fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 8, 0),
__component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, 8, 0),
__fragment_list = nil,
__component_list = nil,
}
---@cast builder evolved.entity_builder
return setmetatable(builder, evolved_entity_builder)
@@ -3427,6 +3445,13 @@ function evolved_entity_builder:set(fragment, ...)
local fragment_list = self.__fragment_list
local component_list = self.__component_list
if not fragment_list then
fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 8, 0)
component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, 8, 0)
self.__fragment_list = fragment_list
self.__component_list = component_list
end
fragment_list[#fragment_list + 1] = fragment
component_list[#component_list + 1] = component
@@ -3438,17 +3463,17 @@ function evolved_entity_builder:build()
local fragment_list = self.__fragment_list
local component_list = self.__component_list
self.__fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 8, 0)
self.__component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, 8, 0)
self.__fragment_list = nil
self.__component_list = nil
local entity = evolved.id()
for i = 1, #fragment_list do
local fragment = fragment_list[i]
local component = component_list[i]
evolved.set(entity, fragment, component)
if not fragment_list then
return entity
end
evolved.multi_set(entity, fragment_list, component_list)
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_list)
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_list)
@@ -3515,18 +3540,29 @@ function evolved_fragment_builder:build()
local fragment = evolved.id()
local fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 3, 0)
local component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, 3, 0)
if tag then
evolved.set(fragment, evolved.TAG, tag)
fragment_list[#fragment_list + 1] = evolved.TAG
component_list[#component_list + 1] = true
end
if default ~= nil then
evolved.set(fragment, evolved.DEFAULT, default)
fragment_list[#fragment_list + 1] = evolved.DEFAULT
component_list[#component_list + 1] = default
end
if construct ~= nil then
evolved.set(fragment, evolved.CONSTRUCT, construct)
fragment_list[#fragment_list + 1] = evolved.CONSTRUCT
component_list[#component_list + 1] = construct
end
evolved.multi_set(fragment, fragment_list, component_list)
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_list)
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_list)
return fragment
end
@@ -3568,7 +3604,7 @@ function evolved_query_builder:include(...)
local include_list = self.__include_list
if not include_list then
include_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 8, 0)
include_list = __table_new(math.max(8, fragment_count), 0)
self.__include_list = include_list
end
@@ -3576,8 +3612,7 @@ function evolved_query_builder:include(...)
for i = 1, fragment_count do
local fragment = select(i, ...)
include_list[include_list_size + 1] = fragment
include_list_size = include_list_size + 1
include_list[include_list_size + i] = fragment
end
return self
@@ -3595,7 +3630,7 @@ function evolved_query_builder:exclude(...)
local exclude_list = self.__exclude_list
if not exclude_list then
exclude_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 8, 0)
exclude_list = __table_new(math.max(8, fragment_count), 0)
self.__exclude_list = exclude_list
end
@@ -3603,8 +3638,7 @@ function evolved_query_builder:exclude(...)
for i = 1, fragment_count do
local fragment = select(i, ...)
exclude_list[exclude_list_size + 1] = fragment
exclude_list_size = exclude_list_size + 1
exclude_list[exclude_list_size + i] = fragment
end
return self
@@ -3620,16 +3654,24 @@ function evolved_query_builder:build()
local query = evolved.id()
local fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, 2, 0)
local component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, 2, 0)
if include_list then
evolved.insert(query, evolved.INCLUDES, __table_unpack(include_list))
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, include_list)
fragment_list[#fragment_list + 1] = evolved.INCLUDES
component_list[#component_list + 1] = include_list
end
if exclude_list then
evolved.insert(query, evolved.EXCLUDES, __table_unpack(exclude_list))
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, exclude_list)
fragment_list[#fragment_list + 1] = evolved.EXCLUDES
component_list[#component_list + 1] = exclude_list
end
evolved.multi_set(query, fragment_list, component_list)
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_list)
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_list)
return query
end