From fb30f845963fca2b160547ab32c46b640792a23e Mon Sep 17 00:00:00 2001 From: ernisto Date: Thu, 10 Apr 2025 21:06:35 -0300 Subject: [PATCH] feat: derive no longer run twice --- src/graph.luau | 61 +++++++++++++++---------------------------------- test/tests.luau | 26 ++++++++++----------- 2 files changed, 31 insertions(+), 56 deletions(-) diff --git a/src/graph.luau b/src/graph.luau index 0f0e0d1..8baa7bc 100644 --- a/src/graph.luau +++ b/src/graph.luau @@ -163,53 +163,28 @@ local update_queue = { n = 0 } :: { n: number, [number]: Node } local function evaluate_node(node: Node) 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 + local cur_value = node.cache - for i = 1, 2 do - local cur_value = node.cache + flush_cleanups(node) + destroy_owned(node) - flush_cleanups(node) - destroy_owned(node) - - push_scope(node) - local ok, new_value = ycall(node.effect :: (T) -> T, cur_value) - pop_scope() - - if not ok then - table.clear(update_queue) - update_queue.n = 0 - error(`effect error stacktrace\n{new_value :: string}`, 0) - end + push_scope(node) + local ok, new_value = (if flags.strict then ycall else pcall :: any)(node.effect :: (T) -> T, node.cache) + pop_scope() - 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) - node.needs_queue_children = needs_queue_children - node.last_eval_update_id = update_id - node.cache = new_value - return needs_queue_children + if not ok then + table.clear(update_queue) + update_queue.n = 0 + error(`effect error:\n{new_value}`, 0) end + + local needs_queue_children = not is_similar(cur_value, new_value) + node.needs_queue_children = needs_queue_children + + node.last_eval_update_id = update_id + node.cache = new_value + + return needs_queue_children end local function queue_children_for_update(node: SourceNode) diff --git a/test/tests.luau b/test/tests.luau index 4b50483..db6d069 100644 --- a/test/tests.luau +++ b/test/tests.luau @@ -1221,24 +1221,24 @@ TEST("show()", wrap_root(function() branch = 1 weapon { id = "1", enchant = "fire" } - CHECK(count == 8) + CHECK(count == 1) branch = 2 weapon { id = "1", enchant = "poison" } - CHECK(count == 10) + CHECK(count == 2) weapon { id = "1", enchant = nil } - CHECK(count == 10) + CHECK(count == 2) branch = 1 weapon { id = "1", enchant = "fire" } - CHECK(count == 14) + CHECK(count == 3) weapon(nil) branch = 2 weapon { id = "1", enchant = "poison" } - CHECK(count == 22) + CHECK(count == 4) vide.strict = false end @@ -2763,9 +2763,9 @@ TEST("strict", wrap_root(function() return src() end) - CHECK(count == 2) + CHECK(count == 1) src(2) - CHECK(count == 4) + CHECK(count == 2) end do CASE "run effect callback twice" @@ -2777,9 +2777,9 @@ TEST("strict", wrap_root(function() src() end) - CHECK(count == 2) + CHECK(count == 1) src(2) - CHECK(count == 4) + CHECK(count == 2) end do CASE "indexes() error if primitive" @@ -2841,9 +2841,9 @@ TEST("strict", wrap_root(function() return count end, count) - CHECK(count == 2) + CHECK(count == 1) src(not src()) - CHECK(count == 4) + CHECK(count == 2) end do CASE "effect using derived source" @@ -2860,11 +2860,11 @@ TEST("strict", wrap_root(function() count += 1 end) - CHECK(count == 2) + CHECK(count == 1) input(false) - CHECK(count == 4) + CHECK(count == 2) end do CASE "destruction of active scope"