mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-13 03:29:08 +07:00
improve performance of the clone operations
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
|
||||
- We can return deferred status from modifying operations and spawn/clone methods.
|
||||
- We should have a way to not copy components on deferred spawn/clone.
|
||||
- We can cache default/duplicate per chunk to speed up entity creation with setup hooks.
|
||||
- We need spawn/clone fuzzy tests!
|
||||
|
||||
## Known Issues
|
||||
|
||||
|
||||
442
evolved.lua
442
evolved.lua
@@ -2055,34 +2055,40 @@ function __spawn_entity(chunk, entity, components)
|
||||
local fragment_default, fragment_duplicate =
|
||||
__evolved_get(component_fragment, __DEFAULT, __DUPLICATE)
|
||||
|
||||
local new_component = components[component_fragment]
|
||||
local ini_component = components[component_fragment]
|
||||
|
||||
if new_component == nil then
|
||||
new_component = fragment_default
|
||||
if ini_component == nil then
|
||||
ini_component = fragment_default
|
||||
end
|
||||
|
||||
if new_component ~= nil and fragment_duplicate then
|
||||
new_component = fragment_duplicate(new_component)
|
||||
end
|
||||
if ini_component ~= nil and fragment_duplicate then
|
||||
local new_component = fragment_duplicate(ini_component)
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
component_storage[place] = new_component
|
||||
else
|
||||
if ini_component == nil then
|
||||
ini_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = ini_component
|
||||
end
|
||||
end
|
||||
else
|
||||
for component_index = 1, chunk_component_count do
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local component_fragment = chunk_component_fragments[component_index]
|
||||
|
||||
local new_component = components[component_fragment]
|
||||
local ini_component = components[component_fragment]
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
if ini_component == nil then
|
||||
ini_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
component_storage[place] = ini_component
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2206,20 +2212,29 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components)
|
||||
local fragment_default, fragment_duplicate =
|
||||
__evolved_get(component_fragment, __DEFAULT, __DUPLICATE)
|
||||
|
||||
if fragment_duplicate then
|
||||
local ini_component = components[component_fragment]
|
||||
|
||||
if ini_component == nil then
|
||||
ini_component = fragment_default
|
||||
end
|
||||
|
||||
if ini_component ~= nil and fragment_duplicate then
|
||||
for place = b_place, e_place do
|
||||
local new_component = components[component_fragment]
|
||||
if new_component == nil then new_component = fragment_default end
|
||||
if new_component ~= nil then new_component = fragment_duplicate(new_component) end
|
||||
if new_component == nil then new_component = true end
|
||||
local new_component = fragment_duplicate(ini_component)
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
else
|
||||
local new_component = components[component_fragment]
|
||||
if new_component == nil then new_component = fragment_default end
|
||||
if new_component == nil then new_component = true end
|
||||
if ini_component == nil then
|
||||
ini_component = true
|
||||
end
|
||||
|
||||
for place = b_place, e_place do
|
||||
component_storage[place] = new_component
|
||||
component_storage[place] = ini_component
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2228,10 +2243,14 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components)
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local component_fragment = chunk_component_fragments[component_index]
|
||||
|
||||
local new_component = components[component_fragment]
|
||||
if new_component == nil then new_component = true end
|
||||
local ini_component = components[component_fragment]
|
||||
|
||||
if ini_component == nil then
|
||||
ini_component = true
|
||||
end
|
||||
|
||||
for place = b_place, e_place do
|
||||
component_storage[place] = new_component
|
||||
component_storage[place] = ini_component
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2312,8 +2331,12 @@ function __clone_entity(prefab, entity, components)
|
||||
prefab_chunk.__without_unique_fragments = __chunk_without_unique_fragments(prefab_chunk)
|
||||
end
|
||||
|
||||
if not prefab_chunk or not prefab_chunk.__without_unique_fragments then
|
||||
return __spawn_entity(nil, entity, components)
|
||||
end
|
||||
|
||||
local chunk = __chunk_with_components(
|
||||
prefab_chunk and prefab_chunk.__without_unique_fragments,
|
||||
prefab_chunk.__without_unique_fragments,
|
||||
components)
|
||||
|
||||
if not chunk then
|
||||
@@ -2324,9 +2347,6 @@ function __clone_entity(prefab, entity, components)
|
||||
local req_fragment_list
|
||||
local req_fragment_count = 0
|
||||
|
||||
local ini_chunk = chunk
|
||||
local ini_fragment_set = ini_chunk.__fragment_set
|
||||
|
||||
if chunk.__has_required_fragments then
|
||||
---@type table<evolved.fragment, integer>
|
||||
req_fragment_set = __acquire_table(__table_pool_tag.fragment_set)
|
||||
@@ -2334,7 +2354,7 @@ function __clone_entity(prefab, entity, components)
|
||||
---@type evolved.fragment[]
|
||||
req_fragment_list = __acquire_table(__table_pool_tag.fragment_list)
|
||||
|
||||
req_fragment_count = __chunk_required_fragments(ini_chunk,
|
||||
req_fragment_count = __chunk_required_fragments(chunk,
|
||||
req_fragment_set, req_fragment_list, req_fragment_count)
|
||||
|
||||
for req_fragment_index = 1, req_fragment_count do
|
||||
@@ -2346,8 +2366,13 @@ function __clone_entity(prefab, entity, components)
|
||||
local chunk_entity_list = chunk.__entity_list
|
||||
local chunk_entity_count = chunk.__entity_count
|
||||
|
||||
local chunk_component_count = chunk.__component_count
|
||||
local chunk_component_indices = chunk.__component_indices
|
||||
local chunk_component_storages = chunk.__component_storages
|
||||
local chunk_component_fragments = chunk.__component_fragments
|
||||
|
||||
local prefab_component_indices = prefab_chunk.__component_indices
|
||||
local prefab_component_storages = prefab_chunk.__component_storages
|
||||
|
||||
local place = chunk_entity_count + 1
|
||||
|
||||
@@ -2362,144 +2387,69 @@ function __clone_entity(prefab, entity, components)
|
||||
__entity_places[entity_primary] = place
|
||||
end
|
||||
|
||||
if prefab_chunk then
|
||||
local prefab_component_count = prefab_chunk.__component_count
|
||||
local prefab_component_storages = prefab_chunk.__component_storages
|
||||
local prefab_component_fragments = prefab_chunk.__component_fragments
|
||||
|
||||
if prefab_chunk.__has_setup_hooks then
|
||||
for prefab_component_index = 1, prefab_component_count do
|
||||
local fragment = prefab_component_fragments[prefab_component_index]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
|
||||
---@type evolved.duplicate?
|
||||
local fragment_duplicate =
|
||||
__evolved_get(fragment, __DUPLICATE)
|
||||
|
||||
local prefab_component_storage = prefab_component_storages[prefab_component_index]
|
||||
local prefab_component = prefab_component_storage[prefab_place]
|
||||
|
||||
local new_component = prefab_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
|
||||
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
end
|
||||
else
|
||||
for prefab_component_index = 1, prefab_component_count do
|
||||
local fragment = prefab_component_fragments[prefab_component_index]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
|
||||
local prefab_component_storage = prefab_component_storages[prefab_component_index]
|
||||
local prefab_component = prefab_component_storage[prefab_place]
|
||||
|
||||
local new_component = prefab_component
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if chunk.__has_setup_hooks then
|
||||
for fragment, component in __lua_next, components do
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
for component_index = 1, chunk_component_count do
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local component_fragment = chunk_component_fragments[component_index]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
---@type evolved.default?, evolved.duplicate?
|
||||
local fragment_default, fragment_duplicate =
|
||||
__evolved_get(component_fragment, __DEFAULT, __DUPLICATE)
|
||||
|
||||
---@type evolved.duplicate?
|
||||
local fragment_duplicate =
|
||||
__evolved_get(fragment, __DUPLICATE)
|
||||
local ini_component = components[component_fragment]
|
||||
|
||||
local new_component = component
|
||||
|
||||
if new_component ~= nil and fragment_duplicate then
|
||||
new_component = fragment_duplicate(new_component)
|
||||
if ini_component == nil then
|
||||
if chunk == prefab_chunk then
|
||||
ini_component = component_storage[prefab_place]
|
||||
else
|
||||
local prefab_component_index = prefab_component_indices[component_fragment]
|
||||
if prefab_component_index then
|
||||
local prefab_component_storage = prefab_component_storages[prefab_component_index]
|
||||
ini_component = prefab_component_storage[prefab_place]
|
||||
else
|
||||
ini_component = fragment_default
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ini_component ~= nil and fragment_duplicate then
|
||||
local new_component = fragment_duplicate(ini_component)
|
||||
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
end
|
||||
|
||||
for req_fragment_index = 1, req_fragment_count do
|
||||
local req_fragment = req_fragment_list[req_fragment_index]
|
||||
|
||||
if ini_fragment_set[req_fragment] then
|
||||
-- this fragment has already been initialized
|
||||
else
|
||||
local req_component_index = chunk_component_indices[req_fragment]
|
||||
|
||||
if req_component_index then
|
||||
local req_component_storage = chunk_component_storages[req_component_index]
|
||||
|
||||
---@type evolved.default?, evolved.duplicate?
|
||||
local req_fragment_default, req_fragment_duplicate =
|
||||
__evolved_get(req_fragment, __DEFAULT, __DUPLICATE)
|
||||
|
||||
local req_component = req_fragment_default
|
||||
|
||||
if req_component ~= nil and req_fragment_duplicate then
|
||||
req_component = req_fragment_duplicate(req_component)
|
||||
end
|
||||
|
||||
if req_component == nil then
|
||||
req_component = true
|
||||
end
|
||||
|
||||
req_component_storage[place] = req_component
|
||||
if ini_component == nil then
|
||||
ini_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = ini_component
|
||||
end
|
||||
end
|
||||
else
|
||||
for fragment, component in __lua_next, components do
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
for component_index = 1, chunk_component_count do
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local component_fragment = chunk_component_fragments[component_index]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local ini_component = components[component_fragment]
|
||||
|
||||
local new_component = component
|
||||
if new_component == nil then new_component = true end
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
end
|
||||
|
||||
for req_fragment_index = 1, req_fragment_count do
|
||||
local req_fragment = req_fragment_list[req_fragment_index]
|
||||
|
||||
if ini_fragment_set[req_fragment] then
|
||||
-- this fragment has already been initialized
|
||||
else
|
||||
local req_component_index = chunk_component_indices[req_fragment]
|
||||
|
||||
if req_component_index then
|
||||
local req_component_storage = chunk_component_storages[req_component_index]
|
||||
|
||||
local req_component = true
|
||||
req_component_storage[place] = req_component
|
||||
if ini_component == nil then
|
||||
if chunk == prefab_chunk then
|
||||
ini_component = component_storage[prefab_place]
|
||||
else
|
||||
local prefab_component_index = prefab_component_indices[component_fragment]
|
||||
if prefab_component_index then
|
||||
local prefab_component_storage = prefab_component_storages[prefab_component_index]
|
||||
ini_component = prefab_component_storage[prefab_place]
|
||||
else
|
||||
ini_component = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
component_storage[place] = ini_component
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2564,8 +2514,12 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
prefab_chunk.__without_unique_fragments = __chunk_without_unique_fragments(prefab_chunk)
|
||||
end
|
||||
|
||||
if not prefab_chunk or not prefab_chunk.__without_unique_fragments then
|
||||
return __multi_spawn_entity(nil, entity_list, entity_count, components)
|
||||
end
|
||||
|
||||
local chunk = __chunk_with_components(
|
||||
prefab_chunk and prefab_chunk.__without_unique_fragments,
|
||||
prefab_chunk.__without_unique_fragments,
|
||||
components)
|
||||
|
||||
if not chunk then
|
||||
@@ -2576,9 +2530,6 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
local req_fragment_list
|
||||
local req_fragment_count = 0
|
||||
|
||||
local ini_chunk = chunk
|
||||
local ini_fragment_set = ini_chunk.__fragment_set
|
||||
|
||||
if chunk.__has_required_fragments then
|
||||
---@type table<evolved.fragment, integer>
|
||||
req_fragment_set = __acquire_table(__table_pool_tag.fragment_set)
|
||||
@@ -2586,7 +2537,7 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
---@type evolved.fragment[]
|
||||
req_fragment_list = __acquire_table(__table_pool_tag.fragment_list)
|
||||
|
||||
req_fragment_count = __chunk_required_fragments(ini_chunk,
|
||||
req_fragment_count = __chunk_required_fragments(chunk,
|
||||
req_fragment_set, req_fragment_list, req_fragment_count)
|
||||
|
||||
for req_fragment_index = 1, req_fragment_count do
|
||||
@@ -2598,8 +2549,13 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
local chunk_entity_list = chunk.__entity_list
|
||||
local chunk_entity_count = chunk.__entity_count
|
||||
|
||||
local chunk_component_count = chunk.__component_count
|
||||
local chunk_component_indices = chunk.__component_indices
|
||||
local chunk_component_storages = chunk.__component_storages
|
||||
local chunk_component_fragments = chunk.__component_fragments
|
||||
|
||||
local prefab_component_indices = prefab_chunk.__component_indices
|
||||
local prefab_component_storages = prefab_chunk.__component_storages
|
||||
|
||||
local b_place = chunk_entity_count + 1
|
||||
local e_place = chunk_entity_count + entity_count
|
||||
@@ -2621,155 +2577,75 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
|
||||
end
|
||||
end
|
||||
|
||||
if prefab_chunk then
|
||||
local prefab_component_count = prefab_chunk.__component_count
|
||||
local prefab_component_storages = prefab_chunk.__component_storages
|
||||
local prefab_component_fragments = prefab_chunk.__component_fragments
|
||||
|
||||
if prefab_chunk.__has_setup_hooks then
|
||||
for prefab_component_index = 1, prefab_component_count do
|
||||
local fragment = prefab_component_fragments[prefab_component_index]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
|
||||
---@type evolved.duplicate?
|
||||
local fragment_duplicate =
|
||||
__evolved_get(fragment, __DUPLICATE)
|
||||
|
||||
local prefab_component_storage = prefab_component_storages[prefab_component_index]
|
||||
local prefab_component = prefab_component_storage[prefab_place]
|
||||
|
||||
if fragment_duplicate then
|
||||
for place = b_place, e_place do
|
||||
local new_component = prefab_component
|
||||
if new_component ~= nil then new_component = fragment_duplicate(new_component) end
|
||||
if new_component == nil then new_component = true end
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
else
|
||||
local new_component = prefab_component
|
||||
if new_component == nil then new_component = true end
|
||||
for place = b_place, e_place do
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for prefab_component_index = 1, prefab_component_count do
|
||||
local fragment = prefab_component_fragments[prefab_component_index]
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
|
||||
local prefab_component_storage = prefab_component_storages[prefab_component_index]
|
||||
local prefab_component = prefab_component_storage[prefab_place]
|
||||
|
||||
local new_component = prefab_component
|
||||
if new_component == nil then new_component = true end
|
||||
for place = b_place, e_place do
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if chunk.__has_setup_hooks then
|
||||
for fragment, component in __lua_next, components do
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
for component_index = 1, chunk_component_count do
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local component_fragment = chunk_component_fragments[component_index]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
---@type evolved.default?, evolved.duplicate?
|
||||
local fragment_default, fragment_duplicate =
|
||||
__evolved_get(component_fragment, __DEFAULT, __DUPLICATE)
|
||||
|
||||
---@type evolved.duplicate?
|
||||
local fragment_duplicate =
|
||||
__evolved_get(fragment, __DUPLICATE)
|
||||
local ini_component = components[component_fragment]
|
||||
|
||||
if fragment_duplicate then
|
||||
for place = b_place, e_place do
|
||||
local new_component = component
|
||||
if new_component ~= nil then new_component = fragment_duplicate(new_component) end
|
||||
if new_component == nil then new_component = true end
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
if ini_component == nil then
|
||||
if chunk == prefab_chunk then
|
||||
ini_component = component_storage[prefab_place]
|
||||
else
|
||||
local new_component = component
|
||||
if new_component == nil then new_component = true end
|
||||
for place = b_place, e_place do
|
||||
component_storage[place] = new_component
|
||||
local prefab_component_index = prefab_component_indices[component_fragment]
|
||||
if prefab_component_index then
|
||||
local prefab_component_storage = prefab_component_storages[prefab_component_index]
|
||||
ini_component = prefab_component_storage[prefab_place]
|
||||
else
|
||||
ini_component = fragment_default
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for req_fragment_index = 1, req_fragment_count do
|
||||
local req_fragment = req_fragment_list[req_fragment_index]
|
||||
if ini_component ~= nil and fragment_duplicate then
|
||||
for place = b_place, e_place do
|
||||
local new_component = fragment_duplicate(ini_component)
|
||||
|
||||
if ini_fragment_set[req_fragment] then
|
||||
-- this fragment has already been initialized
|
||||
else
|
||||
local req_component_index = chunk_component_indices[req_fragment]
|
||||
|
||||
if req_component_index then
|
||||
local req_component_storage = chunk_component_storages[req_component_index]
|
||||
|
||||
---@type evolved.default?, evolved.duplicate?
|
||||
local req_fragment_default, req_fragment_duplicate =
|
||||
__evolved_get(req_fragment, __DEFAULT, __DUPLICATE)
|
||||
|
||||
if req_fragment_duplicate then
|
||||
for place = b_place, e_place do
|
||||
local req_component = req_fragment_default
|
||||
if req_component ~= nil then req_component = req_fragment_duplicate(req_component) end
|
||||
if req_component == nil then req_component = true end
|
||||
req_component_storage[place] = req_component
|
||||
end
|
||||
else
|
||||
local req_component = req_fragment_default
|
||||
if req_component == nil then req_component = true end
|
||||
for place = b_place, e_place do
|
||||
req_component_storage[place] = req_component
|
||||
end
|
||||
if new_component == nil then
|
||||
new_component = true
|
||||
end
|
||||
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
else
|
||||
if ini_component == nil then
|
||||
ini_component = true
|
||||
end
|
||||
|
||||
for place = b_place, e_place do
|
||||
component_storage[place] = ini_component
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for fragment, component in __lua_next, components do
|
||||
local component_index = chunk_component_indices[fragment]
|
||||
for component_index = 1, chunk_component_count do
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local component_fragment = chunk_component_fragments[component_index]
|
||||
|
||||
if component_index then
|
||||
local component_storage = chunk_component_storages[component_index]
|
||||
local ini_component = components[component_fragment]
|
||||
|
||||
local new_component = component
|
||||
if new_component == nil then new_component = true end
|
||||
for place = b_place, e_place do
|
||||
component_storage[place] = new_component
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for req_fragment_index = 1, req_fragment_count do
|
||||
local req_fragment = req_fragment_list[req_fragment_index]
|
||||
|
||||
if ini_fragment_set[req_fragment] then
|
||||
-- this fragment has already been initialized
|
||||
else
|
||||
local req_component_index = chunk_component_indices[req_fragment]
|
||||
|
||||
if req_component_index then
|
||||
local req_component_storage = chunk_component_storages[req_component_index]
|
||||
|
||||
local req_component = true
|
||||
for place = b_place, e_place do
|
||||
req_component_storage[place] = req_component
|
||||
if ini_component == nil then
|
||||
if chunk == prefab_chunk then
|
||||
ini_component = component_storage[prefab_place]
|
||||
else
|
||||
local prefab_component_index = prefab_component_indices[component_fragment]
|
||||
if prefab_component_index then
|
||||
local prefab_component_storage = prefab_component_storages[prefab_component_index]
|
||||
ini_component = prefab_component_storage[prefab_place]
|
||||
else
|
||||
ini_component = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for place = b_place, e_place do
|
||||
component_storage[place] = ini_component
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user