first realloc/compmove imp

This commit is contained in:
BlackMATov
2026-01-13 01:14:50 +07:00
parent c9bfb26748
commit e75ddef396
4 changed files with 516 additions and 96 deletions

View File

@@ -9,6 +9,7 @@
## Thoughts
- We can create component storages on-demand rather than in advance
- We should have a way to not copy components on deferred spawn/clone
## Known Issues

View File

@@ -8,6 +8,7 @@ require 'develop.testing.main_tests'
require 'develop.testing.multi_spawn_tests'
require 'develop.testing.name_tests'
require 'develop.testing.process_with_tests'
require 'develop.testing.realloc_tests'
require 'develop.testing.requires_fragment_tests'
require 'develop.testing.spawn_tests'
require 'develop.testing.system_as_query_tests'
@@ -35,3 +36,5 @@ print '----------------------------------------'
basics.describe_fuzz 'develop.fuzzing.requires_fuzz'
print '----------------------------------------'
basics.describe_fuzz 'develop.fuzzing.unique_fuzz'
print 'All tests passed.'

View File

@@ -0,0 +1,301 @@
local evo = require 'evolved'
---@type ffilib?
local ffi = (function()
local ffi_loader = package and package.preload and package.preload['ffi']
local ffi = ffi_loader and ffi_loader()
return ffi
end)()
if not ffi then
return
end
local FLOAT_TYPEOF = ffi.typeof('float')
local FLOAT_SIZEOF = ffi.sizeof(FLOAT_TYPEOF)
local FLOAT_STORAGE_TYPEOF = ffi.typeof('$[?]', FLOAT_TYPEOF)
local DOUBLE_TYPEOF = ffi.typeof('double')
local DOUBLE_SIZEOF = ffi.sizeof(DOUBLE_TYPEOF)
local DOUBLE_STORAGE_TYPEOF = ffi.typeof('$[?]', DOUBLE_TYPEOF)
---@type evolved.realloc
local function float_realloc(old_storage, old_size, new_size)
local new_storage = ffi.new(FLOAT_STORAGE_TYPEOF, new_size + 1)
if old_storage then
ffi.copy(new_storage + 1, old_storage + 1, math.min(old_size, new_size) * FLOAT_SIZEOF)
end
return new_storage
end
---@type evolved.realloc
local function double_realloc(old_storage, old_size, new_size)
local new_storage = ffi.new(DOUBLE_STORAGE_TYPEOF, new_size + 1)
if old_storage then
ffi.copy(new_storage + 1, old_storage + 1, math.min(old_size, new_size) * DOUBLE_SIZEOF)
end
return new_storage
end
---@type evolved.compmove
local function double_compmove(src, f, e, t, dst)
ffi.copy(dst + t, src + f, (e - f + 1) * DOUBLE_SIZEOF)
end
do
local f1 = evo.builder():realloc(double_realloc):build()
local e1 = evo.builder():set(f1, 21):build()
assert(evo.has(e1, f1) and evo.get(e1, f1) == 21)
local e2 = evo.builder():set(f1, 42):build()
assert(evo.has(e1, f1) and evo.get(e1, f1) == 21)
assert(evo.has(e2, f1) and evo.get(e2, f1) == 42)
local e3 = evo.builder():set(f1, 84):build()
assert(evo.has(e1, f1) and evo.get(e1, f1) == 21)
assert(evo.has(e2, f1) and evo.get(e2, f1) == 42)
assert(evo.has(e3, f1) and evo.get(e3, f1) == 84)
evo.destroy(e1)
assert(not evo.has(e1, f1))
assert(evo.has(e2, f1) and evo.get(e2, f1) == 42)
assert(evo.has(e3, f1) and evo.get(e3, f1) == 84)
evo.destroy(e3)
assert(not evo.has(e1, f1))
assert(evo.has(e2, f1) and evo.get(e2, f1) == 42)
assert(not evo.has(e3, f1))
evo.destroy(e2)
assert(not evo.has(e1, f1))
assert(not evo.has(e2, f1))
assert(not evo.has(e3, f1))
end
do
local f1 = evo.builder():realloc(double_realloc):build()
local q1 = evo.builder():include(f1):build()
do
local es, ec = {}, 10
for i = 1, ec do es[i] = evo.spawn({ [f1] = i }) end
for i = 1, ec do assert(evo.has(es[i], f1) and evo.get(es[i], f1) == i) end
end
do
local p = evo.builder():set(f1, 42):build()
local es, ec = {}, 10
for i = 1, ec do es[i] = evo.clone(p) end
for i = 1, ec do assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42) end
end
do
local es1, ec1 = evo.multi_spawn(10, { [f1] = 42 })
for i = 1, ec1 do assert(evo.has(es1[i], f1) and evo.get(es1[i], f1) == 42) end
local es2, ec2 = evo.multi_spawn(20, { [f1] = 84 })
for i = 1, ec1 do assert(evo.has(es1[i], f1) and evo.get(es1[i], f1) == 42) end
for i = 1, ec2 do assert(evo.has(es2[i], f1) and evo.get(es2[i], f1) == 84) end
end
do
local p = evo.builder():set(f1, 21):build()
local es1, ec1 = evo.multi_clone(10, p)
for i = 1, ec1 do assert(evo.has(es1[i], f1) and evo.get(es1[i], f1) == 21) end
local es2, ec2 = evo.multi_clone(20, p)
for i = 1, ec1 do assert(evo.has(es1[i], f1) and evo.get(es1[i], f1) == 21) end
for i = 1, ec2 do assert(evo.has(es2[i], f1) and evo.get(es2[i], f1) == 21) end
end
evo.batch_destroy(q1)
end
do
local f1 = evo.builder():realloc(double_realloc):build()
local f2 = evo.builder():realloc(double_realloc):build()
local q1 = evo.builder():include(f1):build()
local q2 = evo.builder():include(f2):build()
do
local e = evo.builder():set(f1, 21):set(f2, 42):build()
assert(evo.has(e, f1) and evo.get(e, f1) == 21)
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
evo.remove(e, f1)
assert(not evo.has(e, f1))
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
end
do
local e = evo.builder():set(f1, 21):set(f2, 42):build()
assert(evo.has(e, f1) and evo.get(e, f1) == 21)
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
evo.clear(e)
assert(not evo.has(e, f1))
assert(not evo.has(e, f2))
end
do
local es, ec = evo.multi_spawn(10, { [f1] = 21, [f2] = 42 })
for i = 1, ec do
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 21)
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 42)
end
evo.batch_remove(q1, f1)
local e12 = evo.builder():set(f1, 1):set(f2, 2):build()
assert(evo.has(e12, f1) and evo.get(e12, f1) == 1)
assert(evo.has(e12, f2) and evo.get(e12, f2) == 2)
for i = 1, ec do
assert(not evo.has(es[i], f1))
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 42)
end
evo.batch_set(q2, f1, 84)
assert(evo.has(e12, f1) and evo.get(e12, f1) == 84)
assert(evo.has(e12, f2) and evo.get(e12, f2) == 2)
for i = 1, ec do
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 84)
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 42)
end
evo.batch_set(q2, f1, 21)
assert(evo.has(e12, f1) and evo.get(e12, f1) == 21)
assert(evo.has(e12, f2) and evo.get(e12, f2) == 2)
for i = 1, ec do
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 21)
assert(evo.has(es[i], f2) and evo.get(es[i], f2) == 42)
end
end
end
do
local f1 = evo.builder():realloc(double_realloc):compmove(double_compmove):build()
local f2 = evo.builder():realloc(double_realloc):compmove(double_compmove):build()
local q1 = evo.builder():include(f1):build()
local q2 = evo.builder():include(f2):build()
do
local es1, ec1 = evo.multi_spawn(10, { [f1] = 1, [f2] = 2 })
for i = 1, ec1 do
assert(evo.has(es1[i], f1) and evo.get(es1[i], f1) == 1)
assert(evo.has(es1[i], f2) and evo.get(es1[i], f2) == 2)
end
local es2, ec2 = evo.multi_spawn(20, { [f1] = 3, [f2] = 4 })
for i = 1, ec1 do
assert(evo.has(es1[i], f1) and evo.get(es1[i], f1) == 1)
assert(evo.has(es1[i], f2) and evo.get(es1[i], f2) == 2)
end
for i = 1, ec2 do
assert(evo.has(es2[i], f1) and evo.get(es2[i], f1) == 3)
assert(evo.has(es2[i], f2) and evo.get(es2[i], f2) == 4)
end
local e2 = evo.builder():set(f2, 42):build()
assert(evo.has(e2, f2) and evo.get(e2, f2) == 42)
evo.batch_remove(q1, f1)
assert(evo.has(e2, f2) and evo.get(e2, f2) == 42)
for i = 1, ec1 do
assert(not evo.has(es1[i], f1))
assert(evo.has(es1[i], f2) and evo.get(es1[i], f2) == 2)
end
for i = 1, ec2 do
assert(not evo.has(es2[i], f1))
assert(evo.has(es2[i], f2) and evo.get(es2[i], f2) == 4)
end
local e12 = evo.builder():set(f1, 21):set(f2, 42):build()
assert(evo.has(e2, f2) and evo.get(e2, f2) == 42)
assert(evo.has(e12, f1) and evo.get(e12, f1) == 21)
assert(evo.has(e12, f2) and evo.get(e12, f2) == 42)
evo.batch_set(q2, f1, 84)
assert(evo.has(e2, f2) and evo.get(e2, f2) == 42)
assert(evo.has(e12, f1) and evo.get(e12, f1) == 84)
assert(evo.has(e12, f2) and evo.get(e12, f2) == 42)
for i = 1, ec1 do
assert(evo.has(es1[i], f1) and evo.get(es1[i], f1) == 84)
assert(evo.has(es1[i], f2) and evo.get(es1[i], f2) == 2)
end
for i = 1, ec2 do
assert(evo.has(es2[i], f1) and evo.get(es2[i], f1) == 84)
assert(evo.has(es2[i], f2) and evo.get(es2[i], f2) == 4)
end
end
end
do
local f1 = evo.builder():default(42):build()
local es, ec = evo.multi_spawn(10, { [f1] = 21 })
for i = 1, ec do assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 21) end
evo.set(f1, evo.TAG)
for i = 1, ec do assert(evo.has(es[i], f1) and evo.get(es[i], f1) == nil) end
evo.remove(f1, evo.TAG)
for i = 1, ec do assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42) end
end
do
local f1 = evo.builder():realloc(float_realloc):build()
local e1 = evo.builder():set(f1, 3):build()
assert(evo.has(e1, f1) and evo.get(e1, f1) == 3)
evo.set(f1, evo.REALLOC, double_realloc)
assert(evo.has(e1, f1) and evo.get(e1, f1) == 3)
evo.remove(f1, evo.REALLOC)
assert(evo.has(e1, f1) and evo.get(e1, f1) == 3)
evo.set(f1, evo.REALLOC, double_realloc)
assert(evo.has(e1, f1) and evo.get(e1, f1) == 3)
end
do
local f1 = evo.builder():realloc(double_realloc):build()
local es, ec = evo.multi_spawn(20, { [f1] = 42 })
for i = 1, ec / 2 do
evo.destroy(es[ec - i + 1])
end
evo.collect_garbage()
for i = 1, ec / 2 do
assert(evo.has(es[i], f1) and evo.get(es[i], f1) == 42)
end
end

