diff --git a/src/batch.luau b/src/batch.luau index 1951789..95ebcb2 100644 --- a/src/batch.luau +++ b/src/batch.luau @@ -6,17 +6,18 @@ local graph = require(script.Parent.graph) local function batch(setter: () -> ()) local already_batching = flags.batch + local flush - flags.batch = true + if not already_batching then + flags.batch = true + flush = graph.flush_update_queue() + end local ok, err: string? = pcall(setter) if not already_batching then flags.batch = false - - if not already_batching then - graph.flush_update_queue() - end + flush() end if not ok then throw(`error occured while batching updates: {err}`) end diff --git a/src/graph.luau b/src/graph.luau index f35b9b6..420899d 100644 --- a/src/graph.luau +++ b/src/graph.luau @@ -186,27 +186,29 @@ end local _flushing = false local function flush_update_queue() - assert(not _flushing, "recursive queue flush occured") -- todo - _flushing = true + local n0 = update_queue.n - local n0 = 0 + return function() + assert(not _flushing, "recursive queue flush occured") -- todo + _flushing = true - local i = n0 + 1 - while i <= update_queue.n do - local node = update_queue[i] - --assert(node.effect) + local i = n0 + 1 + while i <= update_queue.n do + local node = update_queue[i] + --assert(node.effect) - if node.owner and evaluate_node(node) then - queue_children_for_update(node) + if node.owner and evaluate_node(node) then + queue_children_for_update(node) + end + + update_queue[i] = false :: any + i += 1 end - update_queue[i] = false :: any - i += 1 + update_queue.n = n0 + + _flushing = false end - - update_queue.n = n0 - - _flushing = false end local function update_descendants(root: SourceNode) diff --git a/test/tests.luau b/test/tests.luau index adda8da..93dc6fa 100644 --- a/test/tests.luau +++ b/test/tests.luau @@ -1920,6 +1920,34 @@ TEST("batch()", wrap_root(function() CHECK(b2() == 3) CHECK(b3() == 4) end + + do CASE "recursive queue flush" + + local a0 = source(0) + local a1 = source(1) + + derive(function() + a0(a1() + 1) + end) + + derive(function() + print("update") + + a0() + + batch(function() + + end) + + return 1 + end) + + a1(2) + + -- if it didnt error, all is fine! + CHECK(true) + + end end)) TEST("read()", wrap_root(function()