mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-15 04:15:28 +07:00
primary/secondary iterators for pair entities
This commit is contained in:
@@ -1683,6 +1683,201 @@ do
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
---@generic T1, T2
|
||||
---@param first T1
|
||||
---@param second T2
|
||||
---@return T1
|
||||
---@diagnostic disable-next-line: unused-local
|
||||
local function fst(first, second)
|
||||
return first
|
||||
end
|
||||
|
||||
---@generic T1, T2
|
||||
---@param first T1
|
||||
---@param second T2
|
||||
---@return T2
|
||||
---@diagnostic disable-next-line: unused-local
|
||||
local function snd(first, second)
|
||||
return second
|
||||
end
|
||||
|
||||
do
|
||||
local p, s1, s2, f = evo.id(4)
|
||||
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p, s1), 21)
|
||||
:set(evo.pair(p, s2), 42)
|
||||
:spawn()
|
||||
|
||||
assert(fst(evo.primary(e, s1)) == p)
|
||||
assert(snd(evo.primary(e, s1)) == 21)
|
||||
assert(fst(evo.primary(e, s2)) == p)
|
||||
assert(snd(evo.primary(e, s2)) == 42)
|
||||
assert(fst(evo.primary(e, s1, 1)) == p)
|
||||
assert(snd(evo.primary(e, s1, 1)) == 21)
|
||||
assert(fst(evo.primary(e, s2, 1)) == p)
|
||||
assert(snd(evo.primary(e, s2, 1)) == 42)
|
||||
assert(fst(evo.primary(e, s1, 2)) == nil)
|
||||
assert(snd(evo.primary(e, s1, 2)) == nil)
|
||||
assert(fst(evo.primary(e, s2, 2)) == nil)
|
||||
assert(snd(evo.primary(e, s2, 2)) == nil)
|
||||
|
||||
assert(fst(evo.primary(evo.pair(e, f), s1)) == p)
|
||||
assert(snd(evo.primary(evo.pair(e, f), s1)) == 21)
|
||||
assert(fst(evo.primary(evo.pair(e, f), s2)) == p)
|
||||
assert(snd(evo.primary(evo.pair(e, f), s2)) == 42)
|
||||
assert(fst(evo.primary(evo.pair(e, f), s1, 1)) == p)
|
||||
assert(snd(evo.primary(evo.pair(e, f), s1, 1)) == 21)
|
||||
assert(fst(evo.primary(evo.pair(e, f), s2, 1)) == p)
|
||||
assert(snd(evo.primary(evo.pair(e, f), s2, 1)) == 42)
|
||||
assert(fst(evo.primary(evo.pair(e, f), s1, 2)) == nil)
|
||||
assert(snd(evo.primary(evo.pair(e, f), s1, 2)) == nil)
|
||||
assert(fst(evo.primary(evo.pair(e, f), s2, 2)) == nil)
|
||||
assert(snd(evo.primary(evo.pair(e, f), s2, 2)) == nil)
|
||||
|
||||
assert(fst(evo.secondary(e, p)) == s1)
|
||||
assert(snd(evo.secondary(e, p)) == 21)
|
||||
assert(fst(evo.secondary(e, p, 1)) == s1)
|
||||
assert(snd(evo.secondary(e, p, 1)) == 21)
|
||||
assert(fst(evo.secondary(e, p, 2)) == s2)
|
||||
assert(snd(evo.secondary(e, p, 2)) == 42)
|
||||
assert(fst(evo.secondary(e, p, 3)) == nil)
|
||||
assert(snd(evo.secondary(e, p, 3)) == nil)
|
||||
|
||||
assert(fst(evo.secondary(evo.pair(e, f), p)) == s1)
|
||||
assert(snd(evo.secondary(evo.pair(e, f), p)) == 21)
|
||||
assert(fst(evo.secondary(evo.pair(e, f), p, 1)) == s1)
|
||||
assert(snd(evo.secondary(evo.pair(e, f), p, 1)) == 21)
|
||||
assert(fst(evo.secondary(evo.pair(e, f), p, 2)) == s2)
|
||||
assert(snd(evo.secondary(evo.pair(e, f), p, 2)) == 42)
|
||||
assert(fst(evo.secondary(evo.pair(e, f), p, 3)) == nil)
|
||||
assert(snd(evo.secondary(evo.pair(e, f), p, 3)) == nil)
|
||||
|
||||
assert(fst(evo.primary(evo.pair(f, e), s1)) == nil)
|
||||
assert(snd(evo.primary(evo.pair(f, e), s1)) == nil)
|
||||
assert(fst(evo.primary(evo.pair(f, e), s2)) == nil)
|
||||
assert(snd(evo.primary(evo.pair(f, e), s2)) == nil)
|
||||
assert(fst(evo.secondary(evo.pair(f, e), p)) == nil)
|
||||
assert(snd(evo.secondary(evo.pair(f, e), p)) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local p, s1, s2, f = evo.id(4)
|
||||
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p, s1), 21)
|
||||
:set(evo.pair(p, s2), 42)
|
||||
:spawn()
|
||||
|
||||
assert(evo.primary_count(e, p) == 0)
|
||||
assert(evo.primary_count(e, s1) == 1)
|
||||
assert(evo.primary_count(e, s2) == 1)
|
||||
assert(evo.secondary_count(e, p) == 2)
|
||||
assert(evo.secondary_count(e, s1) == 0)
|
||||
assert(evo.secondary_count(e, s2) == 0)
|
||||
|
||||
assert(evo.primary_count(evo.pair(e, f), p) == 0)
|
||||
assert(evo.primary_count(evo.pair(e, f), s1) == 1)
|
||||
assert(evo.primary_count(evo.pair(e, f), s2) == 1)
|
||||
assert(evo.secondary_count(evo.pair(e, f), p) == 2)
|
||||
assert(evo.secondary_count(evo.pair(e, f), s1) == 0)
|
||||
assert(evo.secondary_count(evo.pair(e, f), s2) == 0)
|
||||
|
||||
assert(evo.primary_count(evo.pair(f, e), p) == 0)
|
||||
assert(evo.primary_count(evo.pair(f, e), s1) == 0)
|
||||
assert(evo.primary_count(evo.pair(f, e), s2) == 0)
|
||||
assert(evo.secondary_count(evo.pair(f, e), p) == 0)
|
||||
assert(evo.secondary_count(evo.pair(f, e), s1) == 0)
|
||||
assert(evo.secondary_count(evo.pair(f, e), s2) == 0)
|
||||
end
|
||||
|
||||
do
|
||||
local p, s1, s2, f = evo.id(4)
|
||||
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p, s1), 21)
|
||||
:set(evo.pair(p, s2), 42)
|
||||
:spawn()
|
||||
|
||||
do
|
||||
local iter, state = evo.primaries(e, p)
|
||||
local fragment, component = iter(state)
|
||||
assert(fragment == nil and component == nil)
|
||||
|
||||
|
||||
iter, state = evo.primaries(evo.pair(e, f), p)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == nil and component == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local iter, state = evo.primaries(e, s1)
|
||||
local fragment, component = iter(state)
|
||||
assert(fragment == p and component == 21)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == nil and component == nil)
|
||||
|
||||
iter, state = evo.primaries(evo.pair(e, f), s1)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == p and component == 21)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == nil and component == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local iter, state = evo.primaries(e, s2)
|
||||
local fragment, component = iter(state)
|
||||
assert(fragment == p and component == 42)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == nil and component == nil)
|
||||
|
||||
iter, state = evo.primaries(evo.pair(e, f), s2)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == p and component == 42)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == nil and component == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p, s1, s2, f = evo.id(4)
|
||||
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p, s1), 21)
|
||||
:set(evo.pair(p, s2), 42)
|
||||
:spawn()
|
||||
|
||||
do
|
||||
local iter, state = evo.secondaries(e, s1)
|
||||
local fragment, component = iter(state)
|
||||
assert(fragment == nil and component == nil)
|
||||
|
||||
iter, state = evo.secondaries(evo.pair(e, f), s1)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == nil and component == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local iter, state = evo.secondaries(e, p)
|
||||
local fragment, component = iter(state)
|
||||
assert(fragment == s1 and component == 21)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == s2 and component == 42)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == nil and component == nil)
|
||||
|
||||
iter, state = evo.secondaries(evo.pair(e, f), p)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == s1 and component == 21)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == s2 and component == 42)
|
||||
fragment, component = iter(state)
|
||||
assert(fragment == nil and component == nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO
|
||||
-- builder:has/has_all/has_any should work with wildcards / remove too?
|
||||
-- should we provide wildcard support for get operations?
|
||||
|
||||
296
evolved.lua
296
evolved.lua
@@ -4681,15 +4681,14 @@ end
|
||||
---@nodiscard
|
||||
function __evolved_pack(index, version)
|
||||
if index < 1 or index > 2 ^ 20 - 1 then
|
||||
__error_fmt('id index (%d) is out of range [1, 2 ^ 20 - 1]', index)
|
||||
__error_fmt('the index (%d) is out of range [1, 2 ^ 20 - 1]', index)
|
||||
end
|
||||
|
||||
if version < 1 or version > 2 ^ 20 - 1 then
|
||||
__error_fmt('id version (%d) is out of range [1, 2 ^ 20 - 1]', version)
|
||||
__error_fmt('the version (%d) is out of range [1, 2 ^ 20 - 1]', version)
|
||||
end
|
||||
|
||||
return index
|
||||
+ version * 2 ^ 20 --[[@as evolved.id]]
|
||||
return index + version * 2 ^ 20 --[[@as evolved.id]]
|
||||
end
|
||||
|
||||
---@param id evolved.id
|
||||
@@ -4817,8 +4816,8 @@ function __evolved_alive(entity)
|
||||
return false
|
||||
end
|
||||
else
|
||||
local primary = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not primary or primary % 2 ^ 20 ~= entity_index then
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -4879,8 +4878,8 @@ function __evolved_empty(entity)
|
||||
return true
|
||||
end
|
||||
else
|
||||
local primary = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not primary or primary % 2 ^ 20 ~= entity_index then
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -4942,8 +4941,8 @@ function __evolved_has(entity, fragment)
|
||||
return false
|
||||
end
|
||||
else
|
||||
local primary = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not primary or primary % 2 ^ 20 ~= entity_index then
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -4971,8 +4970,8 @@ function __evolved_has_all(entity, ...)
|
||||
return false
|
||||
end
|
||||
else
|
||||
local primary = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not primary or primary % 2 ^ 20 ~= entity_index then
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -5000,8 +4999,8 @@ function __evolved_has_any(entity, ...)
|
||||
return false
|
||||
end
|
||||
else
|
||||
local primary = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not primary or primary % 2 ^ 20 ~= entity_index then
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -5023,8 +5022,8 @@ function __evolved_get(entity, ...)
|
||||
return
|
||||
end
|
||||
else
|
||||
local primary = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not primary or primary % 2 ^ 20 ~= entity_index then
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -5068,13 +5067,13 @@ function __evolved_set(entity, fragment, component)
|
||||
__error_fmt('the pair (%s) is a wildcard and cannot be set', __id_name(fragment))
|
||||
end
|
||||
|
||||
local primary = __freelist_ids[primary_index] --[[@as evolved.id?]]
|
||||
if not primary or primary % 2 ^ 20 ~= primary_index then
|
||||
local fragment_primary_id = __freelist_ids[primary_index] --[[@as evolved.id?]]
|
||||
if not fragment_primary_id or fragment_primary_id % 2 ^ 20 ~= primary_index then
|
||||
__error_fmt('the pair (%s) has no alive primary id and cannot be set', __id_name(fragment))
|
||||
end
|
||||
|
||||
local secondary = __freelist_ids[secondary_index] --[[@as evolved.id?]]
|
||||
if not secondary or secondary % 2 ^ 20 ~= secondary_index then
|
||||
local fragment_secondary_id = __freelist_ids[secondary_index] --[[@as evolved.id?]]
|
||||
if not fragment_secondary_id or fragment_secondary_id % 2 ^ 20 ~= secondary_index then
|
||||
__error_fmt('the pair (%s) has no alive secondary id and cannot be set', __id_name(fragment))
|
||||
end
|
||||
end
|
||||
@@ -5577,13 +5576,13 @@ function __evolved_batch_set(query, fragment, component)
|
||||
__error_fmt('the pair (%s) is a wildcard and cannot be set', __id_name(fragment))
|
||||
end
|
||||
|
||||
local primary = __freelist_ids[primary_index] --[[@as evolved.id?]]
|
||||
if not primary or primary % 2 ^ 20 ~= primary_index then
|
||||
local fragment_primary_id = __freelist_ids[primary_index] --[[@as evolved.id?]]
|
||||
if not fragment_primary_id or fragment_primary_id % 2 ^ 20 ~= primary_index then
|
||||
__error_fmt('the pair (%s) has no alive primary id and cannot be set', __id_name(fragment))
|
||||
end
|
||||
|
||||
local secondary = __freelist_ids[secondary_index] --[[@as evolved.id?]]
|
||||
if not secondary or secondary % 2 ^ 20 ~= secondary_index then
|
||||
local fragment_secondary_id = __freelist_ids[secondary_index] --[[@as evolved.id?]]
|
||||
if not fragment_secondary_id or fragment_secondary_id % 2 ^ 20 ~= secondary_index then
|
||||
__error_fmt('the pair (%s) has no alive secondary id and cannot be set', __id_name(fragment))
|
||||
end
|
||||
end
|
||||
@@ -6121,29 +6120,27 @@ end
|
||||
function __evolved_pair(primary, secondary)
|
||||
local primary_index, _, primary_options = __evolved_unpack(primary)
|
||||
if primary_options >= __PAIR_OPTS then
|
||||
__error_fmt('the primary id (%s) is a pair and cannot be used as a primary id of a pair',
|
||||
__error_fmt('the primary id (%s) is a pair and cannot be used as a primary id of a new pair',
|
||||
__id_name(primary))
|
||||
end
|
||||
|
||||
local secondary_index, _, secondary_options = __evolved_unpack(secondary)
|
||||
if secondary_options >= __PAIR_OPTS then
|
||||
__error_fmt('the secondary id (%s) is a pair and cannot be used as a secondary id of a pair',
|
||||
__error_fmt('the secondary id (%s) is a pair and cannot be used as a secondary id of a new pair',
|
||||
__id_name(secondary))
|
||||
end
|
||||
|
||||
local pair_options = __PAIR_OPTS
|
||||
|
||||
if primary == __ANY and secondary == __ANY then
|
||||
if primary_index == __ANY_INDEX and secondary_index == __ANY_INDEX then
|
||||
pair_options = __ANY_WILDCARD_OPTS
|
||||
elseif primary == __ANY then
|
||||
elseif primary_index == __ANY_INDEX then
|
||||
pair_options = __PRI_WILDCARD_OPTS
|
||||
elseif secondary == __ANY then
|
||||
elseif secondary_index == __ANY_INDEX then
|
||||
pair_options = __SEC_WILDCARD_OPTS
|
||||
end
|
||||
|
||||
return primary_index
|
||||
+ secondary_index * 2 ^ 20
|
||||
+ pair_options * 2 ^ 40 --[[@as evolved.pair]]
|
||||
return primary_index + secondary_index * 2 ^ 20 + pair_options * 2 ^ 40 --[[@as evolved.pair]]
|
||||
end
|
||||
|
||||
---@param pair evolved.pair
|
||||
@@ -6151,44 +6148,41 @@ end
|
||||
---@return evolved.id secondary
|
||||
---@nodiscard
|
||||
function __evolved_unpair(pair)
|
||||
local pair_primary, pair_secondary, pair_options = __evolved_unpack(pair)
|
||||
local primary_index, secondary_index, pair_options = __evolved_unpack(pair)
|
||||
|
||||
if pair_options < __PAIR_OPTS then
|
||||
__error_fmt('the id (%s) is not a pair and cannot be unpaired',
|
||||
__id_name(pair))
|
||||
__error_fmt('the id (%s) is not a pair and cannot be unpaired', __id_name(pair))
|
||||
end
|
||||
|
||||
local primary = __freelist_ids[pair_primary] --[[@as evolved.id?]]
|
||||
if not primary or primary % 2 ^ 20 ~= pair_primary then
|
||||
__error_fmt('the primary id of the pair (%s) is not alive and cannot be unpaired',
|
||||
__id_name(pair))
|
||||
local pair_primary_id = __freelist_ids[primary_index] --[[@as evolved.id?]]
|
||||
if not pair_primary_id or pair_primary_id % 2 ^ 20 ~= primary_index then
|
||||
__error_fmt('the pair (%s) has not alive primary id and cannot be unpaired', __id_name(pair))
|
||||
else
|
||||
---@cast primary -?
|
||||
---@cast pair_primary_id -?
|
||||
end
|
||||
|
||||
local secondary = __freelist_ids[pair_secondary] --[[@as evolved.id?]]
|
||||
if not secondary or secondary % 2 ^ 20 ~= pair_secondary then
|
||||
__error_fmt('the secondary id of the pair (%s) is not alive and cannot be unpaired',
|
||||
__id_name(pair))
|
||||
local pair_secondary_id = __freelist_ids[secondary_index] --[[@as evolved.id?]]
|
||||
if not pair_secondary_id or pair_secondary_id % 2 ^ 20 ~= secondary_index then
|
||||
__error_fmt('the pair (%s) has not alive secondary id and cannot be unpaired', __id_name(pair))
|
||||
else
|
||||
---@cast secondary -?
|
||||
---@cast pair_secondary_id -?
|
||||
end
|
||||
|
||||
return primary, secondary
|
||||
return pair_primary_id, pair_secondary_id
|
||||
end
|
||||
|
||||
---@param id evolved.id
|
||||
---@return boolean
|
||||
---@nodiscard
|
||||
function __evolved_is_pair(id)
|
||||
return id % 2 ^ 41 >= 2 ^ 40
|
||||
return id >= __PAIR_OPTS * 2 ^ 40
|
||||
end
|
||||
|
||||
---@param id evolved.id
|
||||
---@return boolean
|
||||
---@nodiscard
|
||||
function __evolved_is_wildcard(id)
|
||||
return id % 2 ^ 43 >= 2 ^ 41
|
||||
return id >= __PRI_WILDCARD_OPTS * 2 ^ 40
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
@@ -6200,22 +6194,32 @@ end
|
||||
function __evolved_primary(entity, secondary, index)
|
||||
index = index or 1
|
||||
|
||||
if __evolved_is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
local entity_index, _, entity_options = __evolved_unpack(entity)
|
||||
|
||||
if entity_options < __PAIR_OPTS then
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return
|
||||
end
|
||||
else
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local entity_chunk = __entity_chunks[entity_index]
|
||||
|
||||
if not entity_chunk then
|
||||
return
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
local secondary_index, _, secondary_options = __evolved_unpack(secondary)
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
-- non-alive entities do not have any fragments
|
||||
return
|
||||
if secondary_options >= __PAIR_OPTS then
|
||||
__error_fmt('the pair (%s) cannot be used as a secondary fragment', __id_name(secondary))
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
local place = __entity_places[entity_index]
|
||||
|
||||
local secondary_fragments = chunk and chunk.__secondary_pairs[secondary % 2 ^ 20]
|
||||
local secondary_fragments = entity_chunk.__secondary_pairs[secondary_index]
|
||||
local secondary_fragment_list = secondary_fragments and secondary_fragments.__item_list
|
||||
local secondary_fragment_count = secondary_fragments and secondary_fragments.__item_count or 0
|
||||
|
||||
@@ -6226,10 +6230,11 @@ function __evolved_primary(entity, secondary, index)
|
||||
local secondary_fragment = secondary_fragment_list[index]
|
||||
local primary, _ = __evolved_unpair(secondary_fragment)
|
||||
|
||||
local component_index = chunk.__component_indices[secondary_fragment]
|
||||
local component_storage = chunk.__component_storages[component_index]
|
||||
local component_index = entity_chunk.__component_indices[secondary_fragment]
|
||||
local component_storage = entity_chunk.__component_storages[component_index]
|
||||
|
||||
return primary, component_storage and component_storage[place]
|
||||
local entity_place = __entity_places[entity_index]
|
||||
return primary, component_storage and component_storage[entity_place]
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
@@ -6241,22 +6246,32 @@ end
|
||||
function __evolved_secondary(entity, primary, index)
|
||||
index = index or 1
|
||||
|
||||
if __evolved_is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
local entity_index, _, entity_options = __evolved_unpack(entity)
|
||||
|
||||
if entity_options < __PAIR_OPTS then
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return
|
||||
end
|
||||
else
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local entity_chunk = __entity_chunks[entity_index]
|
||||
|
||||
if not entity_chunk then
|
||||
return
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
local primary_index, _, primary_options = __evolved_unpack(primary)
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
-- non-alive entities do not have any fragments
|
||||
return
|
||||
if primary_options >= __PAIR_OPTS then
|
||||
__error_fmt('the pair (%s) cannot be used as a primary fragment', __id_name(primary))
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
local place = __entity_places[entity_index]
|
||||
|
||||
local primary_fragments = chunk and chunk.__primary_pairs[primary % 2 ^ 20]
|
||||
local primary_fragments = entity_chunk.__primary_pairs[primary_index]
|
||||
local primary_fragment_list = primary_fragments and primary_fragments.__item_list
|
||||
local primary_fragment_count = primary_fragments and primary_fragments.__item_count or 0
|
||||
|
||||
@@ -6267,10 +6282,11 @@ function __evolved_secondary(entity, primary, index)
|
||||
local primary_fragment = primary_fragment_list[index]
|
||||
local _, secondary = __evolved_unpair(primary_fragment)
|
||||
|
||||
local component_index = chunk.__component_indices[primary_fragment]
|
||||
local component_storage = chunk.__component_storages[component_index]
|
||||
local component_index = entity_chunk.__component_indices[primary_fragment]
|
||||
local component_storage = entity_chunk.__component_storages[component_index]
|
||||
|
||||
return secondary, component_storage and component_storage[place]
|
||||
local entity_place = __entity_places[entity_index]
|
||||
return secondary, component_storage and component_storage[entity_place]
|
||||
end
|
||||
|
||||
---@param entity evolved.entity
|
||||
@@ -6279,26 +6295,34 @@ end
|
||||
---@return evolved.primaries_state? iterator_state
|
||||
---@nodiscard
|
||||
function __evolved_primaries(entity, secondary)
|
||||
if __evolved_is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
local entity_index, _, entity_options = __evolved_unpack(entity)
|
||||
|
||||
if entity_options < __PAIR_OPTS then
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return __iterator_fns.__primaries_iterator
|
||||
end
|
||||
else
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return __iterator_fns.__primaries_iterator
|
||||
end
|
||||
end
|
||||
|
||||
local entity_chunk = __entity_chunks[entity_index]
|
||||
|
||||
if not entity_chunk then
|
||||
return __iterator_fns.__primaries_iterator
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
local secondary_index, _, secondary_options = __evolved_unpack(secondary)
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
-- non-alive entities do not have any fragments
|
||||
return __iterator_fns.__primaries_iterator
|
||||
if secondary_options >= __PAIR_OPTS then
|
||||
__error_fmt('the pair (%s) cannot be used as a secondary fragment', __id_name(secondary))
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
local place = __entity_places[entity_index]
|
||||
|
||||
local secondary_index = secondary % 2 ^ 20
|
||||
local secondary_fragments = chunk and chunk.__secondary_pairs[secondary_index]
|
||||
local secondary_fragments = entity_chunk.__secondary_pairs[secondary_index]
|
||||
|
||||
if not secondary_fragments or secondary_fragments.__item_count == 0 then
|
||||
-- no primaries for this secondary
|
||||
return __iterator_fns.__primaries_iterator
|
||||
end
|
||||
|
||||
@@ -6306,8 +6330,8 @@ function __evolved_primaries(entity, secondary)
|
||||
local primaries_state = __acquire_table(__table_pool_tag.primaries_state)
|
||||
|
||||
primaries_state[1] = __structural_changes
|
||||
primaries_state[2] = chunk
|
||||
primaries_state[3] = place
|
||||
primaries_state[2] = entity_chunk
|
||||
primaries_state[3] = __entity_places[entity_index]
|
||||
primaries_state[4] = secondary_index
|
||||
primaries_state[5] = 1
|
||||
|
||||
@@ -6320,26 +6344,34 @@ end
|
||||
---@return evolved.secondaries_state? iterator_state
|
||||
---@nodiscard
|
||||
function __evolved_secondaries(entity, primary)
|
||||
if __evolved_is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
local entity_index, _, entity_options = __evolved_unpack(entity)
|
||||
|
||||
if entity_options < __PAIR_OPTS then
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return __iterator_fns.__secondaries_iterator
|
||||
end
|
||||
else
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return __iterator_fns.__secondaries_iterator
|
||||
end
|
||||
end
|
||||
|
||||
local entity_chunk = __entity_chunks[entity_index]
|
||||
|
||||
if not entity_chunk then
|
||||
return __iterator_fns.__secondaries_iterator
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
local primary_index, _, primary_options = __evolved_unpack(primary)
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
-- non-alive entities do not have any fragments
|
||||
return __iterator_fns.__secondaries_iterator
|
||||
if primary_options >= __PAIR_OPTS then
|
||||
__error_fmt('the pair (%s) cannot be used as a primary fragment', __id_name(primary))
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
local place = __entity_places[entity_index]
|
||||
|
||||
local primary_index = primary % 2 ^ 20
|
||||
local primary_fragments = chunk and chunk.__primary_pairs[primary_index]
|
||||
local primary_fragments = entity_chunk.__primary_pairs[primary_index]
|
||||
|
||||
if not primary_fragments or primary_fragments.__item_count == 0 then
|
||||
-- no secondaries for this primary
|
||||
return __iterator_fns.__secondaries_iterator
|
||||
end
|
||||
|
||||
@@ -6347,8 +6379,8 @@ function __evolved_secondaries(entity, primary)
|
||||
local secondaries_state = __acquire_table(__table_pool_tag.secondaries_state)
|
||||
|
||||
secondaries_state[1] = __structural_changes
|
||||
secondaries_state[2] = chunk
|
||||
secondaries_state[3] = place
|
||||
secondaries_state[2] = entity_chunk
|
||||
secondaries_state[3] = __entity_places[entity_index]
|
||||
secondaries_state[4] = primary_index
|
||||
secondaries_state[5] = 1
|
||||
|
||||
@@ -6360,22 +6392,32 @@ end
|
||||
---@return integer
|
||||
---@nodiscard
|
||||
function __evolved_primary_count(entity, secondary)
|
||||
if __evolved_is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
local entity_index, _, entity_options = __evolved_unpack(entity)
|
||||
|
||||
if entity_options < __PAIR_OPTS then
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return 0
|
||||
end
|
||||
else
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
local entity_chunk = __entity_chunks[entity_index]
|
||||
|
||||
if not entity_chunk then
|
||||
return 0
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
local secondary_index, _, secondary_options = __evolved_unpack(secondary)
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
-- non-alive entities do not have any fragments
|
||||
return 0
|
||||
if secondary_options >= __PAIR_OPTS then
|
||||
__error_fmt('the pair (%s) cannot be used as a secondary fragment', __id_name(secondary))
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
|
||||
local secondary_index = secondary % 2 ^ 20
|
||||
local secondary_fragments = chunk and chunk.__secondary_pairs[secondary_index]
|
||||
local secondary_fragments = entity_chunk.__secondary_pairs[secondary_index]
|
||||
|
||||
return secondary_fragments and secondary_fragments.__item_count or 0
|
||||
end
|
||||
@@ -6385,22 +6427,32 @@ end
|
||||
---@return integer
|
||||
---@nodiscard
|
||||
function __evolved_secondary_count(entity, primary)
|
||||
if __evolved_is_pair(entity) then
|
||||
-- pairs are always empty
|
||||
local entity_index, _, entity_options = __evolved_unpack(entity)
|
||||
|
||||
if entity_options < __PAIR_OPTS then
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
return 0
|
||||
end
|
||||
else
|
||||
local entity_primary_id = __freelist_ids[entity_index] --[[@as evolved.id?]]
|
||||
if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_index then
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
local entity_chunk = __entity_chunks[entity_index]
|
||||
|
||||
if not entity_chunk then
|
||||
return 0
|
||||
end
|
||||
|
||||
local entity_index = entity % 2 ^ 20
|
||||
local primary_index, _, primary_options = __evolved_unpack(primary)
|
||||
|
||||
if __freelist_ids[entity_index] ~= entity then
|
||||
-- non-alive entities do not have any fragments
|
||||
return 0
|
||||
if primary_options >= __PAIR_OPTS then
|
||||
__error_fmt('the pair (%s) cannot be used as a primary fragment', __id_name(primary))
|
||||
end
|
||||
|
||||
local chunk = __entity_chunks[entity_index]
|
||||
|
||||
local primary_index = primary % 2 ^ 20
|
||||
local primary_fragments = chunk and chunk.__primary_pairs[primary_index]
|
||||
local primary_fragments = entity_chunk.__primary_pairs[primary_index]
|
||||
|
||||
return primary_fragments and primary_fragments.__item_count or 0
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user