View File

@@ -40,8 +40,8 @@ local evolved = {
---@alias evolved.default evolved.component
---@alias evolved.duplicate fun(component: evolved.component): evolved.component
---@alias evolved.realloc fun(storage?: evolved.storage, old_size: integer, new_size: integer): evolved.storage
---@alias evolved.compmove fun(destination: evolved.storage, source: evolved.storage, count: integer)
---@alias evolved.realloc fun(src?: evolved.storage, old_size: integer, new_size: integer): evolved.storage
---@alias evolved.compmove fun(src: evolved.storage, f: integer, e: integer, t: integer, dst: evolved.storage)
---@alias evolved.execute fun(
--- chunk: evolved.chunk,
@@ -192,6 +192,8 @@ local __structural_changes = 0 ---@type integer
---@field package __has_internal_major boolean
---@field package __has_internal_minors boolean
---@field package __has_internal_fragments boolean
---@field package __has_storage_reallocs boolean
---@field package __has_storage_compmoves boolean
---@field package __has_required_fragments boolean
local __chunk_mt = {}
__chunk_mt.__index = __chunk_mt
@@ -1263,6 +1265,8 @@ function __new_chunk(chunk_parent, chunk_fragment)
__has_internal_major = false,
__has_internal_minors = false,
__has_internal_fragments = false,
__has_storage_reallocs = false,
__has_storage_compmoves = false,
__has_required_fragments = false,
}, __chunk_mt)
@@ -1351,6 +1355,12 @@ function __update_chunk_caches(chunk)
local has_internal_minors = chunk_parent ~= nil and chunk_parent.__has_internal_fragments
local has_internal_fragments = has_internal_major or has_internal_minors
local has_storage_reallocs = chunk_parent ~= nil and chunk_parent.__has_storage_reallocs
or __evolved_has(chunk_fragment, __REALLOC)
local has_storage_compmoves = chunk_parent ~= nil and chunk_parent.__has_storage_compmoves
or __evolved_has(chunk_fragment, __COMPMOVE)
local has_required_fragments = false
for chunk_fragment_index = 1, chunk_fragment_count do
@@ -1391,6 +1401,9 @@ function __update_chunk_caches(chunk)
chunk.__has_internal_minors = has_internal_minors
chunk.__has_internal_fragments = has_internal_fragments
chunk.__has_storage_reallocs = has_storage_reallocs
chunk.__has_storage_compmoves = has_storage_compmoves
chunk.__has_required_fragments = has_required_fragments
if has_required_fragments then
@@ -1445,7 +1458,9 @@ function __update_chunk_storages(chunk)
for fragment_index = 1, fragment_count do
local fragment = fragment_list[fragment_index]
local component_index = component_indices[fragment]
local component_realloc = component_index and component_reallocs[component_index]
---@type evolved.default?, evolved.duplicate?, evolved.realloc?, evolved.compmove?
local fragment_default, fragment_duplicate, fragment_realloc, fragment_compmove =
@@ -1485,7 +1500,9 @@ function __update_chunk_storages(chunk)
component_count = component_count + 1
chunk.__component_count = component_count
local component_storage = __lua_table_new(entity_count)
local component_storage = fragment_realloc
and fragment_realloc(nil, 0, entity_capacity)
or __lua_table_new(entity_capacity)
local component_storage_index = component_count
component_indices[fragment] = component_storage_index
@@ -1511,6 +1528,33 @@ function __update_chunk_storages(chunk)
end
end
elseif component_index then
if component_realloc ~= fragment_realloc then
local old_component_storage = component_storages[component_index]
local new_component_storage = fragment_realloc
and fragment_realloc(nil, 0, entity_capacity)
or __lua_table_new(entity_capacity)
if fragment_duplicate then
for place = 1, entity_count do
local new_component = old_component_storage[place]
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
new_component_storage[place] = new_component
end
else
for place = 1, entity_count do
local new_component = old_component_storage[place]
if new_component == nil then new_component = fragment_default end
if new_component == nil then new_component = true end
new_component_storage[place] = new_component
end
end
component_storages[component_index] = new_component_storage
end
component_defaults[component_index] = fragment_default
component_duplicates[component_index] = fragment_duplicate
component_reallocs[component_index] = fragment_realloc
@@ -2186,27 +2230,16 @@ function __detach_entity(chunk, place)
local component_count = chunk.__component_count
local component_storages = chunk.__component_storages
if place == entity_count then
entity_list[entity_count] = nil
for component_index = 1, component_count do
local component_storage = component_storages[component_index]
component_storage[entity_count] = nil
end
else
if place ~= entity_count then
local last_entity = entity_list[entity_count]
local last_entity_primary = last_entity % 2 ^ 20
entity_list[place] = last_entity
local last_entity_primary = last_entity % 2 ^ 20
__entity_places[last_entity_primary] = place
entity_list[place] = last_entity
entity_list[entity_count] = nil
for component_index = 1, component_count do
local component_storage = component_storages[component_index]
local last_entity_component = component_storage[entity_count]
component_storage[place] = last_entity_component
component_storage[entity_count] = nil
component_storage[place] = component_storage[entity_count]
end
end
@@ -2215,18 +2248,6 @@ end
---@param chunk evolved.chunk
function __detach_all_entities(chunk)
local entity_list = chunk.__entity_list
local component_count = chunk.__component_count
local component_storages = chunk.__component_storages
__lua_table_clear(entity_list)
for component_index = 1, component_count do
local component_storage = component_storages[component_index]
__lua_table_clear(component_storage)
end
chunk.__entity_count = 0
end
@@ -2257,25 +2278,21 @@ function __spawn_entity(chunk, entity, components)
return
end
local chunk_entity_list = chunk.__entity_list
local chunk_entity_count = chunk.__entity_count
local chunk_entity_capacity = chunk.__entity_capacity
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 chunk_component_defaults = chunk.__component_defaults
local chunk_component_duplicates = chunk.__component_duplicates
local chunk_component_reallocs = chunk.__component_reallocs
local chunk_component_compmoves = chunk.__component_compmoves
local place = chunk_entity_count + 1
local place = chunk.__entity_count + 1
if place > chunk_entity_capacity then
if place > chunk.__entity_capacity then
__expand_chunk(chunk, place)
end
local chunk_entity_list = chunk.__entity_list
do
chunk.__entity_count = place
__structural_changes = __structural_changes + 1
@@ -2383,26 +2400,22 @@ function __multi_spawn_entity(chunk, entity_list, entity_count, components)
return
end
local chunk_entity_list = chunk.__entity_list
local chunk_entity_count = chunk.__entity_count
local chunk_entity_capacity = chunk.__entity_capacity
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 chunk_component_defaults = chunk.__component_defaults
local chunk_component_duplicates = chunk.__component_duplicates
local chunk_component_reallocs = chunk.__component_reallocs
local chunk_component_compmoves = chunk.__component_compmoves
local b_place = chunk_entity_count + 1
local e_place = chunk_entity_count + entity_count
local b_place = chunk.__entity_count + 1
local e_place = b_place + entity_count - 1
if e_place > chunk_entity_capacity then
if e_place > chunk.__entity_capacity then
__expand_chunk(chunk, e_place)
end
local chunk_entity_list = chunk.__entity_list
do
chunk.__entity_count = e_place
__structural_changes = __structural_changes + 1
@@ -2541,28 +2554,24 @@ function __clone_entity(prefab, entity, components)
return
end
local chunk_entity_list = chunk.__entity_list
local chunk_entity_count = chunk.__entity_count
local chunk_entity_capacity = chunk.__entity_capacity
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 chunk_component_defaults = chunk.__component_defaults
local chunk_component_duplicates = chunk.__component_duplicates
local chunk_component_reallocs = chunk.__component_reallocs
local chunk_component_compmoves = chunk.__component_compmoves
local prefab_component_indices = prefab_chunk.__component_indices
local prefab_component_storages = prefab_chunk.__component_storages
local place = chunk_entity_count + 1
local place = chunk.__entity_count + 1
if place > chunk_entity_capacity then
if place > chunk.__entity_capacity then
__expand_chunk(chunk, place)
end
local chunk_entity_list = chunk.__entity_list
do
chunk.__entity_count = place
__structural_changes = __structural_changes + 1
@@ -2694,29 +2703,25 @@ function __multi_clone_entity(prefab, entity_list, entity_count, components)
return
end
local chunk_entity_list = chunk.__entity_list
local chunk_entity_count = chunk.__entity_count
local chunk_entity_capacity = chunk.__entity_capacity
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 chunk_component_defaults = chunk.__component_defaults
local chunk_component_duplicates = chunk.__component_duplicates
local chunk_component_reallocs = chunk.__component_reallocs
local chunk_component_compmoves = chunk.__component_compmoves
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
local b_place = chunk.__entity_count + 1
local e_place = b_place + entity_count - 1
if e_place > chunk_entity_capacity then
if e_place > chunk.__entity_capacity then
__expand_chunk(chunk, e_place)
end
local chunk_entity_list = chunk.__entity_list
do
chunk.__entity_count = e_place
__structural_changes = __structural_changes + 1
@@ -2891,10 +2896,104 @@ end
---@param chunk evolved.chunk
---@param min_capacity integer
function __expand_chunk(chunk, min_capacity)
if __defer_depth <= 0 then
__error_fmt('this operation should be deferred')
end
if min_capacity < 4 then
min_capacity = 4
end
local entity_count = chunk.__entity_count
if min_capacity < entity_count then
min_capacity = entity_count
end
local old_capacity = chunk.__entity_capacity
if old_capacity >= min_capacity then
-- no need to expand, the chunk is already large enough
return
end
local new_capacity = old_capacity * 2
if new_capacity < min_capacity then
new_capacity = min_capacity
end
if chunk.__has_storage_reallocs then
local component_count = chunk.__component_count
local component_storages = chunk.__component_storages
local component_reallocs = chunk.__component_reallocs
for component_index = 1, component_count do
local component_realloc = component_reallocs[component_index]
if component_realloc then
local old_component_storage = component_storages[component_index]
local new_component_storage = component_realloc(
old_component_storage, old_capacity, new_capacity)
component_storages[component_index] = new_component_storage
end
end
end
chunk.__entity_capacity = new_capacity
end
---@param chunk evolved.chunk
function __shrink_chunk(chunk)
if __defer_depth <= 0 then
__error_fmt('this operation should be deferred')
end
local min_capacity = 4
local entity_count = chunk.__entity_count
if min_capacity < entity_count then
min_capacity = entity_count
end
local old_capacity = chunk.__entity_capacity
if old_capacity <= min_capacity then
-- no need to shrink, the chunk is already small enough
return
end
do
local entity_list = __lua_table_new(min_capacity)
__lua_table_move(chunk.__entity_list, 1, entity_count, 1, entity_list)
chunk.__entity_list = entity_list
end
do
local component_count = chunk.__component_count
local component_storages = chunk.__component_storages
local component_reallocs = chunk.__component_reallocs
for component_index = 1, component_count do
local component_realloc = component_reallocs[component_index]
local old_component_storage = component_storages[component_index]
local new_component_storage ---@type evolved.storage?
if component_realloc then
new_component_storage = component_realloc(
old_component_storage, old_capacity, min_capacity)
else
new_component_storage = __lua_table_new(min_capacity)
__lua_table_move(old_component_storage, 1, entity_count, 1, new_component_storage)
end
component_storages[component_index] = new_component_storage
end
end
chunk.__entity_capacity = min_capacity
end
---@param chunk_list evolved.chunk[]
@@ -3216,12 +3315,10 @@ function __chunk_set(old_chunk, fragment, component)
end
end
local new_entity_list = new_chunk.__entity_list
local new_entity_count = new_chunk.__entity_count
local new_entity_capacity = new_chunk.__entity_capacity
local new_component_indices = new_chunk.__component_indices
local new_component_storages = new_chunk.__component_storages
local new_component_reallocs = new_chunk.__component_reallocs
local new_component_compmoves = new_chunk.__component_compmoves
local new_chunk_has_setup_hooks = new_chunk.__has_setup_hooks
local new_chunk_has_insert_hooks = new_chunk.__has_insert_hooks
@@ -3234,12 +3331,15 @@ function __chunk_set(old_chunk, fragment, component)
__evolved_get(fragment, __DEFAULT, __DUPLICATE, __ON_SET, __ON_INSERT)
end
local sum_entity_count = old_entity_count + new_entity_count
local sum_entity_count = old_entity_count + new_chunk.__entity_count
if sum_entity_count > new_entity_capacity then
if sum_entity_count > new_chunk.__entity_capacity then
__expand_chunk(new_chunk, sum_entity_count)
end
local new_entity_list = new_chunk.__entity_list
local new_entity_count = new_chunk.__entity_count
if new_entity_count == 0 then
old_chunk.__entity_list, new_chunk.__entity_list =
new_entity_list, old_entity_list
@@ -3263,10 +3363,19 @@ function __chunk_set(old_chunk, fragment, component)
local new_ci = new_component_indices[old_f]
local new_cs = new_component_storages[new_ci]
local new_cr = new_component_reallocs[new_ci]
local new_cm = new_component_compmoves[new_ci]
__lua_table_move(
old_cs, 1, old_entity_count,
new_entity_count + 1, new_cs)
if new_cm then
new_cm(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
elseif new_cr then
for old_place = 1, old_entity_count do
local new_place = new_entity_count + old_place
new_cs[new_place] = old_cs[old_place]
end
else
__lua_table_move(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
end
end
__lua_table_move(
@@ -3544,20 +3653,21 @@ function __chunk_remove(old_chunk, ...)
end
if new_chunk then
local new_entity_list = new_chunk.__entity_list
local new_entity_count = new_chunk.__entity_count
local new_entity_capacity = new_chunk.__entity_capacity
local new_component_count = new_chunk.__component_count
local new_component_storages = new_chunk.__component_storages
local new_component_fragments = new_chunk.__component_fragments
local new_component_reallocs = new_chunk.__component_reallocs
local new_component_compmoves = new_chunk.__component_compmoves
local sum_entity_count = old_entity_count + new_entity_count
local sum_entity_count = old_entity_count + new_chunk.__entity_count
if sum_entity_count > new_entity_capacity then
if sum_entity_count > new_chunk.__entity_capacity then
__expand_chunk(new_chunk, sum_entity_count)
end
local new_entity_list = new_chunk.__entity_list
local new_entity_count = new_chunk.__entity_count
if new_entity_count == 0 then
old_chunk.__entity_list, new_chunk.__entity_list =
new_entity_list, old_entity_list
@@ -3578,13 +3688,22 @@ function __chunk_remove(old_chunk, ...)
for new_ci = 1, new_component_count do
local new_f = new_component_fragments[new_ci]
local new_cs = new_component_storages[new_ci]
local new_cr = new_component_reallocs[new_ci]
local new_cm = new_component_compmoves[new_ci]
local old_ci = old_component_indices[new_f]
local old_cs = old_component_storages[old_ci]
__lua_table_move(
old_cs, 1, old_entity_count,
new_entity_count + 1, new_cs)
if new_cm then
new_cm(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
elseif new_cr then
for old_place = 1, old_entity_count do
local new_place = new_entity_count + old_place
new_cs[new_place] = old_cs[old_place]
end
else
__lua_table_move(old_cs, 1, old_entity_count, new_entity_count + 1, new_cs)
end
end
__lua_table_move(
@@ -4723,10 +4842,6 @@ function __evolved_set(entity, fragment, component)
end
end
local new_entity_list = new_chunk.__entity_list
local new_entity_count = new_chunk.__entity_count
local new_entity_capacity = new_chunk.__entity_capacity
local new_component_indices = new_chunk.__component_indices
local new_component_storages = new_chunk.__component_storages
@@ -4741,12 +4856,14 @@ function __evolved_set(entity, fragment, component)
__evolved_get(fragment, __DEFAULT, __DUPLICATE, __ON_SET, __ON_INSERT)
end
local new_place = new_entity_count + 1
local new_place = new_chunk.__entity_count + 1
if new_place > new_entity_capacity then
if new_place > new_chunk.__entity_capacity then
__expand_chunk(new_chunk, new_place)
end
local new_entity_list = new_chunk.__entity_list
new_entity_list[new_place] = entity
new_chunk.__entity_count = new_place
@@ -4934,20 +5051,18 @@ function __evolved_remove(entity, ...)
end
if new_chunk then
local new_entity_list = new_chunk.__entity_list
local new_entity_count = new_chunk.__entity_count
local new_entity_capacity = new_chunk.__entity_capacity
local new_component_count = new_chunk.__component_count
local new_component_storages = new_chunk.__component_storages
local new_component_fragments = new_chunk.__component_fragments
local new_place = new_entity_count + 1
local new_place = new_chunk.__entity_count + 1
if new_place > new_entity_capacity then
if new_place > new_chunk.__entity_capacity then
__expand_chunk(new_chunk, new_place)
end
local new_entity_list = new_chunk.__entity_list
new_entity_list[new_place] = entity
new_chunk.__entity_count = new_place
@@ -6361,10 +6476,10 @@ __evolved_set(__DEFAULT, __ON_REMOVE, __update_major_chunks)
__evolved_set(__DUPLICATE, __ON_INSERT, __update_major_chunks)
__evolved_set(__DUPLICATE, __ON_REMOVE, __update_major_chunks)
__evolved_set(__REALLOC, __ON_INSERT, __update_major_chunks)
__evolved_set(__REALLOC, __ON_SET, __update_major_chunks)
__evolved_set(__REALLOC, __ON_REMOVE, __update_major_chunks)
__evolved_set(__COMPMOVE, __ON_INSERT, __update_major_chunks)
__evolved_set(__COMPMOVE, __ON_SET, __update_major_chunks)
__evolved_set(__COMPMOVE, __ON_REMOVE, __update_major_chunks)
---