debug mode for pack/unpack and pair/unpair

This commit is contained in:
BlackMATov
2025-08-26 05:42:04 +07:00
parent 71a7d382c1
commit 12beee6eec
4 changed files with 98 additions and 55 deletions

View File

@@ -19,15 +19,3 @@ for _ = 1, 1000 do
assert(initial_secondary == unpacked_secondary)
assert(0 == unpacked_options)
end
for _ = 1, 1000 do
local initial_primary = math.random(1, 2 ^ 31 - 1)
local initial_secondary = math.random(1, 2 ^ 31 - 1)
local packed_id = evo.pack(initial_primary, initial_secondary)
local unpacked_primary, unpacked_secondary, unpacked_options = evo.unpack(packed_id)
assert(initial_primary % 2 ^ 20 == unpacked_primary)
assert(initial_secondary % 2 ^ 20 == unpacked_secondary)
assert(0 == unpacked_options)
end

View File

@@ -180,9 +180,20 @@ for _ = 1, math.random(1, 100) do
for fragment in evo.each(entity) do
if evo.has(fragment, evo.EXPLICIT) then
local is_fragment_included =
query_include_set[fragment] ~= nil or
query_include_set[evo.pair(fragment, evo.ANY)] ~= nil
local is_fragment_included = false
if not is_fragment_included then
is_fragment_included = query_include_set[fragment] ~= nil
end
if not is_fragment_included and evo.is_pair(fragment) then
local fragment_primary = evo.unpair(fragment)
is_fragment_included = query_include_set[evo.pair(fragment_primary, evo.ANY)] ~= nil
end
if not is_fragment_included and not evo.is_pair(fragment) then
is_fragment_included = query_include_set[evo.pair(fragment, evo.ANY)] ~= nil
end
if not is_fragment_included then
is_entity_expected = false

View File

@@ -1,10 +1,28 @@
local evo = require 'evolved'
do
local p1, s1 = evo.id(2)
local pair1 = evo.pair(p1, s1)
local p2, s2 = evo.unpair(pair1)
assert(p1 == p2 and s1 == s2)
do
local p, s = evo.unpair(evo.pair(evo.ANY, evo.ANY))
assert(p == evo.ANY and s == evo.ANY)
end
do
local f = evo.id()
local p, s = evo.unpair(evo.pair(evo.ANY, f))
assert(p == evo.ANY and s == f)
end
do
local f = evo.id()
local p, s = evo.unpair(evo.pair(f, evo.ANY))
assert(p == f and s == evo.ANY)
end
do
local fp, fs = evo.id(2)
local p, s = evo.unpair(evo.pair(fp, fs))
assert(p == fp and s == fs)
end
end
do
@@ -1617,4 +1635,3 @@ end
-- process evo.ANY as single wildcard
-- should we provide an evolved.pair type?
-- how should the destroy function handle pairs?
-- add debug mode for pack/unpack and pair/unpair

View File

