mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-13 03:29:08 +07:00
improve perf of cloning prefabs with many unique fragments
This commit is contained in:
@@ -1303,6 +1303,7 @@ builder_mt:destruction_policy :: id -> builder
|
||||
- The internal garbage collector now collects more garbage
|
||||
- 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)
|
||||
|
||||
### v1.2.0
|
||||
|
||||
|
||||
@@ -14,4 +14,3 @@
|
||||
|
||||
- We can return deferred status from modifying operations and spawn/clone methods.
|
||||
- Should we make one builder:build method instead of :spawn and :clone?
|
||||
- Should we cache the result of without_unique_fragments to clone faster?
|
||||
|
||||
@@ -6373,3 +6373,48 @@ do
|
||||
assert(evo.get(e, f) ~= v2_default)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2 = evo.id(2)
|
||||
|
||||
local prefab = evo.builder():prefab():set(f1, 11):set(f2, 22):spawn()
|
||||
|
||||
do
|
||||
local entity = evo.clone(prefab)
|
||||
assert(evo.has(entity, f1) and evo.get(entity, f1) == 11)
|
||||
assert(evo.has(entity, f2) and evo.get(entity, f2) == 22)
|
||||
end
|
||||
|
||||
evo.set(f2, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local entity = evo.clone(prefab)
|
||||
assert(evo.has(entity, f1) and evo.get(entity, f1) == 11)
|
||||
assert(not evo.has(entity, f2) and evo.get(entity, f2) == nil)
|
||||
end
|
||||
|
||||
evo.remove(f2, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local entity = evo.clone(prefab)
|
||||
assert(evo.has(entity, f1) and evo.get(entity, f1) == 11)
|
||||
assert(evo.has(entity, f2) and evo.get(entity, f2) == 22)
|
||||
end
|
||||
|
||||
evo.set(f1, evo.UNIQUE)
|
||||
evo.set(f2, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local entity = evo.clone(prefab)
|
||||
assert(evo.empty(entity))
|
||||
end
|
||||
|
||||
evo.remove(f1, evo.UNIQUE)
|
||||
evo.remove(f2, evo.UNIQUE)
|
||||
|
||||
do
|
||||
local entity = evo.clone(prefab)
|
||||
assert(evo.has(entity, f1) and evo.get(entity, f1) == 11)
|
||||
assert(evo.has(entity, f2) and evo.get(entity, f2) == 22)
|
||||
end
|
||||
end
|
||||
|
||||
26
evolved.lua
26
evolved.lua
@@ -160,6 +160,7 @@ local __group_subsystems = {} ---@type table<evolved.system, evolved.assoc_list<
|
||||
---@field package __component_fragments evolved.fragment[]
|
||||
---@field package __with_fragment_edges table<evolved.fragment, evolved.chunk>
|
||||
---@field package __without_fragment_edges table<evolved.fragment, evolved.chunk>
|
||||
---@field package __without_unique_fragments? evolved.chunk
|
||||
---@field package __unreachable_or_collected boolean
|
||||
---@field package __has_setup_hooks boolean
|
||||
---@field package __has_assign_hooks boolean
|
||||
@@ -998,6 +999,7 @@ function __new_chunk(chunk_parent, chunk_fragment)
|
||||
__component_fragments = {},
|
||||
__with_fragment_edges = {},
|
||||
__without_fragment_edges = {},
|
||||
__without_unique_fragments = nil,
|
||||
__unreachable_or_collected = false,
|
||||
__has_setup_hooks = false,
|
||||
__has_assign_hooks = false,
|
||||
@@ -1116,6 +1118,12 @@ function __update_chunk_caches(chunk)
|
||||
chunk.__has_internal_fragments = has_internal_fragments
|
||||
|
||||
chunk.__has_required_fragments = has_required_fragments
|
||||
|
||||
if has_unique_fragments then
|
||||
chunk.__without_unique_fragments = nil
|
||||
else
|
||||
chunk.__without_unique_fragments = chunk
|
||||
end
|
||||
end
|
||||
|
||||
---@param chunk evolved.chunk
|
||||
@@ -2240,13 +2248,14 @@ function __clone_entity(entity, prefab, components)
|
||||
__error_fmt('clone entity operations should be deferred')
|
||||
end
|
||||
|
||||
local prefab_primary = prefab % 2 ^ 20
|
||||
local prefab_chunk, prefab_place = __evolved_locate(prefab)
|
||||
|
||||
local prefab_chunk = __entity_chunks[prefab_primary]
|
||||
local prefab_place = __entity_places[prefab_primary]
|
||||
if prefab_chunk and prefab_chunk.__has_unique_fragments and not prefab_chunk.__without_unique_fragments then
|
||||
prefab_chunk.__without_unique_fragments = __chunk_without_unique_fragments(prefab_chunk)
|
||||
end
|
||||
|
||||
local chunk = __chunk_with_components(
|
||||
__chunk_without_unique_fragments(prefab_chunk),
|
||||
prefab_chunk and prefab_chunk.__without_unique_fragments,
|
||||
components)
|
||||
|
||||
if not chunk then
|
||||
@@ -2491,13 +2500,14 @@ function __multi_clone_entity(entity_list, entity_count, prefab, components)
|
||||
__error_fmt('clone entity operations should be deferred')
|
||||
end
|
||||
|
||||
local prefab_primary = prefab % 2 ^ 20
|
||||
local prefab_chunk, prefab_place = __evolved_locate(prefab)
|
||||
|
||||
local prefab_chunk = __entity_chunks[prefab_primary]
|
||||
local prefab_place = __entity_places[prefab_primary]
|
||||
if prefab_chunk and prefab_chunk.__has_unique_fragments and not prefab_chunk.__without_unique_fragments then
|
||||
prefab_chunk.__without_unique_fragments = __chunk_without_unique_fragments(prefab_chunk)
|
||||
end
|
||||
|
||||
local chunk = __chunk_with_components(
|
||||
__chunk_without_unique_fragments(prefab_chunk),
|
||||
prefab_chunk and prefab_chunk.__without_unique_fragments,
|
||||
components)
|
||||
|
||||
if not chunk then
|
||||
|
||||
Reference in New Issue
Block a user