mirror of
https://github.com/BlackMATov/evolved.lua.git
synced 2025-12-15 12:19:47 +07:00
proof of concept chunk_without for pair wildcards
This commit is contained in:
@@ -99,3 +99,315 @@ do
|
||||
assert(evo.get(evo.pair(p1, s1), p1) == nil)
|
||||
assert(evo.get(evo.pair(p1, s1), s1) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local p, s1, s2 = evo.id(3)
|
||||
|
||||
do
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p, s1), 21)
|
||||
:set(evo.pair(p, s2), 42)
|
||||
:spawn()
|
||||
|
||||
evo.remove(e, evo.pair(p, s1))
|
||||
|
||||
assert(not evo.has(e, evo.pair(p, s1)))
|
||||
assert(evo.get(e, evo.pair(p, s1)) == nil)
|
||||
|
||||
assert(evo.has(e, evo.pair(p, s2)))
|
||||
assert(evo.get(e, evo.pair(p, s2)) == 42)
|
||||
|
||||
evo.remove(e, evo.pair(p, s2))
|
||||
|
||||
assert(not evo.has(e, evo.pair(p, s2)))
|
||||
assert(evo.get(e, evo.pair(p, s2)) == nil)
|
||||
|
||||
assert(not evo.has(e, evo.pair(p, s2)))
|
||||
assert(evo.get(e, evo.pair(p, s2)) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p, s1), 21)
|
||||
:set(evo.pair(p, s2), 42)
|
||||
:spawn()
|
||||
|
||||
evo.remove(e, evo.pair(p, s2))
|
||||
|
||||
assert(evo.has(e, evo.pair(p, s1)))
|
||||
assert(evo.get(e, evo.pair(p, s1)) == 21)
|
||||
|
||||
assert(not evo.has(e, evo.pair(p, s2)))
|
||||
assert(evo.get(e, evo.pair(p, s2)) == nil)
|
||||
|
||||
evo.remove(e, evo.pair(p, s1))
|
||||
|
||||
assert(not evo.has(e, evo.pair(p, s1)))
|
||||
assert(evo.get(e, evo.pair(p, s1)) == nil)
|
||||
|
||||
assert(not evo.has(e, evo.pair(p, s2)))
|
||||
assert(evo.get(e, evo.pair(p, s2)) == nil)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p1, p2, s1, s2 = evo.id(4)
|
||||
|
||||
do
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p1, s1), 11)
|
||||
:set(evo.pair(p1, s2), 12)
|
||||
:set(evo.pair(p2, s1), 21)
|
||||
:set(evo.pair(p2, s2), 22)
|
||||
:spawn()
|
||||
|
||||
evo.remove(e, evo.pair(p1, evo.ANY))
|
||||
|
||||
assert(not evo.has(e, evo.pair(p1, s1)))
|
||||
assert(not evo.has(e, evo.pair(p1, s2)))
|
||||
assert(not evo.has(e, evo.pair(p1, evo.ANY)))
|
||||
|
||||
assert(evo.has(e, evo.pair(p2, s1)))
|
||||
assert(evo.get(e, evo.pair(p2, s1)) == 21)
|
||||
assert(evo.has(e, evo.pair(p2, s2)))
|
||||
assert(evo.get(e, evo.pair(p2, s2)) == 22)
|
||||
assert(evo.has(e, evo.pair(p2, evo.ANY)))
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p1, s1), 11)
|
||||
:set(evo.pair(p1, s2), 12)
|
||||
:set(evo.pair(p2, s1), 21)
|
||||
:set(evo.pair(p2, s2), 22)
|
||||
:spawn()
|
||||
|
||||
evo.remove(e, evo.pair(p2, evo.ANY))
|
||||
|
||||
assert(not evo.has(e, evo.pair(p2, s1)))
|
||||
assert(not evo.has(e, evo.pair(p2, s2)))
|
||||
assert(not evo.has(e, evo.pair(p2, evo.ANY)))
|
||||
|
||||
assert(evo.has(e, evo.pair(p1, s1)))
|
||||
assert(evo.get(e, evo.pair(p1, s1)) == 11)
|
||||
assert(evo.has(e, evo.pair(p1, s2)))
|
||||
assert(evo.get(e, evo.pair(p1, s2)) == 12)
|
||||
assert(evo.has(e, evo.pair(p1, evo.ANY)))
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p1, s1), 11)
|
||||
:set(evo.pair(p1, s2), 12)
|
||||
:set(evo.pair(p2, s1), 21)
|
||||
:set(evo.pair(p2, s2), 22)
|
||||
:spawn()
|
||||
|
||||
evo.remove(e, evo.pair(evo.ANY, s1))
|
||||
|
||||
assert(not evo.has(e, evo.pair(p1, s1)))
|
||||
assert(not evo.has(e, evo.pair(p2, s1)))
|
||||
assert(not evo.has(e, evo.pair(evo.ANY, s1)))
|
||||
|
||||
assert(evo.has(e, evo.pair(p1, s2)))
|
||||
assert(evo.get(e, evo.pair(p1, s2)) == 12)
|
||||
assert(evo.has(e, evo.pair(p2, s2)))
|
||||
assert(evo.get(e, evo.pair(p2, s2)) == 22)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p1, s1), 11)
|
||||
:set(evo.pair(p1, s2), 12)
|
||||
:set(evo.pair(p2, s1), 21)
|
||||
:set(evo.pair(p2, s2), 22)
|
||||
:spawn()
|
||||
|
||||
evo.remove(e, evo.pair(evo.ANY, s2))
|
||||
|
||||
assert(not evo.has(e, evo.pair(p1, s2)))
|
||||
assert(not evo.has(e, evo.pair(p2, s2)))
|
||||
assert(not evo.has(e, evo.pair(evo.ANY, s2)))
|
||||
|
||||
assert(evo.has(e, evo.pair(p1, s1)))
|
||||
assert(evo.get(e, evo.pair(p1, s1)) == 11)
|
||||
assert(evo.has(e, evo.pair(p2, s1)))
|
||||
assert(evo.get(e, evo.pair(p2, s1)) == 21)
|
||||
end
|
||||
|
||||
do
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p1, s1), 11)
|
||||
:set(evo.pair(p1, s2), 12)
|
||||
:set(evo.pair(p2, s1), 21)
|
||||
:set(evo.pair(p2, s2), 22)
|
||||
:set(p1, s1)
|
||||
:set(p2, s2)
|
||||
:spawn()
|
||||
|
||||
evo.remove(e, evo.pair(evo.ANY, evo.ANY))
|
||||
|
||||
assert(not evo.has(e, evo.pair(p1, s1)))
|
||||
assert(not evo.has(e, evo.pair(p1, s2)))
|
||||
assert(not evo.has(e, evo.pair(p2, s1)))
|
||||
assert(not evo.has(e, evo.pair(p2, s2)))
|
||||
|
||||
assert(evo.has(e, p1) and evo.get(e, p1) == s1)
|
||||
assert(evo.has(e, p2) and evo.get(e, p2) == s2)
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local p1, s1, p2, s2 = evo.id(4)
|
||||
|
||||
local e = evo.builder()
|
||||
:set(evo.pair(p1, s1), 42)
|
||||
:spawn()
|
||||
|
||||
evo.remove(e, evo.pair(p2, evo.ANY))
|
||||
evo.remove(e, evo.pair(evo.ANY, s2))
|
||||
|
||||
assert(evo.has(e, evo.pair(p1, s1)))
|
||||
assert(evo.get(e, evo.pair(p1, s1)) == 42)
|
||||
|
||||
evo.remove(e, evo.pair(p1, s1))
|
||||
|
||||
assert(not evo.has(e, evo.pair(p1, s1)))
|
||||
assert(evo.get(e, evo.pair(p1, s1)) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local f1, f2, f3, p1, s1, p2, s2 = evo.id(7)
|
||||
evo.set(f1, evo.REQUIRES, { f2 })
|
||||
evo.set(f2, evo.DEFAULT, 84)
|
||||
evo.set(f2, evo.REQUIRES, { evo.pair(p2, s2) })
|
||||
evo.set(p1, evo.REQUIRES, { f3 })
|
||||
evo.set(s1, evo.REQUIRES, { f3 })
|
||||
evo.set(p2, evo.REQUIRES, { f3 })
|
||||
evo.set(s2, evo.REQUIRES, { f3 })
|
||||
|
||||
local e = evo.builder()
|
||||
:set(f1, 21)
|
||||
:set(evo.pair(p1, s1), 42)
|
||||
:spawn()
|
||||
|
||||
assert(evo.has(e, evo.pair(p1, s1)))
|
||||
assert(evo.get(e, evo.pair(p1, s1)) == 42)
|
||||
|
||||
assert(evo.has(e, evo.pair(p2, s2)))
|
||||
assert(evo.get(e, evo.pair(p2, s2)) == true)
|
||||
|
||||
assert(evo.has(e, f1))
|
||||
assert(evo.get(e, f1) == 21)
|
||||
|
||||
assert(evo.has(e, f2))
|
||||
assert(evo.get(e, f2) == 84)
|
||||
|
||||
assert(not evo.has(e, f3))
|
||||
assert(evo.get(e, f3) == nil)
|
||||
end
|
||||
|
||||
do
|
||||
local p1, p2, s1, s2 = evo.id(4)
|
||||
|
||||
do
|
||||
local e1 = evo.builder()
|
||||
:set(evo.pair(p1, s1))
|
||||
:set(evo.pair(p1, s2))
|
||||
:spawn()
|
||||
|
||||
local e2 = evo.clone(e1)
|
||||
|
||||
evo.remove(e1, evo.pair(p1, evo.ANY))
|
||||
evo.remove(e2, evo.pair(p1, evo.ANY))
|
||||
assert(evo.empty_all(e1, e2))
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.builder()
|
||||
:set(evo.pair(p1, s1))
|
||||
:set(evo.pair(p2, s1))
|
||||
:spawn()
|
||||
|
||||
local e2 = evo.clone(e1)
|
||||
|
||||
evo.remove(e1, evo.pair(evo.ANY, s1))
|
||||
evo.remove(e2, evo.pair(evo.ANY, s1))
|
||||
assert(evo.empty_all(e1, e2))
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.builder()
|
||||
:set(evo.pair(p1, s1))
|
||||
:set(evo.pair(p1, s2))
|
||||
:set(evo.pair(p2, s1))
|
||||
:set(evo.pair(p2, s2))
|
||||
:spawn()
|
||||
|
||||
local e2 = evo.clone(e1)
|
||||
|
||||
evo.remove(e1, evo.pair(evo.ANY, evo.ANY))
|
||||
evo.remove(e2, evo.pair(evo.ANY, evo.ANY))
|
||||
assert(evo.empty_all(e1, e2))
|
||||
end
|
||||
end
|
||||
|
||||
do
|
||||
local f, p1, p2, s1, s2 = evo.id(5)
|
||||
|
||||
do
|
||||
local e1 = evo.builder()
|
||||
:set(f, 42)
|
||||
:set(evo.pair(p1, s1))
|
||||
:set(evo.pair(p1, s2))
|
||||
:spawn()
|
||||
|
||||
local e2 = evo.clone(e1)
|
||||
|
||||
evo.remove(e1, evo.pair(p1, evo.ANY))
|
||||
evo.remove(e2, evo.pair(p1, evo.ANY))
|
||||
|
||||
assert(evo.has(e1, f) and evo.has(e2, f))
|
||||
assert(not evo.has(e1, evo.pair(evo.ANY, evo.ANY)))
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.builder()
|
||||
:set(f, 42)
|
||||
:set(evo.pair(p1, s1))
|
||||
:set(evo.pair(p2, s1))
|
||||
:spawn()
|
||||
|
||||
local e2 = evo.clone(e1)
|
||||
|
||||
evo.remove(e1, evo.pair(evo.ANY, s1))
|
||||
evo.remove(e2, evo.pair(evo.ANY, s1))
|
||||
|
||||
assert(evo.has(e1, f) and evo.has(e2, f))
|
||||
assert(not evo.has(e1, evo.pair(evo.ANY, evo.ANY)))
|
||||
end
|
||||
|
||||
do
|
||||
local e1 = evo.builder()
|
||||
:set(f, 42)
|
||||
:set(evo.pair(p1, s1))
|
||||
:set(evo.pair(p1, s2))
|
||||
:set(evo.pair(p2, s1))
|
||||
:set(evo.pair(p2, s2))
|
||||
:spawn()
|
||||
|
||||
local e2 = evo.clone(e1)
|
||||
|
||||
evo.remove(e1, evo.pair(evo.ANY, evo.ANY))
|
||||
evo.remove(e2, evo.pair(evo.ANY, evo.ANY))
|
||||
|
||||
assert(evo.has(e1, f) and evo.has(e2, f))
|
||||
assert(not evo.has(e1, evo.pair(evo.ANY, evo.ANY)))
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO:
|
||||
-- How should required fragments work with pairs?
|
||||
-- How can we set defaults for paired fragments?
|
||||
-- Prevent setting wildcard pairs to entities!
|
||||
-- Should paired fragments be greater than common fragments?
|
||||
|
||||
109
evolved.lua
109
evolved.lua
@@ -1385,10 +1385,6 @@ local function __chunk_without_fragment(chunk, fragment)
|
||||
return nil
|
||||
end
|
||||
|
||||
if not chunk.__fragment_set[fragment] then
|
||||
return chunk
|
||||
end
|
||||
|
||||
if fragment == chunk.__fragment then
|
||||
return chunk.__parent
|
||||
end
|
||||
@@ -1398,6 +1394,111 @@ local function __chunk_without_fragment(chunk, fragment)
|
||||
if without_fragment_edge then return without_fragment_edge end
|
||||
end
|
||||
|
||||
if fragment < 0 and chunk.__has_pairs then
|
||||
local primary_index = (0 - fragment) % 0x100000
|
||||
local secondary_index = (0 - fragment - primary_index) / 0x100000
|
||||
|
||||
local primary = __freelist_ids[primary_index] --[[@as evolved.id]]
|
||||
local secondary = __freelist_ids[secondary_index] --[[@as evolved.id]]
|
||||
|
||||
if primary == __ANY and secondary == __ANY then
|
||||
local sib_chunk = chunk.__parent
|
||||
|
||||
while sib_chunk and sib_chunk.__has_pairs do
|
||||
sib_chunk = sib_chunk.__parent
|
||||
end
|
||||
|
||||
local ini_fragment_list = chunk.__fragment_list
|
||||
local ini_fragment_count = chunk.__fragment_count
|
||||
|
||||
for ini_fragment_index = 1, ini_fragment_count do
|
||||
local ini_fragment = ini_fragment_list[ini_fragment_index]
|
||||
if ini_fragment > 0 then
|
||||
sib_chunk = __chunk_with_fragment(sib_chunk, ini_fragment)
|
||||
end
|
||||
end
|
||||
|
||||
if sib_chunk then
|
||||
chunk.__without_fragment_edges[fragment] = sib_chunk
|
||||
sib_chunk.__with_fragment_edges[fragment] = chunk
|
||||
end
|
||||
|
||||
return sib_chunk
|
||||
elseif primary == __ANY then
|
||||
local sec_pairs = chunk.__secondary_pairs[secondary]
|
||||
|
||||
if not sec_pairs then
|
||||
return chunk
|
||||
end
|
||||
|
||||
local sib_chunk = chunk.__parent
|
||||
|
||||
while sib_chunk and sib_chunk.__has_pairs and sib_chunk.__secondary_pairs[secondary] do
|
||||
sib_chunk = sib_chunk.__parent
|
||||
end
|
||||
|
||||
local ini_fragment_list = chunk.__fragment_list
|
||||
local ini_fragment_count = chunk.__fragment_count
|
||||
|
||||
for ini_fragment_index = 1, ini_fragment_count do
|
||||
local ini_fragment = ini_fragment_list[ini_fragment_index]
|
||||
if ini_fragment > 0 then
|
||||
sib_chunk = __chunk_with_fragment(sib_chunk, ini_fragment)
|
||||
else
|
||||
local _, ini_secondary = __evolved_unpair(ini_fragment)
|
||||
if secondary ~= ini_secondary then
|
||||
sib_chunk = __chunk_with_fragment(sib_chunk, ini_fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if sib_chunk then
|
||||
chunk.__without_fragment_edges[fragment] = sib_chunk
|
||||
sib_chunk.__with_fragment_edges[fragment] = chunk
|
||||
end
|
||||
|
||||
return sib_chunk
|
||||
elseif secondary == __ANY then
|
||||
local pri_pairs = chunk.__primary_pairs[primary]
|
||||
|
||||
if not pri_pairs then
|
||||
return chunk
|
||||
end
|
||||
|
||||
local sib_chunk = chunk.__parent
|
||||
|
||||
while sib_chunk and sib_chunk.__has_pairs and sib_chunk.__primary_pairs[primary] do
|
||||
sib_chunk = sib_chunk.__parent
|
||||
end
|
||||
|
||||
local ini_fragment_list = chunk.__fragment_list
|
||||
local ini_fragment_count = chunk.__fragment_count
|
||||
|
||||
for ini_fragment_index = 1, ini_fragment_count do
|
||||
local ini_fragment = ini_fragment_list[ini_fragment_index]
|
||||
if ini_fragment > 0 then
|
||||
sib_chunk = __chunk_with_fragment(sib_chunk, ini_fragment)
|
||||
else
|
||||
local ini_primary, _ = __evolved_unpair(ini_fragment)
|
||||
if primary ~= ini_primary then
|
||||
sib_chunk = __chunk_with_fragment(sib_chunk, ini_fragment)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if sib_chunk then
|
||||
chunk.__without_fragment_edges[fragment] = sib_chunk
|
||||
sib_chunk.__with_fragment_edges[fragment] = chunk
|
||||
end
|
||||
|
||||
return sib_chunk
|
||||
end
|
||||
end
|
||||
|
||||
if not chunk.__fragment_set[fragment] then
|
||||
return chunk
|
||||
end
|
||||
|
||||
if fragment < chunk.__fragment then
|
||||
local sibling_chunk = __chunk_with_fragment(
|
||||
__chunk_without_fragment(chunk.__parent, fragment),
|
||||
|
||||
Reference in New Issue
Block a user