@@ -948,7 +948,9 @@ local __component_storage
---@return string
---@nodiscard
function __id_name(id)
if not __evolved_is_pair(id) then
local id_primary, id_secondary, id_options = __evolved_unpack(id)
if id_options < __PAIR_OPTS then
---@type string?
local id_name = __evolved_get(id, __NAME)
@@ -956,27 +958,24 @@ function __id_name(id)
return id_name
end
else
local id_primary_index, id_secondary_index = __evolved_unpack(id)
---@type string?, string?
local pair_primary_id_name, pair_secondary_id_name
local id_primary = __freelist_ids[id_primary_index] --[[@as evolved.id?]]
local id_secondary = __freelist_ids[id_secondary_index] --[[@as evolved.id?]]
local id_primary_name, id_secondary_name
if id_primary and id_primary % 2 ^ 20 == id_primary_index then
id_primary_name = __id_name(id_primary)
local pair_primary_id = __freelist_ids[id_primary] --[[@as evolved.id?]]
if pair_primary_id and pair_primary_id % 2 ^ 20 == id_primary then
pair_primary_id_name = __id_name(pair_primary_id)
end
if id_secondary and id_secondary % 2 ^ 20 == id_secondary_index then
id_secondary_name = __id_name(id_secondary)
local pair_secondary_id = __freelist_ids[id_secondary] --[[@as evolved.id?]]
if pair_secondary_id and pair_secondary_id % 2 ^ 20 == id_secondary then
pair_secondary_id_name = __id_name(pair_secondary_id)
end
if id_primary_name and id_secondary_name then
return __lua_string_format('${%s,%s}', id_primary_name, id_secondary_name)
if pair_primary_id_name and pair_secondary_id_name then
return __lua_string_format('${%s,%s}', pair_primary_id_name, pair_secondary_id_name)
end
end
local id_primary, id_secondary, id_options = __evolved_unpack(id)
return __lua_string_format('$%d#%d:%d:%d', id, id_primary, id_secondary, id_options)
end
@@ -4683,8 +4682,16 @@ end
---@return evolved.id id
---@nodiscard
function __evolved_pack(index, version)
return index % 2 ^ 20
+ version % 2 ^ 20 * 2 ^ 20 --[[@as evolved.id]]
if index < 1 or index > 2 ^ 20 - 1 then
__error_fmt('index (%d) is out of range [1, 2 ^ 20 - 1]', index)
end
if version < 1 or version > 2 ^ 20 - 1 then
__error_fmt('version (%d) is out of range [1, 2 ^ 20 - 1]', version)
end
return index
+ version * 2 ^ 20 --[[@as evolved.id]]
end
---@param id evolved.id
@@ -6117,19 +6124,31 @@ end
---@return evolved.pair pair
---@nodiscard
function __evolved_pair(primary, secondary)
local options = __PAIR_OPTS
if primary == __ANY and secondary == __ANY then
options = __ANY_WILDCARD_OPTS
elseif primary == __ANY then
options = __PRI_WILDCARD_OPTS
elseif secondary == __ANY then
options = __SEC_WILDCARD_OPTS
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',
__id_name(primary))
end
return primary % 2 ^ 20
+ secondary % 2 ^ 20 * 2 ^ 20
+ options * 2 ^ 40 --[[@as evolved.pair]]
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',
__id_name(secondary))
end
local pair_options = __PAIR_OPTS
if primary == __ANY and secondary == __ANY then
pair_options = __ANY_WILDCARD_OPTS
elseif primary == __ANY then
pair_options = __PRI_WILDCARD_OPTS
elseif secondary == __ANY then
pair_options = __SEC_WILDCARD_OPTS
end
return primary_index
+ secondary_index * 2 ^ 20
+ pair_options * 2 ^ 40 --[[@as evolved.pair]]
end
---@param pair evolved.pair
@@ -6137,19 +6156,27 @@ end
---@return evolved.id secondary
---@nodiscard
function __evolved_unpair(pair)
local primary_index = pair % 2 ^ 20
local secondary_index = (pair - primary_index) / 2 ^ 20 % 2 ^ 20
local pair_primary, pair_secondary, pair_options = __evolved_unpack(pair)
local primary = __freelist_ids[primary_index] --[[@as evolved.id]]
if not primary or primary % 2 ^ 20 ~= primary_index then
__error_fmt('the primary fragment of the pair (%s) is not alive and cannot be unpaired',
if pair_options < __PAIR_OPTS then
__error_fmt('the id (%s) is not a pair and cannot be unpaired',
__id_name(pair))
end
local secondary = __freelist_ids[secondary_index] --[[@as evolved.id]]
if not secondary or secondary % 2 ^ 20 ~= secondary_index then
__error_fmt('the secondary fragment of the pair (%s) is not alive and cannot be unpaired',
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))
else
---@cast primary -?
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))
else
---@cast secondary -?
end
return primary, secondary