mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-15 04:15:28 +07:00
Merge branch 'feature/builders' into feature/benches
This commit is contained in:
@@ -61,6 +61,11 @@ remove :: entity, fragment... -> boolean, boolean
|
||||
clear :: entity -> boolean, boolean
|
||||
destroy :: entity -> boolean, boolean
|
||||
|
||||
multi_set :: entity, fragment[], component[]? -> boolean, boolean
|
||||
multi_assign :: entity, fragment[], component[]? -> boolean, boolean
|
||||
multi_insert :: entity, fragment[], component[]? -> boolean, boolean
|
||||
multi_remove :: entity, fragment[] -> boolean, boolean
|
||||
|
||||
batch_set :: query, fragment, any... -> integer, boolean
|
||||
batch_assign :: query, fragment, any... -> integer, boolean
|
||||
batch_insert :: query, fragment, any... -> integer, boolean
|
||||
|
||||
@@ -2510,3 +2510,436 @@ do
|
||||
assert(entities[1] == e2)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(not evo.multi_insert(e, {}))
|
||||
assert(not evo.multi_insert(e, {}, {}))
|
||||
assert(not evo.multi_insert(e, {}, { 41 }))
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
|
||||
assert(evo.multi_insert(e, { f1 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == true)
|
||||
|
||||
assert(not evo.multi_insert(e, { f1 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == true)
|
||||
|
||||
assert(evo.multi_insert(e, { f2 }, { 42, 43 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == true)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(evo.multi_insert(e, { f1, f2 }, { 41 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
|
||||
assert(evo.multi_insert(e, { f1, f3 }, { 20, 43 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == 43)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
do
|
||||
local e1 = evo.id()
|
||||
assert(evo.multi_insert(e1, { f1, f2 }, { 41, 42 }))
|
||||
assert(evo.has(e1, f1) and evo.get(e1, f1) == 41)
|
||||
assert(evo.has(e1, f2) and evo.get(e1, f2) == 42)
|
||||
|
||||
local e2 = evo.id()
|
||||
assert(evo.multi_insert(e2, { f1, f2 }, { 43, 44 }))
|
||||
assert(evo.has(e2, f1) and evo.get(e2, f1) == 43)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == 44)
|
||||
|
||||
assert(evo.multi_insert(e1, { f3 }))
|
||||
do
|
||||
local chunk, entities = evo.chunk(f1, f2)
|
||||
assert(entities and #entities == 1 and entities[1] == e2)
|
||||
assert(chunk and evo.select(chunk, f2)[1] == 44)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local e1, e2 = evo.id(2)
|
||||
evo.defer()
|
||||
do
|
||||
evo.multi_insert(e1, { f1, f2 }, { 41, 42 })
|
||||
evo.multi_insert(e2, { f2, f2 }, { 43, 44 })
|
||||
end
|
||||
assert(evo.is_alive(e1) and evo.is_empty(e1))
|
||||
assert(evo.is_alive(e2) and evo.is_empty(e2))
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
local last_set_entity = 0
|
||||
local last_set_component = 0
|
||||
|
||||
evo.set(f1, evo.ON_SET, function(e, f, c)
|
||||
assert(f == f1)
|
||||
last_set_entity = e
|
||||
last_set_component = c
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_SET, function(e, f, c)
|
||||
assert(f == f2)
|
||||
last_set_entity = e
|
||||
last_set_component = c
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_SET, function(e, f, c)
|
||||
assert(f == f3)
|
||||
last_set_entity = e
|
||||
last_set_component = c
|
||||
end)
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(evo.multi_insert(e, { f1, f2 }, { 41, 42 }))
|
||||
assert(last_set_entity == e and last_set_component == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(evo.multi_insert(e, { f1, f2, f3 }, { 41, 42, 43 }))
|
||||
assert(last_set_entity == e and last_set_component == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(not evo.multi_assign(e, {}))
|
||||
assert(not evo.multi_assign(e, {}, {}))
|
||||
assert(not evo.multi_assign(e, {}, { 41 }))
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
|
||||
assert(evo.multi_insert(e, { f1 }, { 21 }))
|
||||
assert(evo.multi_assign(e, { f1, f2 }, { 41, 42 }))
|
||||
assert(not evo.multi_assign(e, { f2 }, { 42 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
assert(not evo.has(e, f2) and evo.get(e, f2) == nil)
|
||||
|
||||
assert(not evo.multi_assign(e, { f3 }, { 43 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
assert(not evo.has(e, f2) and evo.get(e, f2) == nil)
|
||||
assert(not evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||
|
||||
assert(evo.multi_insert(e, { f2 }, { 22 }))
|
||||
assert(evo.multi_assign(e, { f2 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
assert(evo.multi_assign(e, { f2 }, { 42, 43 }))
|
||||
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 e1, e2 = evo.id(2)
|
||||
evo.defer()
|
||||
do
|
||||
evo.multi_insert(e1, { f1, f2 }, { 21, 22 })
|
||||
evo.multi_assign(e1, { f1, f2 }, { 41, 42 })
|
||||
|
||||
evo.multi_insert(e2, { f1, f2 }, { 31, 32 })
|
||||
evo.multi_assign(e2, { f1, f2 }, { 51, 52 })
|
||||
end
|
||||
assert(evo.is_alive(e1) and evo.is_empty(e1))
|
||||
assert(evo.is_alive(e2) and evo.is_empty(e2))
|
||||
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, f1) and evo.get(e2, f1) == 51)
|
||||
assert(evo.has(e2, f2) and evo.get(e2, f2) == 52)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
local last_set_entity = 0
|
||||
local last_set_component = 0
|
||||
|
||||
evo.set(f1, evo.ON_SET, function(e, f, c)
|
||||
assert(f == f1)
|
||||
last_set_entity = e
|
||||
last_set_component = c
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_SET, function(e, f, c)
|
||||
assert(f == f2)
|
||||
last_set_entity = e
|
||||
last_set_component = c
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_SET, function(e, f, c)
|
||||
assert(f == f3)
|
||||
last_set_entity = e
|
||||
last_set_component = c
|
||||
end)
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(not evo.multi_assign(e, { f1, f2 }, { 41, 42 }))
|
||||
assert(last_set_entity == 0 and last_set_component == 0)
|
||||
|
||||
assert(evo.multi_insert(e, { f1, f2 }, { 21, 22 }))
|
||||
assert(last_set_entity == e and last_set_component == 22)
|
||||
|
||||
assert(evo.multi_assign(e, { f1, f2 }, { 41, 42 }))
|
||||
assert(last_set_entity == e and last_set_component == 42)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(evo.multi_insert(e, { f1, f2, f3 }, { 21, 22, 23 }))
|
||||
assert(last_set_entity == e and last_set_component == nil)
|
||||
|
||||
last_set_entity, last_set_component = 0, 0
|
||||
assert(evo.multi_assign(e, { f1, f2, f3 }, { 41, 42, 43 }))
|
||||
assert(last_set_entity == e and last_set_component == nil)
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(evo.multi_insert(e, { f1, f2, f3 }, { 41, 42, 43 }))
|
||||
assert(evo.has_all(e, f1, f2, f3))
|
||||
|
||||
assert(evo.multi_remove(e, {}))
|
||||
assert(evo.multi_remove(e, { f4 }))
|
||||
assert(evo.has_all(e, f1, f2, f3))
|
||||
|
||||
assert(evo.multi_remove(e, { f3 }))
|
||||
assert(evo.has(e, f1) and evo.has(e, f2) and not evo.has(e, f3))
|
||||
assert(evo.get(e, f1) == 41 and evo.get(e, f2) == 42 and evo.get(e, f3) == nil)
|
||||
|
||||
assert(evo.multi_remove(e, { f1, f2, f4 }))
|
||||
assert(not evo.has_any(e, f1, f2, f3))
|
||||
assert(evo.get(e, f1) == nil and evo.get(e, f2) == nil and evo.get(e, f3) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(evo.multi_insert(e, { f1, f2, f3 }, { 41, 42, 43 }))
|
||||
assert(evo.has_all(e, f1, f2, f3))
|
||||
evo.defer()
|
||||
evo.multi_remove(e, { f1, f2 })
|
||||
assert(evo.has_all(e, f1, f2, f3))
|
||||
assert(evo.commit())
|
||||
assert(not evo.has(e, f1) and not evo.has(e, f2) and evo.has(e, f3))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
local last_remove_entity = 0
|
||||
local last_remove_component = 0
|
||||
|
||||
evo.set(f1, evo.ON_REMOVE, function(e, f, c)
|
||||
assert(f == f1)
|
||||
last_remove_entity = e
|
||||
last_remove_component = c
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_REMOVE, function(e, f, c)
|
||||
assert(f == f2)
|
||||
last_remove_entity = e
|
||||
last_remove_component = c
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_REMOVE, function(e, f, c)
|
||||
assert(f == f3)
|
||||
last_remove_entity = e
|
||||
last_remove_component = c
|
||||
end)
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(evo.multi_remove(e, { f1, f2 }))
|
||||
assert(last_remove_entity == 0 and last_remove_component == 0)
|
||||
|
||||
assert(evo.multi_insert(e, { f1, f2, f3 }, { 41, 42 }))
|
||||
assert(last_remove_entity == 0 and last_remove_component == 0)
|
||||
assert(evo.multi_remove(e, { f1, f2 }))
|
||||
assert(last_remove_entity == e and last_remove_component == 42)
|
||||
assert(evo.multi_remove(e, { f3 }))
|
||||
assert(last_remove_entity == e and last_remove_component == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
do
|
||||
local e1, e2 = evo.id(2)
|
||||
assert(evo.multi_insert(e1, { f1, f2, f3 }, { 41, 42, 43 }))
|
||||
assert(evo.multi_insert(e2, { f1, f2, f3 }, { 44, 45, 46 }))
|
||||
|
||||
assert(evo.multi_remove(e1, { f1, f2 }))
|
||||
|
||||
do
|
||||
local chunk, entities = evo.chunk(f1, f2, f3)
|
||||
assert(entities and #entities == 1 and entities[1] == e2)
|
||||
assert(chunk and evo.select(chunk, f2)[1] == 45)
|
||||
end
|
||||
|
||||
do
|
||||
local chunk, entities = evo.chunk(f3)
|
||||
assert(entities and #entities == 1 and entities[1] == e1)
|
||||
assert(chunk and evo.select(chunk, f3)[1] == 43)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, f4 = evo.id(4)
|
||||
|
||||
evo.set(f3, evo.DEFAULT, 43)
|
||||
evo.set(f4, evo.TAG)
|
||||
|
||||
|
||||
do
|
||||
local e = evo.id()
|
||||
assert(not evo.multi_set(e, {}))
|
||||
assert(not evo.multi_set(e, {}, {}))
|
||||
assert(not evo.multi_set(e, {}, { 41 }))
|
||||
assert(evo.is_alive(e) and evo.is_empty(e))
|
||||
|
||||
assert(evo.multi_set(e, { f1 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == true)
|
||||
|
||||
assert(evo.multi_set(e, { f1 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == true)
|
||||
|
||||
assert(evo.multi_set(e, { f1 }, { 41 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
|
||||
assert(evo.multi_set(e, { f2 }, { 42 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
|
||||
|
||||
assert(evo.multi_set(e, { f2 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == true)
|
||||
|
||||
assert(evo.multi_set(e, { f2, f3 }, { 42 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == 43)
|
||||
|
||||
assert(evo.multi_set(e, { f3, f4 }, { 33, 44 }))
|
||||
assert(evo.has(e, f1) and evo.get(e, f1) == 41)
|
||||
assert(evo.has(e, f2) and evo.get(e, f2) == 42)
|
||||
assert(evo.has(e, f3) and evo.get(e, f3) == 33)
|
||||
assert(evo.has(e, f4) and evo.get(e, f4) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3 = evo.id(3)
|
||||
|
||||
evo.set(f2, evo.DEFAULT, 42)
|
||||
evo.set(f3, evo.TAG)
|
||||
|
||||
local last_assign_entity = 0
|
||||
local last_assign_new_component = 0
|
||||
local last_assign_old_component = 0
|
||||
|
||||
evo.set(f1, evo.ON_ASSIGN, function(e, f, nc, oc)
|
||||
assert(f == f1)
|
||||
last_assign_entity = e
|
||||
last_assign_new_component = nc
|
||||
last_assign_old_component = oc
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_ASSIGN, function(e, f, nc, oc)
|
||||
assert(f == f2)
|
||||
last_assign_entity = e
|
||||
last_assign_new_component = nc
|
||||
last_assign_old_component = oc
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_ASSIGN, function(e, f, nc, oc)
|
||||
assert(f == f3)
|
||||
last_assign_entity = e
|
||||
last_assign_new_component = nc
|
||||
last_assign_old_component = oc
|
||||
end)
|
||||
|
||||
local last_insert_entity = 0
|
||||
local last_insert_component = 0
|
||||
|
||||
evo.set(f1, evo.ON_INSERT, function(e, f, nc)
|
||||
assert(f == f1)
|
||||
last_insert_entity = e
|
||||
last_insert_component = nc
|
||||
end)
|
||||
|
||||
evo.set(f2, evo.ON_INSERT, function(e, f, nc)
|
||||
assert(f == f2)
|
||||
last_insert_entity = e
|
||||
last_insert_component = nc
|
||||
end)
|
||||
|
||||
evo.set(f3, evo.ON_INSERT, function(e, f, nc)
|
||||
assert(f == f3)
|
||||
last_insert_entity = e
|
||||
last_insert_component = nc
|
||||
end)
|
||||
|
||||
do
|
||||
last_assign_entity, last_assign_old_component, last_assign_new_component = 0, 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
|
||||
local e = evo.id()
|
||||
assert(evo.multi_set(e, { f1 }))
|
||||
assert(last_assign_entity == 0 and last_assign_old_component == 0 and last_assign_new_component == 0)
|
||||
assert(last_insert_entity == e and last_insert_component == true)
|
||||
|
||||
last_assign_entity, last_assign_old_component, last_assign_new_component = 0, 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
|
||||
assert(evo.multi_set(e, { f1 }, { 41 }))
|
||||
assert(last_assign_entity == e and last_assign_old_component == true and last_assign_new_component == 41)
|
||||
assert(last_insert_entity == 0 and last_insert_component == 0)
|
||||
|
||||
last_assign_entity, last_assign_old_component, last_assign_new_component = 0, 0, 0
|
||||
last_insert_entity, last_insert_component = 0, 0
|
||||
|
||||
assert(evo.multi_set(e, { f1, f2 }, { 11 }))
|
||||
assert(last_assign_entity == e and last_assign_old_component == 41 and last_assign_new_component == 11)
|
||||
assert(last_insert_entity == e and last_insert_component == 42)
|
||||
end
|
||||
end
|
||||
|
||||
758
evolved.lua
758
evolved.lua
@@ -369,6 +369,11 @@ local __EMPTY_FRAGMENT_LIST = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty fragment list') end
|
||||
})
|
||||
|
||||
---@type evolved.component[]
|
||||
local __EMPTY_COMPONENT_LIST = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty component list') end
|
||||
})
|
||||
|
||||
---@type evolved.component[]
|
||||
local __EMPTY_COMPONENT_STORAGE = setmetatable({}, {
|
||||
__newindex = function() error('attempt to modify empty component storage') end
|
||||
@@ -644,6 +649,25 @@ local function __chunk_with_fragment(parent_chunk, child_fragment)
|
||||
return child_chunk
|
||||
end
|
||||
|
||||
---@param chunk? evolved.chunk
|
||||
---@param fragment_list evolved.fragment[]
|
||||
---@return evolved.chunk?
|
||||
---@nodiscard
|
||||
local function __chunk_with_fragment_list(chunk, fragment_list)
|
||||
local fragment_count = #fragment_list
|
||||
|
||||
if fragment_count == 0 then
|
||||
return chunk
|
||||
end
|
||||
|
||||
for i = 1, fragment_count do
|
||||
local fragment = fragment_list[i]
|
||||
chunk = __chunk_with_fragment(chunk, fragment)
|
||||
end
|
||||
|
||||
return chunk
|
||||
end
|
||||
|
||||
---@param chunk? evolved.chunk
|
||||
---@param fragment evolved.fragment
|
||||
---@return evolved.chunk?
|
||||
@@ -699,6 +723,25 @@ local function __chunk_without_fragments(chunk, ...)
|
||||
return chunk
|
||||
end
|
||||
|
||||
---@param chunk? evolved.chunk
|
||||
---@param fragment_list evolved.fragment[]
|
||||
---@return evolved.chunk?
|
||||
---@nodiscard
|
||||
local function __chunk_without_fragment_list(chunk, fragment_list)
|
||||
local fragment_count = #fragment_list
|
||||
|
||||
if fragment_count == 0 then
|
||||
return chunk
|
||||
end
|
||||
|
||||
for i = 1, fragment_count do
|
||||
local fragment = fragment_list[i]
|
||||
chunk = __chunk_without_fragment(chunk, fragment)
|
||||
end
|
||||
|
||||
return chunk
|
||||
end
|
||||
|
||||
---
|
||||
---
|
||||
---
|
||||
@@ -955,8 +998,8 @@ local function __chunk_insert(chunk, fragment, ...)
|
||||
local old_f = old_component_fragments[i]
|
||||
local old_cs = old_component_storages[i]
|
||||
local new_ci = new_component_indices[old_f]
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
if new_cs then
|
||||
if new_ci then
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
__table_move(old_cs, 1, old_size, new_size + 1, new_cs)
|
||||
end
|
||||
end
|
||||
@@ -1098,8 +1141,8 @@ local function __chunk_remove(chunk, ...)
|
||||
local new_f = new_component_fragments[i]
|
||||
local new_cs = new_component_storages[i]
|
||||
local old_ci = old_component_indices[new_f]
|
||||
local old_cs = old_component_storages[old_ci]
|
||||
if old_cs then
|
||||
if old_ci then
|
||||
local old_cs = old_component_storages[old_ci]
|
||||
__table_move(old_cs, 1, old_size, new_size + 1, new_cs)
|
||||
end
|
||||
end
|
||||
@@ -1305,12 +1348,18 @@ local __defer_op = {
|
||||
remove = 4,
|
||||
clear = 5,
|
||||
destroy = 6,
|
||||
batch_set = 7,
|
||||
batch_assign = 8,
|
||||
batch_insert = 9,
|
||||
batch_remove = 10,
|
||||
batch_clear = 11,
|
||||
batch_destroy = 12,
|
||||
|
||||
multi_set = 7,
|
||||
multi_assign = 8,
|
||||
multi_insert = 9,
|
||||
multi_remove = 10,
|
||||
|
||||
batch_set = 11,
|
||||
batch_assign = 12,
|
||||
batch_insert = 13,
|
||||
batch_remove = 14,
|
||||
batch_clear = 15,
|
||||
batch_destroy = 16,
|
||||
}
|
||||
|
||||
---@type table<evolved.defer_op, fun(bytes: any[], index: integer): integer>
|
||||
@@ -1352,6 +1401,40 @@ local __defer_ops = {
|
||||
evolved.destroy(entity)
|
||||
return 1
|
||||
end,
|
||||
[__defer_op.multi_set] = function(bytes, index)
|
||||
local entity = bytes[index + 0]
|
||||
local fragments = bytes[index + 1]
|
||||
local components = bytes[index + 2]
|
||||
evolved.multi_set(entity, fragments, components)
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragments)
|
||||
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, components)
|
||||
return 3
|
||||
end,
|
||||
[__defer_op.multi_assign] = function(bytes, index)
|
||||
local entity = bytes[index + 0]
|
||||
local fragments = bytes[index + 1]
|
||||
local components = bytes[index + 2]
|
||||
evolved.multi_assign(entity, fragments, components)
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragments)
|
||||
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, components)
|
||||
return 3
|
||||
end,
|
||||
[__defer_op.multi_insert] = function(bytes, index)
|
||||
local entity = bytes[index + 0]
|
||||
local fragments = bytes[index + 1]
|
||||
local components = bytes[index + 2]
|
||||
evolved.multi_insert(entity, fragments, components)
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragments)
|
||||
__release_table(__TABLE_POOL_TAG__COMPONENT_LIST, components)
|
||||
return 3
|
||||
end,
|
||||
[__defer_op.multi_remove] = function(bytes, index)
|
||||
local entity = bytes[index + 0]
|
||||
local fragments = bytes[index + 1]
|
||||
evolved.multi_remove(entity, fragments)
|
||||
__release_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragments)
|
||||
return 2
|
||||
end,
|
||||
[__defer_op.batch_set] = function(bytes, index)
|
||||
local query = bytes[index + 0]
|
||||
local fragment = bytes[index + 1]
|
||||
@@ -1534,6 +1617,92 @@ local function __defer_destroy(entity)
|
||||
__defer_length = length + 2
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param fragments evolved.fragment[]
|
||||
---@param components any[]
|
||||
local function __defer_multi_set(entity, fragments, components)
|
||||
local fragment_count = #fragments
|
||||
local fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_count, 0)
|
||||
__table_move(fragments, 1, fragment_count, 1, fragment_list)
|
||||
|
||||
local component_count = #components
|
||||
local component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_count, 0)
|
||||
__table_move(components, 1, component_count, 1, component_list)
|
||||
|
||||
local length = __defer_length
|
||||
local bytecode = __defer_bytecode
|
||||
|
||||
bytecode[length + 1] = __defer_op.multi_set
|
||||
bytecode[length + 2] = entity
|
||||
bytecode[length + 3] = fragment_list
|
||||
bytecode[length + 4] = component_list
|
||||
|
||||
__defer_length = length + 4
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param fragments evolved.fragment[]
|
||||
---@param components any[]
|
||||
local function __defer_multi_assign(entity, fragments, components)
|
||||
local fragment_count = #fragments
|
||||
local fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_count, 0)
|
||||
__table_move(fragments, 1, fragment_count, 1, fragment_list)
|
||||
|
||||
local component_count = #components
|
||||
local component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_count, 0)
|
||||
__table_move(components, 1, component_count, 1, component_list)
|
||||
|
||||
local length = __defer_length
|
||||
local bytecode = __defer_bytecode
|
||||
|
||||
bytecode[length + 1] = __defer_op.multi_assign
|
||||
bytecode[length + 2] = entity
|
||||
bytecode[length + 3] = fragment_list
|
||||
bytecode[length + 4] = component_list
|
||||
|
||||
__defer_length = length + 4
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param fragments evolved.fragment[]
|
||||
---@param components any[]
|
||||
local function __defer_multi_insert(entity, fragments, components)
|
||||
local fragment_count = #fragments
|
||||
local fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_count, 0)
|
||||
__table_move(fragments, 1, fragment_count, 1, fragment_list)
|
||||
|
||||
local component_count = #components
|
||||
local component_list = __acquire_table(__TABLE_POOL_TAG__COMPONENT_LIST, component_count, 0)
|
||||
__table_move(components, 1, component_count, 1, component_list)
|
||||
|
||||
local length = __defer_length
|
||||
local bytecode = __defer_bytecode
|
||||
|
||||
bytecode[length + 1] = __defer_op.multi_insert
|
||||
bytecode[length + 2] = entity
|
||||
bytecode[length + 3] = fragment_list
|
||||
bytecode[length + 4] = component_list
|
||||
|
||||
__defer_length = length + 4
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param fragments evolved.fragment[]
|
||||
local function __defer_multi_remove(entity, fragments)
|
||||
local fragment_count = #fragments
|
||||
local fragment_list = __acquire_table(__TABLE_POOL_TAG__FRAGMENT_LIST, fragment_count, 0)
|
||||
__table_move(fragments, 1, fragment_count, 1, fragment_list)
|
||||
|
||||
local length = __defer_length
|
||||
local bytecode = __defer_bytecode
|
||||
|
||||
bytecode[length + 1] = __defer_op.multi_remove
|
||||
bytecode[length + 2] = entity
|
||||
bytecode[length + 3] = fragment_list
|
||||
|
||||
__defer_length = length + 3
|
||||
end
|
||||
|
||||
---@param query evolved.query
|
||||
---@param fragment evolved.fragment
|
||||
---@param ... any component arguments
|
||||
@@ -1834,6 +2003,12 @@ function evolved.set(entity, fragment, ...)
|
||||
|
||||
local new_chunk = __chunk_with_fragment(old_chunk, fragment)
|
||||
|
||||
if not new_chunk then
|
||||
return false, false
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
if old_chunk == new_chunk then
|
||||
local old_component_indices = old_chunk.__component_indices
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
@@ -1867,12 +2042,7 @@ function evolved.set(entity, fragment, ...)
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment)
|
||||
end
|
||||
end
|
||||
|
||||
return true, false
|
||||
end
|
||||
|
||||
__defer()
|
||||
do
|
||||
else
|
||||
local new_entities = new_chunk.__entities
|
||||
local new_component_indices = new_chunk.__component_indices
|
||||
local new_component_storages = new_chunk.__component_storages
|
||||
@@ -1880,6 +2050,23 @@ function evolved.set(entity, fragment, ...)
|
||||
local new_place = #new_entities + 1
|
||||
new_entities[new_place] = entity
|
||||
|
||||
if old_chunk then
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
local old_component_fragments = old_chunk.__component_fragments
|
||||
|
||||
for i = 1, #old_component_fragments do
|
||||
local old_f = old_component_fragments[i]
|
||||
local old_cs = old_component_storages[i]
|
||||
local new_ci = new_component_indices[old_f]
|
||||
if new_ci then
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
|
||||
__detach_entity(entity)
|
||||
end
|
||||
|
||||
do
|
||||
local new_component_index = new_component_indices[fragment]
|
||||
|
||||
@@ -1911,28 +2098,12 @@ function evolved.set(entity, fragment, ...)
|
||||
end
|
||||
end
|
||||
|
||||
if old_chunk then
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
local old_component_fragments = old_chunk.__component_fragments
|
||||
|
||||
for i = 1, #old_component_fragments do
|
||||
local old_f = old_component_fragments[i]
|
||||
local old_cs = old_component_storages[i]
|
||||
local new_ci = new_component_indices[old_f]
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
if new_cs then
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
|
||||
__detach_entity(entity)
|
||||
end
|
||||
|
||||
__entity_chunks[entity_index] = new_chunk
|
||||
__entity_places[entity_index] = new_place
|
||||
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return true, false
|
||||
end
|
||||
@@ -1961,6 +2132,8 @@ function evolved.assign(entity, fragment, ...)
|
||||
return false, false
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
do
|
||||
local component_indices = chunk.__component_indices
|
||||
local component_storages = chunk.__component_storages
|
||||
@@ -1996,6 +2169,7 @@ function evolved.assign(entity, fragment, ...)
|
||||
end
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return true, false
|
||||
end
|
||||
|
||||
@@ -2021,11 +2195,12 @@ function evolved.insert(entity, fragment, ...)
|
||||
|
||||
local new_chunk = __chunk_with_fragment(old_chunk, fragment)
|
||||
|
||||
if old_chunk == new_chunk then
|
||||
if not new_chunk or old_chunk == new_chunk then
|
||||
return false, false
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
do
|
||||
local new_entities = new_chunk.__entities
|
||||
local new_component_indices = new_chunk.__component_indices
|
||||
@@ -2034,6 +2209,23 @@ function evolved.insert(entity, fragment, ...)
|
||||
local new_place = #new_entities + 1
|
||||
new_entities[new_place] = entity
|
||||
|
||||
if old_chunk then
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
local old_component_fragments = old_chunk.__component_fragments
|
||||
|
||||
for i = 1, #old_component_fragments do
|
||||
local old_f = old_component_fragments[i]
|
||||
local old_cs = old_component_storages[i]
|
||||
local new_ci = new_component_indices[old_f]
|
||||
if new_ci then
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
|
||||
__detach_entity(entity)
|
||||
end
|
||||
|
||||
do
|
||||
local new_component_index = new_component_indices[fragment]
|
||||
|
||||
@@ -2065,28 +2257,12 @@ function evolved.insert(entity, fragment, ...)
|
||||
end
|
||||
end
|
||||
|
||||
if old_chunk then
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
local old_component_fragments = old_chunk.__component_fragments
|
||||
|
||||
for i = 1, #old_component_fragments do
|
||||
local old_f = old_component_fragments[i]
|
||||
local old_cs = old_component_storages[i]
|
||||
local new_ci = new_component_indices[old_f]
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
if new_cs then
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
|
||||
__detach_entity(entity)
|
||||
end
|
||||
|
||||
__entity_chunks[entity_index] = new_chunk
|
||||
__entity_places[entity_index] = new_place
|
||||
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return true, false
|
||||
end
|
||||
@@ -2117,6 +2293,7 @@ function evolved.remove(entity, ...)
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
do
|
||||
local old_fragment_set = old_chunk.__fragment_set
|
||||
local old_component_indices = old_chunk.__component_indices
|
||||
@@ -2150,8 +2327,8 @@ function evolved.remove(entity, ...)
|
||||
local new_f = new_component_fragments[i]
|
||||
local new_cs = new_component_storages[i]
|
||||
local old_ci = old_component_indices[new_f]
|
||||
local old_cs = old_component_storages[old_ci]
|
||||
if old_cs then
|
||||
if old_ci then
|
||||
local old_cs = old_component_storages[old_ci]
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
@@ -2166,6 +2343,7 @@ function evolved.remove(entity, ...)
|
||||
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return true, false
|
||||
end
|
||||
@@ -2193,6 +2371,7 @@ function evolved.clear(entity)
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
do
|
||||
local fragment_list = chunk.__fragment_list
|
||||
local component_indices = chunk.__component_indices
|
||||
@@ -2216,6 +2395,7 @@ function evolved.clear(entity)
|
||||
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return true, false
|
||||
end
|
||||
@@ -2244,6 +2424,7 @@ function evolved.destroy(entity)
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
do
|
||||
local fragment_list = chunk.__fragment_list
|
||||
local component_indices = chunk.__component_indices
|
||||
@@ -2268,6 +2449,477 @@ function evolved.destroy(entity)
|
||||
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return true, false
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param fragments evolved.fragment[]
|
||||
---@param components? any[]
|
||||
---@return boolean is_any_set
|
||||
---@return boolean is_deferred
|
||||
function evolved.multi_set(entity, fragments, components)
|
||||
local fragment_count = #fragments
|
||||
|
||||
if fragment_count == 0 then
|
||||
return false, false
|
||||
end
|
||||
|
||||
if not components then
|
||||
components = __EMPTY_COMPONENT_LIST
|
||||
end
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_multi_set(entity, fragments, components)
|
||||
return false, true
|
||||
end
|
||||
|
||||
local entity_index = entity % 0x100000
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return false, false
|
||||
end
|
||||
|
||||
local old_chunk = __entity_chunks[entity_index]
|
||||
local old_place = __entity_places[entity_index]
|
||||
|
||||
local new_chunk = __chunk_with_fragment_list(old_chunk, fragments)
|
||||
|
||||
if not new_chunk then
|
||||
return false, false
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
if old_chunk == new_chunk then
|
||||
local old_fragment_set = old_chunk.__fragment_set
|
||||
local old_component_indices = old_chunk.__component_indices
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
|
||||
for i = 1, fragment_count do
|
||||
local fragment = fragments[i]
|
||||
if old_fragment_set[fragment] then
|
||||
local old_component_index = old_component_indices[fragment]
|
||||
|
||||
if old_component_index then
|
||||
local old_component_storage = old_component_storages[old_component_index]
|
||||
local old_component = old_component_storage[old_place]
|
||||
|
||||
if old_chunk.__has_defaults_or_constructs then
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then new_component = evolved.get(fragment, evolved.DEFAULT) end
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
old_component_storage[old_place] = new_component
|
||||
|
||||
if old_chunk.__has_set_or_assign_hooks then
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment, new_component, old_component)
|
||||
end
|
||||
else
|
||||
local new_component = components[i]
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
old_component_storage[old_place] = new_component
|
||||
|
||||
if old_chunk.__has_set_or_assign_hooks then
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment, new_component, old_component)
|
||||
end
|
||||
end
|
||||
else
|
||||
if old_chunk.__has_set_or_assign_hooks then
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local new_entities = new_chunk.__entities
|
||||
local new_component_indices = new_chunk.__component_indices
|
||||
local new_component_storages = new_chunk.__component_storages
|
||||
|
||||
local old_fragment_set = old_chunk and old_chunk.__fragment_set or __EMPTY_FRAGMENT_SET
|
||||
|
||||
local new_place = #new_entities + 1
|
||||
new_entities[new_place] = entity
|
||||
|
||||
if old_chunk then
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
local old_component_fragments = old_chunk.__component_fragments
|
||||
|
||||
for i = 1, #old_component_fragments do
|
||||
local old_f = old_component_fragments[i]
|
||||
local old_cs = old_component_storages[i]
|
||||
local new_ci = new_component_indices[old_f]
|
||||
if new_ci then
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
|
||||
__detach_entity(entity)
|
||||
end
|
||||
|
||||
for i = 1, fragment_count do
|
||||
local fragment = fragments[i]
|
||||
if old_fragment_set[fragment] then
|
||||
local new_component_index = new_component_indices[fragment]
|
||||
|
||||
if new_component_index then
|
||||
local new_component_storage = new_component_storages[new_component_index]
|
||||
local old_component = new_component_storage[new_place]
|
||||
|
||||
if new_chunk.__has_defaults_or_constructs then
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then new_component = evolved.get(fragment, evolved.DEFAULT) end
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
new_component_storage[new_place] = new_component
|
||||
|
||||
if new_chunk.__has_set_or_assign_hooks then
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment, new_component, old_component)
|
||||
end
|
||||
else
|
||||
local new_component = components[i]
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
new_component_storage[new_place] = new_component
|
||||
|
||||
if new_chunk.__has_set_or_assign_hooks then
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment, new_component, old_component)
|
||||
end
|
||||
end
|
||||
else
|
||||
if new_chunk.__has_set_or_assign_hooks then
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment)
|
||||
end
|
||||
end
|
||||
else
|
||||
local new_component_index = new_component_indices[fragment]
|
||||
|
||||
if new_component_index then
|
||||
local new_component_storage = new_component_storages[new_component_index]
|
||||
|
||||
if new_chunk.__has_defaults_or_constructs then
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then new_component = evolved.get(fragment, evolved.DEFAULT) end
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
new_component_storage[new_place] = new_component
|
||||
|
||||
if new_chunk.__has_set_or_insert_hooks then
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment, new_component)
|
||||
end
|
||||
else
|
||||
local new_component = components[i]
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
new_component_storage[new_place] = new_component
|
||||
|
||||
if new_chunk.__has_set_or_insert_hooks then
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment, new_component)
|
||||
end
|
||||
end
|
||||
else
|
||||
if new_chunk.__has_set_or_insert_hooks then
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
__entity_chunks[entity_index] = new_chunk
|
||||
__entity_places[entity_index] = new_place
|
||||
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return true, false
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param fragments evolved.fragment[]
|
||||
---@param components? any[]
|
||||
---@return boolean is_any_assigned
|
||||
---@return boolean is_deferred
|
||||
function evolved.multi_assign(entity, fragments, components)
|
||||
local fragment_count = #fragments
|
||||
|
||||
if fragment_count == 0 then
|
||||
return false, false
|
||||
end
|
||||
|
||||
if not components then
|
||||
components = __EMPTY_COMPONENT_LIST
|
||||
end
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_multi_assign(entity, fragments, components)
|
||||
return false, true
|
||||
end
|
||||
|
||||
local entity_index = entity % 0x100000
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return false, false
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
local place = __entity_places[entity_index]
|
||||
|
||||
if not chunk or not __chunk_has_any_fragment_list(chunk, fragments) then
|
||||
return false, false
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
do
|
||||
local fragment_set = chunk.__fragment_set
|
||||
local component_indices = chunk.__component_indices
|
||||
local component_storages = chunk.__component_storages
|
||||
|
||||
for i = 1, fragment_count do
|
||||
local fragment = fragments[i]
|
||||
if fragment_set[fragment] then
|
||||
local component_index = component_indices[fragment]
|
||||
|
||||
if component_index then
|
||||
local component_storage = component_storages[component_index]
|
||||
local old_component = component_storage[place]
|
||||
|
||||
if chunk.__has_defaults_or_constructs then
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then new_component = evolved.get(fragment, evolved.DEFAULT) end
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
component_storage[place] = new_component
|
||||
|
||||
if chunk.__has_set_or_assign_hooks then
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment, new_component, old_component)
|
||||
end
|
||||
else
|
||||
local new_component = components[i]
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
component_storage[place] = new_component
|
||||
|
||||
if chunk.__has_set_or_assign_hooks then
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment, new_component, old_component)
|
||||
end
|
||||
end
|
||||
else
|
||||
if chunk.__has_set_or_assign_hooks then
|
||||
__fragment_call_set_and_assign_hooks(entity, fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return true, false
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param fragments evolved.fragment[]
|
||||
---@param components? any[]
|
||||
---@return boolean is_any_inserted
|
||||
---@return boolean is_deferred
|
||||
function evolved.multi_insert(entity, fragments, components)
|
||||
local fragment_count = #fragments
|
||||
|
||||
if fragment_count == 0 then
|
||||
return false, false
|
||||
end
|
||||
|
||||
if not components then
|
||||
components = __EMPTY_COMPONENT_LIST
|
||||
end
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_multi_insert(entity, fragments, components)
|
||||
return false, true
|
||||
end
|
||||
|
||||
local entity_index = entity % 0x100000
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return false, false
|
||||
end
|
||||
|
||||
local old_chunk = __entity_chunks[entity_index]
|
||||
local old_place = __entity_places[entity_index]
|
||||
|
||||
local new_chunk = __chunk_with_fragment_list(old_chunk, fragments)
|
||||
|
||||
if not new_chunk or old_chunk == new_chunk then
|
||||
return false, false
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
do
|
||||
local new_entities = new_chunk.__entities
|
||||
local new_component_indices = new_chunk.__component_indices
|
||||
local new_component_storages = new_chunk.__component_storages
|
||||
|
||||
local old_fragment_set = old_chunk and old_chunk.__fragment_set or __EMPTY_FRAGMENT_SET
|
||||
|
||||
local new_place = #new_entities + 1
|
||||
new_entities[new_place] = entity
|
||||
|
||||
if old_chunk then
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
local old_component_fragments = old_chunk.__component_fragments
|
||||
|
||||
for i = 1, #old_component_fragments do
|
||||
local old_f = old_component_fragments[i]
|
||||
local old_cs = old_component_storages[i]
|
||||
local new_ci = new_component_indices[old_f]
|
||||
if new_ci then
|
||||
local new_cs = new_component_storages[new_ci]
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
|
||||
__detach_entity(entity)
|
||||
end
|
||||
|
||||
for i = 1, fragment_count do
|
||||
local fragment = fragments[i]
|
||||
if not old_fragment_set[fragment] then
|
||||
local new_component_index = new_component_indices[fragment]
|
||||
|
||||
if new_component_index then
|
||||
local new_component_storage = new_component_storages[new_component_index]
|
||||
|
||||
if new_chunk.__has_defaults_or_constructs then
|
||||
local new_component = components[i]
|
||||
|
||||
if new_component == nil then new_component = evolved.get(fragment, evolved.DEFAULT) end
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
new_component_storage[new_place] = new_component
|
||||
|
||||
if new_chunk.__has_set_or_insert_hooks then
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment, new_component)
|
||||
end
|
||||
else
|
||||
local new_component = components[i]
|
||||
if new_component == nil then new_component = true end
|
||||
|
||||
new_component_storage[new_place] = new_component
|
||||
|
||||
if new_chunk.__has_set_or_insert_hooks then
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment, new_component)
|
||||
end
|
||||
end
|
||||
else
|
||||
if new_chunk.__has_set_or_insert_hooks then
|
||||
__fragment_call_set_and_insert_hooks(entity, fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
__entity_chunks[entity_index] = new_chunk
|
||||
__entity_places[entity_index] = new_place
|
||||
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return true, false
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
---@param fragments evolved.fragment[]
|
||||
---@return boolean is_all_removed
|
||||
---@return boolean is_deferred
|
||||
function evolved.multi_remove(entity, fragments)
|
||||
local fragment_count = #fragments
|
||||
|
||||
if fragment_count == 0 then
|
||||
return true, false
|
||||
end
|
||||
|
||||
if __defer_depth > 0 then
|
||||
__defer_multi_remove(entity, fragments)
|
||||
return false, true
|
||||
end
|
||||
|
||||
local entity_index = entity % 0x100000
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return false, false
|
||||
end
|
||||
|
||||
local old_chunk = __entity_chunks[entity_index]
|
||||
local old_place = __entity_places[entity_index]
|
||||
|
||||
local new_chunk = __chunk_without_fragment_list(old_chunk, fragments)
|
||||
|
||||
if old_chunk == new_chunk then
|
||||
return true, false
|
||||
end
|
||||
|
||||
__defer()
|
||||
|
||||
do
|
||||
local old_fragment_set = old_chunk.__fragment_set
|
||||
local old_component_indices = old_chunk.__component_indices
|
||||
local old_component_storages = old_chunk.__component_storages
|
||||
|
||||
if old_chunk.__has_remove_hooks then
|
||||
for i = 1, fragment_count do
|
||||
local fragment = fragments[i]
|
||||
if old_fragment_set[fragment] then
|
||||
local old_component_index = old_component_indices[fragment]
|
||||
if old_component_index then
|
||||
local old_component_storage = old_component_storages[old_component_index]
|
||||
local old_component = old_component_storage[old_place]
|
||||
__fragment_call_remove_hook(entity, fragment, old_component)
|
||||
else
|
||||
__fragment_call_remove_hook(entity, fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if new_chunk then
|
||||
local new_entities = new_chunk.__entities
|
||||
local new_component_storages = new_chunk.__component_storages
|
||||
local new_component_fragments = new_chunk.__component_fragments
|
||||
|
||||
local new_place = #new_entities + 1
|
||||
new_entities[new_place] = entity
|
||||
|
||||
for i = 1, #new_component_fragments do
|
||||
local new_f = new_component_fragments[i]
|
||||
local new_cs = new_component_storages[i]
|
||||
local old_ci = old_component_indices[new_f]
|
||||
if old_ci then
|
||||
local old_cs = old_component_storages[old_ci]
|
||||
new_cs[new_place] = old_cs[old_place]
|
||||
end
|
||||
end
|
||||
|
||||
__detach_entity(entity)
|
||||
|
||||
__entity_chunks[entity_index] = new_chunk
|
||||
__entity_places[entity_index] = new_place
|
||||
else
|
||||
__detach_entity(entity)
|
||||
end
|
||||
|
||||
__structural_changes = __structural_changes + 1
|
||||
end
|
||||
|
||||
__defer_commit()
|
||||
return true, false
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user