Fix diamond graphs

This commit is contained in:
Aaron Smith 2023-10-25 15:49:35 +01:00
parent da85cbbac8
commit 8218e4702f
2 changed files with 140 additions and 27 deletions

View file

@ -181,47 +181,80 @@ local function evaluate_node<T>(node: Node<T>)
return cur_value ~= new_value -- node has changed value
end
local function update_from<T>(node: StartNode<T>, n0: number)
if not node[1] then return end
-- local function update_from<T>(node: StartNode<T>, n0: number)
-- if not node[1] then return end
local n = n0
-- local n = n0
-- unparent all children and queue for eval
do
local child = node[1]
while child do
--assert(child.parents.owner)
unparent(child)
n += 1
update_queue[n] = child
child = node[1]
end
-- -- unparent all children and queue for eval
-- do
-- local child = node[1]
-- while child do
-- --assert(child.parents.owner)
-- unparent(child)
-- n += 1
-- update_queue[n] = child
-- child = node[1]
-- end
-- end
-- update_queue.n = n
-- -- evaluate all queued children
-- for i = n0 + 1, n do
-- local child = update_queue[i]
-- assert(type(child.effect) == "function")
-- if evaluate_node(child) then
-- update_from(child, n)
-- end
-- update_queue[i] = false :: any -- false instead of nil to avoid sparse
-- end
-- update_queue.n = n0
-- end
-- local function update<T>(node: StartNode<T>)
-- update_from(node, update_queue.n)
-- end
local function queue_children<T>(node: StartNode<T>)
local i = update_queue.n
local child = node[1]
while child do
--assert(child.parents.owner)
unparent(child)
i += 1
update_queue[i] = child
child = node[1]
end
update_queue.n = i
end
update_queue.n = n
local function update<T>(root: StartNode<T>)
local n0 = update_queue.n
queue_children(root)
-- evaluate all queued children
for i = n0 + 1, n do
local child = update_queue[i]
assert(type(child.effect) == "function")
local i = n0 + 1
while i <= update_queue.n do
local node = update_queue[i]
assert(node.effect)
if evaluate_node(child) then
update_from(child, n)
if evaluate_node(node) then
queue_children(node)
end
update_queue[i] = false :: any -- false instead of nil to avoid sparse
i += 1
end
update_queue.n = n0
end
local function update<T>(node: StartNode<T>)
update_from(node, update_queue.n)
end
local function track<T>(node: StartNode<T>)
local scope = get_scope()
if scope and type(scope.effect) == "function" then -- do not track nodes with no effect
if scope and scope.effect then -- do not track nodes with no effect
add_child(node, scope)
end
end