diff --git a/develop/testing/pairs_tests.lua b/develop/testing/pairs_tests.lua index 932c0ec..f156fce 100644 --- a/develop/testing/pairs_tests.lua +++ b/develop/testing/pairs_tests.lua @@ -1723,43 +1723,26 @@ do 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)) == nil) + assert(fst(evo.primary(evo.pair(e, f), s2)) == nil) + assert(fst(evo.primary(evo.pair(e, f), s1, 1)) == nil) + assert(fst(evo.primary(evo.pair(e, f), s2, 1)) == nil) 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)) == nil) + assert(fst(evo.secondary(evo.pair(e, f), p, 1)) == nil) + assert(fst(evo.secondary(evo.pair(e, f), p, 2)) == nil) 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 @@ -1778,9 +1761,9 @@ do 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.primary_count(evo.pair(e, f), s1) == 0) + assert(evo.primary_count(evo.pair(e, f), s2) == 0) + assert(evo.secondary_count(evo.pair(e, f), p) == 0) assert(evo.secondary_count(evo.pair(e, f), s1) == 0) assert(evo.secondary_count(evo.pair(e, f), s2) == 0) @@ -1820,8 +1803,6 @@ do 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 @@ -1834,8 +1815,6 @@ do 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 @@ -1869,10 +1848,6 @@ do 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 @@ -1936,26 +1911,9 @@ do assert(not evo.has(e, evo.pair(p, s1)) and evo.get(e, evo.pair(p, s1)) == nil) assert(not evo.has(e, evo.pair(p, s2)) and evo.get(e, evo.pair(p, s2)) == nil) end - - do - local p, s = evo.id(2) - - evo.destroy(s) - - evo.debug_mode(false) - - local e = evo.spawn { - [evo.pair(p, s)] = 21, - } - - evo.debug_mode(true) - - assert(evo.has(e, evo.pair(p, s)) and evo.get(e, evo.pair(p, s)) == 21) - end end -- TODO --- builder:has/has_all/has_any should work with wildcards / remove too? -- should we provide wildcard support for get operations? -- prevent setting pairs with dead secondary fragments -- process evo.ANY as single wildcard diff --git a/evolved.lua b/evolved.lua index 61789e3..3a658cb 100644 --- a/evolved.lua +++ b/evolved.lua @@ -1373,8 +1373,34 @@ local __update_major_chunks_trace ---@return evolved.chunk ---@nodiscard function __new_chunk(chunk_parent, chunk_fragment) - if chunk_fragment >= __PRI_WILDCARD_OPTIONS * 2 ^ 40 then - __error_fmt('chunk cannot contain wildcard fragments') + local chunk_fragment_primary, chunk_fragment_secondary, chunk_fragment_options = + __evolved_unpack(chunk_fragment) + + if chunk_fragment_options < __PAIR_OPTIONS then + if chunk_fragment_primary == __ANY_INDEX then + __error_fmt('the id (%s) is a wildcard and cannot be used for a new chunk', + __universal_name(chunk_fragment)) + elseif __freelist_ids[chunk_fragment_primary] ~= chunk_fragment then + __error_fmt('the id (%s) is not alive and cannot be used for a new chunk', + __universal_name(chunk_fragment)) + end + else + if chunk_fragment_options >= __PRI_WILDCARD_OPTIONS then + __error_fmt('the pair (%s) is a wildcard and cannot be used for a new chunk', + __universal_name(chunk_fragment)) + end + + local fragment_primary_id = __freelist_ids[chunk_fragment_primary] --[[@as evolved.id?]] + if not fragment_primary_id or fragment_primary_id % 2 ^ 20 ~= chunk_fragment_primary then + __error_fmt('the pair (%s) has no alive primary id and cannot be used for a new chunk', + __universal_name(chunk_fragment)) + end + + local fragment_secondary_id = __freelist_ids[chunk_fragment_secondary] --[[@as evolved.id?]] + if not fragment_secondary_id or fragment_secondary_id % 2 ^ 20 ~= chunk_fragment_secondary then + __error_fmt('the pair (%s) has no alive secondary id and cannot be used for a new chunk', + __universal_name(chunk_fragment)) + end end local chunk_fragment_set = {} ---@type table @@ -1427,9 +1453,6 @@ function __new_chunk(chunk_parent, chunk_fragment) chunk_pair_count = chunk_pair_count + 1 chunk_pair_list[chunk_pair_count] = chunk_fragment - local chunk_fragment_primary, chunk_fragment_secondary = - __evolved_unpack(chunk_fragment) - local chunk_primary_fragments = chunk_primary_pairs[chunk_fragment_primary] local chunk_secondary_fragments = chunk_secondary_pairs[chunk_fragment_secondary] @@ -6352,15 +6375,12 @@ function __evolved_primary(entity, secondary, index) local entity_primary, _, entity_options = __evolved_unpack(entity) - if entity_options < __PAIR_OPTIONS then - if __freelist_ids[entity_primary] ~= entity then - return - end - else - local entity_primary_id = __freelist_ids[entity_primary] --[[@as evolved.id?]] - if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_primary then - return - end + if entity_options >= __PAIR_OPTIONS then + return + end + + if __freelist_ids[entity_primary] ~= entity then + return end local entity_chunk = __entity_chunks[entity_primary] @@ -6405,15 +6425,12 @@ function __evolved_secondary(entity, primary, index) local entity_primary, _, entity_options = __evolved_unpack(entity) - if entity_options < __PAIR_OPTIONS then - if __freelist_ids[entity_primary] ~= entity then - return - end - else - local entity_primary_id = __freelist_ids[entity_primary] --[[@as evolved.id?]] - if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_primary then - return - end + if entity_options >= __PAIR_OPTIONS then + return + end + + if __freelist_ids[entity_primary] ~= entity then + return end local entity_chunk = __entity_chunks[entity_primary] @@ -6455,15 +6472,12 @@ end function __evolved_primaries(entity, secondary) local entity_primary, _, entity_options = __evolved_unpack(entity) - if entity_options < __PAIR_OPTIONS then - if __freelist_ids[entity_primary] ~= entity then - return __iterator_fns.__primaries_iterator - end - else - local entity_primary_id = __freelist_ids[entity_primary] --[[@as evolved.id?]] - if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_primary then - return __iterator_fns.__primaries_iterator - end + if entity_options >= __PAIR_OPTIONS then + return __iterator_fns.__primaries_iterator + end + + if __freelist_ids[entity_primary] ~= entity then + return __iterator_fns.__primaries_iterator end local entity_chunk = __entity_chunks[entity_primary] @@ -6505,15 +6519,12 @@ end function __evolved_secondaries(entity, primary) local entity_primary, _, entity_options = __evolved_unpack(entity) - if entity_options < __PAIR_OPTIONS then - if __freelist_ids[entity_primary] ~= entity then - return __iterator_fns.__secondaries_iterator - end - else - local entity_primary_id = __freelist_ids[entity_primary] --[[@as evolved.id?]] - if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_primary then - return __iterator_fns.__secondaries_iterator - end + if entity_options >= __PAIR_OPTIONS then + return __iterator_fns.__secondaries_iterator + end + + if __freelist_ids[entity_primary] ~= entity then + return __iterator_fns.__secondaries_iterator end local entity_chunk = __entity_chunks[entity_primary] @@ -6554,15 +6565,12 @@ end function __evolved_primary_count(entity, secondary) local entity_primary, _, entity_options = __evolved_unpack(entity) - if entity_options < __PAIR_OPTIONS then - if __freelist_ids[entity_primary] ~= entity then - return 0 - end - else - local entity_primary_id = __freelist_ids[entity_primary] --[[@as evolved.id?]] - if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_primary then - return 0 - end + if entity_options >= __PAIR_OPTIONS then + return 0 + end + + if __freelist_ids[entity_primary] ~= entity then + return 0 end local entity_chunk = __entity_chunks[entity_primary] @@ -6590,15 +6598,12 @@ end function __evolved_secondary_count(entity, primary) local entity_primary, _, entity_options = __evolved_unpack(entity) - if entity_options < __PAIR_OPTIONS then - if __freelist_ids[entity_primary] ~= entity then - return 0 - end - else - local entity_primary_id = __freelist_ids[entity_primary] --[[@as evolved.id?]] - if not entity_primary_id or entity_primary_id % 2 ^ 20 ~= entity_primary then - return 0 - end + if entity_options >= __PAIR_OPTIONS then + return 0 + end + + if __freelist_ids[entity_primary] ~= entity then + return 0 end local entity_chunk = __entity_chunks[entity_primary]