mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-13 03:29:08 +07:00
improve performance of builders that are used for spawning multiple times
This commit is contained in:
@@ -1304,6 +1304,7 @@ builder_mt:destruction_policy :: id -> builder
|
||||
- Improved system processing debugging experience with stack traces on errors
|
||||
- [`SET/ASSIGN hooks`](#fragment-hooks) are not invoked for tags on override operations anymore
|
||||
- Improved performance of cloning prefabs with many [`Unique Fragments`](#unique-fragments)
|
||||
- Improved performance of builders that are used for spawning multiple times
|
||||
|
||||
### v1.2.0
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
## Backlog
|
||||
|
||||
- Improve the performance of builders that are used multiple times by caching hint chunks.
|
||||
- Queries can cache major chunks to avoid finding them every time.
|
||||
- observers and events
|
||||
- add INDEX fragment trait
|
||||
|
||||
@@ -99,10 +99,10 @@ print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 component', N),
|
||||
function()
|
||||
local builder = evo.builder()
|
||||
local builder = evo.builder():set(F1)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:set(F1):spawn()
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
@@ -110,10 +110,10 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 components', N),
|
||||
function()
|
||||
local builder = evo.builder()
|
||||
local builder = evo.builder():set(F1):set(F2):set(F3)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:set(F1):set(F2):set(F3):spawn()
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
@@ -121,10 +121,10 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 components', N),
|
||||
function()
|
||||
local builder = evo.builder()
|
||||
local builder = evo.builder():set(F1):set(F2):set(F3):set(F4):set(F5)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:set(F1):set(F2):set(F3):set(F4):set(F5):spawn()
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
@@ -134,10 +134,10 @@ print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 1 required component', N),
|
||||
function()
|
||||
local builder = evo.builder()
|
||||
local builder = evo.builder():set(R1)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:set(R1):spawn()
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
@@ -145,10 +145,10 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 3 required components', N),
|
||||
function()
|
||||
local builder = evo.builder()
|
||||
local builder = evo.builder():set(R3)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:set(R3):spawn()
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
@@ -156,14 +156,15 @@ basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entiti
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Builder Spawn | %d entities with 5 required components', N),
|
||||
function()
|
||||
local builder = evo.builder()
|
||||
local builder = evo.builder():set(R5)
|
||||
|
||||
for _ = 1, N do
|
||||
builder:set(R5):spawn()
|
||||
builder:spawn()
|
||||
end
|
||||
|
||||
evo.batch_destroy(Q1)
|
||||
end)
|
||||
|
||||
print '----------------------------------------'
|
||||
|
||||
basics.describe_bench(string.format('Spawn Benchmarks: Multi Spawn | %d entities with 1 component', N),
|
||||
|
||||
@@ -6418,3 +6418,34 @@ do
|
||||
assert(evo.has(entity, f2) and evo.get(entity, f2) == 22)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
do
|
||||
local f = evo.id()
|
||||
local c = evo.chunk(f)
|
||||
local b = evo.builder():set(f, 42)
|
||||
evo.collect_garbage()
|
||||
local e = b:spawn()
|
||||
assert(evo.locate(e) ~= c)
|
||||
assert(evo.locate(e) == evo.chunk(f))
|
||||
end
|
||||
|
||||
do
|
||||
local f = evo.id()
|
||||
local c = evo.chunk(f)
|
||||
local b = evo.builder():set(f, 42)
|
||||
evo.collect_garbage()
|
||||
local es = b:multi_spawn(5)
|
||||
for i = 1, 5 do
|
||||
assert(evo.locate(es[i]) ~= c)
|
||||
assert(evo.locate(es[i]) == evo.chunk(f))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local ff, ft = evo.id(2)
|
||||
local b = evo.builder():set(ff, false):set(ft, true)
|
||||
assert(b:has_all() and not b:has_any())
|
||||
assert(b:has(ff) and b:has(ft) and b:has_all(ff, ft) and b:has_any(ff, ft))
|
||||
end
|
||||
|
||||
345
evolved.lua
345
evolved.lua
@@ -180,6 +180,7 @@ local __chunk_mt = {}
|
||||
__chunk_mt.__index = __chunk_mt
|
||||
|
||||
---@class evolved.builder
|
||||
---@field package __chunk? evolved.chunk
|
||||
---@field package __components table<evolved.fragment, evolved.component>
|
||||
local __builder_mt = {}
|
||||
__builder_mt.__index = __builder_mt
|
||||
@@ -1877,14 +1878,17 @@ function __detach_all_entities(chunk)
|
||||
chunk.__entity_count = 0
|
||||
end
|
||||
|
||||
---@param chunk? evolved.chunk
|
||||
---@param entity evolved.entity
|
||||
---@param components table<evolved.fragment, evolved.component>
|
||||
function __spawn_entity(entity, components)
|
||||
function __spawn_entity(chunk, entity, components)
|
||||
if __defer_depth <= 0 then
|
||||
__error_fmt('spawn entity operations should be deferred')
|
||||
end
|
||||
|
||||
local chunk = __chunk_components(components)
|
||||
if not chunk or chunk.__unreachable_or_collected then
|
||||
chunk = __chunk_components(components)
|
||||
end
|
||||
|
||||
if not chunk then
|
||||
return
|
||||
@@ -2063,15 +2067,18 @@ function __spawn_entity(entity, components)
|
||||
end
|
||||
end
|
||||
|
||||
---@param chunk? evolved.chunk
|
||||
---@param entity_list evolved.entity[]
|
||||
---@param entity_count integer
|
||||
---@param components table<evolved.fragment, evolved.component>
|
||||
function __multi_spawn_entity(entity_list, entity_count, components)
|
||||
function __multi_spawn_entity(chunk, entity_list, entity_count, components)
|
||||
if __defer_depth <= 0 then
|
||||
__error_fmt('spawn entity operations should be deferred')
|
||||
end
|
||||
|
||||
local chunk = __chunk_components(components)
|
||||
if not chunk or chunk.__unreachable_or_collected then
|
||||
chunk = __chunk_components(components)
|
||||
end
|
||||
|
||||
if not chunk then
|
||||
return
|
||||
@@ -2283,10 +2290,10 @@ function __multi_spawn_entity(entity_list, entity_count, components)
|
||||
end
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param prefab evolved.entity
|
||||
---@param entity evolved.entity
|
||||
---@param components table<evolved.fragment, evolved.component>
|
||||
function __clone_entity(entity, prefab, components)
|
||||
function __clone_entity(prefab, entity, components)
|
||||
if __defer_depth <= 0 then
|
||||
__error_fmt('clone entity operations should be deferred')
|
||||
end
|
||||
@@ -2534,11 +2541,11 @@ function __clone_entity(entity, prefab, components)
|
||||
end
|
||||
end
|
||||
|
||||
---@param prefab evolved.entity
|
||||
---@param entity_list evolved.entity[]
|
||||
---@param entity_count integer
|
||||
---@param prefab evolved.entity
|
||||
---@param components table<evolved.fragment, evolved.component>
|
||||
function __multi_clone_entity(entity_list, entity_count, prefab, components)
|
||||
function __multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
if __defer_depth <= 0 then
|
||||
__error_fmt('clone entity operations should be deferred')
|
||||
end
|
||||
@@ -4184,9 +4191,10 @@ __defer_ops[__defer_op.batch_destroy] = function(bytes, index)
|
||||
return 1 + argument_count
|
||||
end
|
||||
|
||||
---@param chunk? evolved.chunk
|
||||
---@param entity evolved.entity
|
||||
---@param component_map table<evolved.fragment, evolved.component>
|
||||
function __defer_spawn_entity(entity, component_map)
|
||||
function __defer_spawn_entity(chunk, entity, component_map)
|
||||
---@type table<evolved.fragment, evolved.component>
|
||||
local component_map_dup = __acquire_table(__table_pool_tag.component_map)
|
||||
|
||||
@@ -4198,30 +4206,33 @@ function __defer_spawn_entity(entity, component_map)
|
||||
local bytecode = __defer_bytecode
|
||||
|
||||
bytecode[length + 1] = __defer_op.spawn_entity
|
||||
bytecode[length + 2] = entity
|
||||
bytecode[length + 3] = component_map_dup
|
||||
bytecode[length + 2] = chunk
|
||||
bytecode[length + 3] = entity
|
||||
bytecode[length + 4] = component_map_dup
|
||||
|
||||
__defer_length = length + 3
|
||||
__defer_length = length + 4
|
||||
end
|
||||
|
||||
__defer_ops[__defer_op.spawn_entity] = function(bytes, index)
|
||||
local entity = bytes[index + 0]
|
||||
local component_map_dup = bytes[index + 1]
|
||||
local chunk = bytes[index + 0]
|
||||
local entity = bytes[index + 1]
|
||||
local component_map_dup = bytes[index + 2]
|
||||
|
||||
__evolved_defer()
|
||||
do
|
||||
__spawn_entity(entity, component_map_dup)
|
||||
__spawn_entity(chunk, entity, component_map_dup)
|
||||
__release_table(__table_pool_tag.component_map, component_map_dup)
|
||||
end
|
||||
__evolved_commit()
|
||||
|
||||
return 2
|
||||
return 3
|
||||
end
|
||||
|
||||
---@param chunk? evolved.chunk
|
||||
---@param entity_list evolved.entity[]
|
||||
---@param entity_count integer
|
||||
---@param component_map table<evolved.fragment, evolved.component>
|
||||
function __defer_multi_spawn_entity(entity_list, entity_count, component_map)
|
||||
function __defer_multi_spawn_entity(chunk, entity_list, entity_count, component_map)
|
||||
---@type evolved.entity[]
|
||||
local entity_list_dup = __acquire_table(__table_pool_tag.entity_list)
|
||||
|
||||
@@ -4240,33 +4251,35 @@ function __defer_multi_spawn_entity(entity_list, entity_count, component_map)
|
||||
local bytecode = __defer_bytecode
|
||||
|
||||
bytecode[length + 1] = __defer_op.multi_spawn_entity
|
||||
bytecode[length + 2] = entity_count
|
||||
bytecode[length + 3] = entity_list_dup
|
||||
bytecode[length + 4] = component_map_dup
|
||||
bytecode[length + 2] = chunk
|
||||
bytecode[length + 3] = entity_count
|
||||
bytecode[length + 4] = entity_list_dup
|
||||
bytecode[length + 5] = component_map_dup
|
||||
|
||||
__defer_length = length + 4
|
||||
__defer_length = length + 5
|
||||
end
|
||||
|
||||
__defer_ops[__defer_op.multi_spawn_entity] = function(bytes, index)
|
||||
local entity_count = bytes[index + 0]
|
||||
local entity_list_dup = bytes[index + 1]
|
||||
local component_map_dup = bytes[index + 2]
|
||||
local chunk = bytes[index + 0]
|
||||
local entity_count = bytes[index + 1]
|
||||
local entity_list_dup = bytes[index + 2]
|
||||
local component_map_dup = bytes[index + 3]
|
||||
|
||||
__evolved_defer()
|
||||
do
|
||||
__multi_spawn_entity(entity_list_dup, entity_count, component_map_dup)
|
||||
__multi_spawn_entity(chunk, entity_list_dup, entity_count, component_map_dup)
|
||||
__release_table(__table_pool_tag.entity_list, entity_list_dup)
|
||||
__release_table(__table_pool_tag.component_map, component_map_dup)
|
||||
end
|
||||
__evolved_commit()
|
||||
|
||||
return 3
|
||||
return 4
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param prefab evolved.entity
|
||||
---@param entity evolved.entity
|
||||
---@param components table<evolved.fragment, evolved.component>
|
||||
function __defer_clone_entity(entity, prefab, components)
|
||||
function __defer_clone_entity(prefab, entity, components)
|
||||
---@type table<evolved.fragment, evolved.component>
|
||||
local component_map_dup = __acquire_table(__table_pool_tag.component_map)
|
||||
|
||||
@@ -4292,7 +4305,7 @@ __defer_ops[__defer_op.clone_entity] = function(bytes, index)
|
||||
|
||||
__evolved_defer()
|
||||
do
|
||||
__clone_entity(entity, prefab, component_map_dup)
|
||||
__clone_entity(prefab, entity, component_map_dup)
|
||||
__release_table(__table_pool_tag.component_map, component_map_dup)
|
||||
end
|
||||
__evolved_commit()
|
||||
@@ -4300,11 +4313,11 @@ __defer_ops[__defer_op.clone_entity] = function(bytes, index)
|
||||
return 3
|
||||
end
|
||||
|
||||
---@param prefab evolved.entity
|
||||
---@param entity_list evolved.entity[]
|
||||
---@param entity_count integer
|
||||
---@param prefab evolved.entity
|
||||
---@param components table<evolved.fragment, evolved.component>
|
||||
function __defer_multi_clone_entity(entity_list, entity_count, prefab, components)
|
||||
function __defer_multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
---@type evolved.entity[]
|
||||
local entity_list_dup = __acquire_table(__table_pool_tag.entity_list)
|
||||
|
||||
@@ -4339,7 +4352,7 @@ __defer_ops[__defer_op.multi_clone_entity] = function(bytes, index)
|
||||
|
||||
__evolved_defer()
|
||||
do
|
||||
__multi_clone_entity(entity_list_dup, entity_count, prefab, component_map_dup)
|
||||
__multi_clone_entity(prefab, entity_list_dup, entity_count, component_map_dup)
|
||||
__release_table(__table_pool_tag.entity_list, entity_list_dup)
|
||||
__release_table(__table_pool_tag.component_map, component_map_dup)
|
||||
end
|
||||
@@ -4754,11 +4767,11 @@ function __evolved_spawn(components)
|
||||
local entity = __acquire_id()
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_spawn_entity(entity, components)
|
||||
__defer_spawn_entity(nil, entity, components)
|
||||
else
|
||||
__evolved_defer()
|
||||
do
|
||||
__spawn_entity(entity, components)
|
||||
__spawn_entity(nil, entity, components)
|
||||
end
|
||||
__evolved_commit()
|
||||
end
|
||||
@@ -4796,11 +4809,11 @@ function __evolved_multi_spawn(entity_count, components)
|
||||
end
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_multi_spawn_entity(entity_list, entity_count, components)
|
||||
__defer_multi_spawn_entity(nil, entity_list, entity_count, components)
|
||||
else
|
||||
__evolved_defer()
|
||||
do
|
||||
__multi_spawn_entity(entity_list, entity_count, components)
|
||||
__multi_spawn_entity(nil, entity_list, entity_count, components)
|
||||
end
|
||||
__evolved_commit()
|
||||
end
|
||||
@@ -4833,11 +4846,11 @@ function __evolved_clone(prefab, components)
|
||||
local entity = __acquire_id()
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_clone_entity(entity, prefab, components)
|
||||
__defer_clone_entity(prefab, entity, components)
|
||||
else
|
||||
__evolved_defer()
|
||||
do
|
||||
__clone_entity(entity, prefab, components)
|
||||
__clone_entity(prefab, entity, components)
|
||||
end
|
||||
__evolved_commit()
|
||||
end
|
||||
@@ -4881,11 +4894,11 @@ function __evolved_multi_clone(entity_count, prefab, components)
|
||||
end
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_multi_clone_entity(entity_list, entity_count, prefab, components)
|
||||
__defer_multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
else
|
||||
__evolved_defer()
|
||||
do
|
||||
__multi_clone_entity(entity_list, entity_count, prefab, components)
|
||||
__multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
end
|
||||
__evolved_commit()
|
||||
end
|
||||
@@ -6256,33 +6269,159 @@ end
|
||||
|
||||
---@return evolved.entity entity
|
||||
function __builder_mt:spawn()
|
||||
return __evolved_spawn(self.__components)
|
||||
local chunk = self.__chunk
|
||||
local components = self.__components
|
||||
|
||||
if __debug_mode then
|
||||
for fragment in __lua_next, components do
|
||||
if not __evolved_alive(fragment) then
|
||||
__error_fmt('the fragment (%s) is not alive and cannot be used',
|
||||
__id_name(fragment))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local entity = __acquire_id()
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_spawn_entity(chunk, entity, components)
|
||||
else
|
||||
__evolved_defer()
|
||||
do
|
||||
__spawn_entity(chunk, entity, components)
|
||||
end
|
||||
__evolved_commit()
|
||||
end
|
||||
|
||||
return entity
|
||||
end
|
||||
|
||||
---@param entity_count integer
|
||||
---@return evolved.entity[] entity_list
|
||||
function __builder_mt:multi_spawn(entity_count)
|
||||
return __evolved_multi_spawn(entity_count, self.__components)
|
||||
entity_count = entity_count or 1
|
||||
|
||||
if entity_count <= 0 then
|
||||
return {}
|
||||
end
|
||||
|
||||
local chunk = self.__chunk
|
||||
local components = self.__components
|
||||
|
||||
if __debug_mode then
|
||||
for fragment in __lua_next, components do
|
||||
if not __evolved_alive(fragment) then
|
||||
__error_fmt('the fragment (%s) is not alive and cannot be used',
|
||||
__id_name(fragment))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local entity_list = __list_new(entity_count)
|
||||
|
||||
for entity_index = 1, entity_count do
|
||||
entity_list[entity_index] = __acquire_id()
|
||||
end
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_multi_spawn_entity(chunk, entity_list, entity_count, components)
|
||||
else
|
||||
__evolved_defer()
|
||||
do
|
||||
__multi_spawn_entity(chunk, entity_list, entity_count, components)
|
||||
end
|
||||
__evolved_commit()
|
||||
end
|
||||
|
||||
return entity_list
|
||||
end
|
||||
|
||||
---@param prefab evolved.entity
|
||||
---@return evolved.entity entity
|
||||
function __builder_mt:clone(prefab)
|
||||
return __evolved_clone(prefab, self.__components)
|
||||
local components = self.__components
|
||||
|
||||
if __debug_mode then
|
||||
if not __evolved_alive(prefab) then
|
||||
__error_fmt('the prefab (%s) is not alive and cannot be used',
|
||||
__id_name(prefab))
|
||||
end
|
||||
|
||||
for fragment in __lua_next, components do
|
||||
if not __evolved_alive(fragment) then
|
||||
__error_fmt('the fragment (%s) is not alive and cannot be used',
|
||||
__id_name(fragment))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local entity = __acquire_id()
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_clone_entity(prefab, entity, components)
|
||||
else
|
||||
__evolved_defer()
|
||||
do
|
||||
__clone_entity(prefab, entity, components)
|
||||
end
|
||||
__evolved_commit()
|
||||
end
|
||||
|
||||
return entity
|
||||
end
|
||||
|
||||
---@param entity_count integer
|
||||
---@param prefab evolved.entity
|
||||
---@return evolved.entity[] entity_list
|
||||
function __builder_mt:multi_clone(entity_count, prefab)
|
||||
return __evolved_multi_clone(entity_count, prefab, self.__components)
|
||||
entity_count = entity_count or 1
|
||||
|
||||
if entity_count <= 0 then
|
||||
return {}
|
||||
end
|
||||
|
||||
local components = self.__components
|
||||
|
||||
if __debug_mode then
|
||||
if not __evolved_alive(prefab) then
|
||||
__error_fmt('the prefab (%s) is not alive and cannot be used',
|
||||
__id_name(prefab))
|
||||
end
|
||||
|
||||
for fragment in __lua_next, components do
|
||||
if not __evolved_alive(fragment) then
|
||||
__error_fmt('the fragment (%s) is not alive and cannot be used',
|
||||
__id_name(fragment))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local entity_list = __list_new(entity_count)
|
||||
|
||||
for entity_index = 1, entity_count do
|
||||
entity_list[entity_index] = __acquire_id()
|
||||
end
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
else
|
||||
__evolved_defer()
|
||||
do
|
||||
__multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
end
|
||||
__evolved_commit()
|
||||
end
|
||||
|
||||
return entity_list
|
||||
end
|
||||
|
||||
---@param fragment evolved.fragment
|
||||
---@return boolean
|
||||
---@nodiscard
|
||||
function __builder_mt:has(fragment)
|
||||
if self.__components[fragment] then
|
||||
local chunk = self.__chunk
|
||||
|
||||
if chunk and __chunk_has_fragment(chunk, fragment) then
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -6293,78 +6432,26 @@ end
|
||||
---@return boolean
|
||||
---@nodiscard
|
||||
function __builder_mt:has_all(...)
|
||||
local fragment_count = __lua_select("#", ...)
|
||||
local chunk = self.__chunk
|
||||
|
||||
if fragment_count == 0 then
|
||||
if chunk and __chunk_has_all_fragments(chunk, ...) then
|
||||
return true
|
||||
end
|
||||
|
||||
local cs = self.__components
|
||||
|
||||
if fragment_count == 1 then
|
||||
local f1 = ...
|
||||
return cs[f1] ~= nil
|
||||
end
|
||||
|
||||
if fragment_count == 2 then
|
||||
local f1, f2 = ...
|
||||
return cs[f1] ~= nil and cs[f2] ~= nil
|
||||
end
|
||||
|
||||
if fragment_count == 3 then
|
||||
local f1, f2, f3 = ...
|
||||
return cs[f1] ~= nil and cs[f2] ~= nil and cs[f3] ~= nil
|
||||
end
|
||||
|
||||
if fragment_count == 4 then
|
||||
local f1, f2, f3, f4 = ...
|
||||
return cs[f1] ~= nil and cs[f2] ~= nil and cs[f3] ~= nil and cs[f4] ~= nil
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = ...
|
||||
return cs[f1] ~= nil and cs[f2] ~= nil and cs[f3] ~= nil and cs[f4] ~= nil
|
||||
and self:has_all(__lua_select(5, ...))
|
||||
end
|
||||
return __lua_select("#", ...) == 0
|
||||
end
|
||||
|
||||
---@param ... evolved.fragment fragments
|
||||
---@return boolean
|
||||
---@nodiscard
|
||||
function __builder_mt:has_any(...)
|
||||
local fragment_count = __lua_select("#", ...)
|
||||
local chunk = self.__chunk
|
||||
|
||||
if fragment_count == 0 then
|
||||
return false
|
||||
if chunk and __chunk_has_any_fragments(chunk, ...) then
|
||||
return true
|
||||
end
|
||||
|
||||
local cs = self.__components
|
||||
|
||||
if fragment_count == 1 then
|
||||
local f1 = ...
|
||||
return cs[f1] ~= nil
|
||||
end
|
||||
|
||||
if fragment_count == 2 then
|
||||
local f1, f2 = ...
|
||||
return cs[f1] ~= nil or cs[f2] ~= nil
|
||||
end
|
||||
|
||||
if fragment_count == 3 then
|
||||
local f1, f2, f3 = ...
|
||||
return cs[f1] ~= nil or cs[f2] ~= nil or cs[f3] ~= nil
|
||||
end
|
||||
|
||||
if fragment_count == 4 then
|
||||
local f1, f2, f3, f4 = ...
|
||||
return cs[f1] ~= nil or cs[f2] ~= nil or cs[f3] ~= nil or cs[f4] ~= nil
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = ...
|
||||
return cs[f1] ~= nil or cs[f2] ~= nil or cs[f3] ~= nil or cs[f4] ~= nil
|
||||
or self:has_any(__lua_select(5, ...))
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---@param ... evolved.fragment fragments
|
||||
@@ -6419,7 +6506,10 @@ function __builder_mt:set(fragment, component)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local new_chunk = __chunk_with_fragment(self.__chunk, fragment)
|
||||
local components = self.__components
|
||||
|
||||
if new_chunk.__has_setup_hooks then
|
||||
---@type evolved.default?, evolved.duplicate?
|
||||
local fragment_default, fragment_duplicate =
|
||||
__evolved_get(fragment, __DEFAULT, __DUPLICATE)
|
||||
@@ -6429,9 +6519,15 @@ function __builder_mt:set(fragment, component)
|
||||
if new_component ~= nil and fragment_duplicate then new_component = fragment_duplicate(new_component) end
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
self.__components[fragment] = new_component
|
||||
components[fragment] = new_component
|
||||
else
|
||||
local new_component = component
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
components[fragment] = new_component
|
||||
end
|
||||
|
||||
self.__chunk = new_chunk
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -6444,41 +6540,22 @@ function __builder_mt:remove(...)
|
||||
return self
|
||||
end
|
||||
|
||||
local cs = self.__components
|
||||
local new_chunk = self.__chunk
|
||||
local components = self.__components
|
||||
|
||||
if fragment_count == 1 then
|
||||
local f1 = ...
|
||||
cs[f1] = nil
|
||||
return self
|
||||
for fragment_index = 1, fragment_count do
|
||||
---@type evolved.fragment
|
||||
local fragment = __lua_select(fragment_index, ...)
|
||||
new_chunk, components[fragment] = __chunk_without_fragment(new_chunk, fragment), nil
|
||||
end
|
||||
|
||||
if fragment_count == 2 then
|
||||
local f1, f2 = ...
|
||||
cs[f1], cs[f2] = nil, nil
|
||||
return self
|
||||
end
|
||||
|
||||
if fragment_count == 3 then
|
||||
local f1, f2, f3 = ...
|
||||
cs[f1], cs[f2], cs[f3] = nil, nil, nil
|
||||
return self
|
||||
end
|
||||
|
||||
if fragment_count == 4 then
|
||||
local f1, f2, f3, f4 = ...
|
||||
cs[f1], cs[f2], cs[f3], cs[f4] = nil, nil, nil, nil
|
||||
return self
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = ...
|
||||
cs[f1], cs[f2], cs[f3], cs[f4] = nil, nil, nil, nil
|
||||
return self:remove(__lua_select(5, ...))
|
||||
end
|
||||
self.__chunk = new_chunk
|
||||
return self
|
||||
end
|
||||
|
||||
---@return evolved.builder builder
|
||||
function __builder_mt:clear()
|
||||
self.__chunk = nil
|
||||
__lua_table_clear(self.__components)
|
||||
return self
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user