mirror of
https://github.com/centau/vide.git
synced 2026-08-20 14:41:37 +00:00
feat: derive no longer run twice
This commit is contained in:
parent
7350cf1c54
commit
fb30f84596
2 changed files with 31 additions and 56 deletions
|
|
@ -163,53 +163,28 @@ local update_queue = { n = 0 } :: { n: number, [number]: Node<any> }
|
||||||
|
|
||||||
local function evaluate_node<T>(node: Node<T>)
|
local function evaluate_node<T>(node: Node<T>)
|
||||||
if node.higher_parent_update_id == node.last_eval_update_id then return node.needs_queue_children end
|
if node.higher_parent_update_id == node.last_eval_update_id then return node.needs_queue_children end
|
||||||
if flags.strict then
|
|
||||||
local initial_value = node.cache
|
|
||||||
|
|
||||||
for i = 1, 2 do
|
|
||||||
local cur_value = node.cache
|
local cur_value = node.cache
|
||||||
|
|
||||||
flush_cleanups(node)
|
flush_cleanups(node)
|
||||||
destroy_owned(node)
|
destroy_owned(node)
|
||||||
|
|
||||||
push_scope(node)
|
push_scope(node)
|
||||||
local ok, new_value = ycall(node.effect :: (T) -> T, cur_value)
|
local ok, new_value = (if flags.strict then ycall else pcall :: any)(node.effect :: (T) -> T, node.cache)
|
||||||
pop_scope()
|
pop_scope()
|
||||||
|
|
||||||
if not ok then
|
if not ok then
|
||||||
table.clear(update_queue)
|
table.clear(update_queue)
|
||||||
update_queue.n = 0
|
update_queue.n = 0
|
||||||
error(`effect error stacktrace\n{new_value :: string}`, 0)
|
error(`effect error:\n{new_value}`, 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
node.cache = new_value :: T
|
|
||||||
end
|
|
||||||
|
|
||||||
local needs_queue_children = not is_similar(initial_value, node.cache)
|
|
||||||
node.needs_queue_children = needs_queue_children
|
|
||||||
node.last_eval_update_id = update_id
|
|
||||||
return needs_queue_children
|
|
||||||
else
|
|
||||||
local cur_value = node.cache
|
|
||||||
|
|
||||||
flush_cleanups(node)
|
|
||||||
destroy_owned(node)
|
|
||||||
|
|
||||||
push_scope(node)
|
|
||||||
local ok, new_value = pcall(node.effect :: (T) -> T, node.cache)
|
|
||||||
pop_scope()
|
|
||||||
|
|
||||||
if not ok then
|
|
||||||
table.clear(update_queue)
|
|
||||||
update_queue.n = 0
|
|
||||||
error(`effect error:\n{new_value}\n`, 0)
|
|
||||||
end
|
|
||||||
local needs_queue_children = not is_similar(cur_value, new_value)
|
local needs_queue_children = not is_similar(cur_value, new_value)
|
||||||
node.needs_queue_children = needs_queue_children
|
node.needs_queue_children = needs_queue_children
|
||||||
|
|
||||||
node.last_eval_update_id = update_id
|
node.last_eval_update_id = update_id
|
||||||
node.cache = new_value
|
node.cache = new_value
|
||||||
|
|
||||||
return needs_queue_children
|
return needs_queue_children
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function queue_children_for_update<T>(node: SourceNode<T>)
|
local function queue_children_for_update<T>(node: SourceNode<T>)
|
||||||
|
|
|
||||||
|
|
@ -1221,24 +1221,24 @@ TEST("show()", wrap_root(function()
|
||||||
|
|
||||||
branch = 1
|
branch = 1
|
||||||
weapon { id = "1", enchant = "fire" }
|
weapon { id = "1", enchant = "fire" }
|
||||||
CHECK(count == 8)
|
CHECK(count == 1)
|
||||||
|
|
||||||
branch = 2
|
branch = 2
|
||||||
weapon { id = "1", enchant = "poison" }
|
weapon { id = "1", enchant = "poison" }
|
||||||
CHECK(count == 10)
|
CHECK(count == 2)
|
||||||
|
|
||||||
weapon { id = "1", enchant = nil }
|
weapon { id = "1", enchant = nil }
|
||||||
CHECK(count == 10)
|
CHECK(count == 2)
|
||||||
|
|
||||||
branch = 1
|
branch = 1
|
||||||
weapon { id = "1", enchant = "fire" }
|
weapon { id = "1", enchant = "fire" }
|
||||||
CHECK(count == 14)
|
CHECK(count == 3)
|
||||||
|
|
||||||
weapon(nil)
|
weapon(nil)
|
||||||
|
|
||||||
branch = 2
|
branch = 2
|
||||||
weapon { id = "1", enchant = "poison" }
|
weapon { id = "1", enchant = "poison" }
|
||||||
CHECK(count == 22)
|
CHECK(count == 4)
|
||||||
|
|
||||||
vide.strict = false
|
vide.strict = false
|
||||||
end
|
end
|
||||||
|
|
@ -2763,9 +2763,9 @@ TEST("strict", wrap_root(function()
|
||||||
return src()
|
return src()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
CHECK(count == 2)
|
CHECK(count == 1)
|
||||||
src(2)
|
src(2)
|
||||||
CHECK(count == 4)
|
CHECK(count == 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
do CASE "run effect callback twice"
|
do CASE "run effect callback twice"
|
||||||
|
|
@ -2777,9 +2777,9 @@ TEST("strict", wrap_root(function()
|
||||||
src()
|
src()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
CHECK(count == 2)
|
CHECK(count == 1)
|
||||||
src(2)
|
src(2)
|
||||||
CHECK(count == 4)
|
CHECK(count == 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
do CASE "indexes() error if primitive"
|
do CASE "indexes() error if primitive"
|
||||||
|
|
@ -2841,9 +2841,9 @@ TEST("strict", wrap_root(function()
|
||||||
return count
|
return count
|
||||||
end, count)
|
end, count)
|
||||||
|
|
||||||
CHECK(count == 2)
|
CHECK(count == 1)
|
||||||
src(not src())
|
src(not src())
|
||||||
CHECK(count == 4)
|
CHECK(count == 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
do CASE "effect using derived source"
|
do CASE "effect using derived source"
|
||||||
|
|
@ -2860,11 +2860,11 @@ TEST("strict", wrap_root(function()
|
||||||
count += 1
|
count += 1
|
||||||
end)
|
end)
|
||||||
|
|
||||||
CHECK(count == 2)
|
CHECK(count == 1)
|
||||||
|
|
||||||
input(false)
|
input(false)
|
||||||
|
|
||||||
CHECK(count == 4)
|
CHECK(count == 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
do CASE "destruction of active scope"
|
do CASE "destruction of active scope"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue