mirror of
https://github.com/centau/vide.git
synced 2026-08-20 06:21:37 +00:00
Fix recursive batch() use
This commit is contained in:
parent
65fe3fcf47
commit
8eb5f96c5b
5 changed files with 75 additions and 16 deletions
|
|
@ -73,4 +73,22 @@ read can still be tracked inside a reactive scope.
|
||||||
function read<T>(value: T | () -> T): T
|
function read<T>(value: T | () -> T): T
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## batch()
|
||||||
|
|
||||||
|
Runs a given function where any source updates made within the function do not
|
||||||
|
trigger effects until after the function runs.
|
||||||
|
|
||||||
|
- **Type**
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function batch(fn: () -> ())
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Details**
|
||||||
|
|
||||||
|
Improves performance when an effect depends on multiple sources, and those
|
||||||
|
sources need to be updated. Updating those sources inside a batch call will
|
||||||
|
only cause the effect to run once after the batch call ends instead of after
|
||||||
|
each time a source is updated.
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,15 @@ local function batch(setter: () -> ())
|
||||||
|
|
||||||
local ok, err: string? = pcall(setter)
|
local ok, err: string? = pcall(setter)
|
||||||
|
|
||||||
flags.batch = false
|
if not already_batching then
|
||||||
|
flags.batch = false
|
||||||
if not ok then throw(`error occured while batching updates: {err}`) end
|
|
||||||
|
if not already_batching then
|
||||||
if not already_batching then -- todo: flush anyways?
|
graph.flush_update_queue()
|
||||||
graph.flush_update_queue()
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not ok then throw(`error occured while batching updates: {err}`) end
|
||||||
end
|
end
|
||||||
|
|
||||||
return batch
|
return batch
|
||||||
|
|
|
||||||
|
|
@ -185,8 +185,11 @@ local function queue_children<T>(node: StartNode<T>)
|
||||||
update_queue.n = i
|
update_queue.n = i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local _flushing = false
|
||||||
local function flush_update_queue()
|
local function flush_update_queue()
|
||||||
-- todo: test with recursive batch sets
|
assert(not flushing, "recursive queue flush occured") -- todo
|
||||||
|
_flushing = true
|
||||||
|
|
||||||
local n0 = 0
|
local n0 = 0
|
||||||
|
|
||||||
local i = n0 + 1
|
local i = n0 + 1
|
||||||
|
|
@ -203,6 +206,8 @@ local function flush_update_queue()
|
||||||
end
|
end
|
||||||
|
|
||||||
update_queue.n = n0
|
update_queue.n = n0
|
||||||
|
|
||||||
|
_flushing = false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function update<T>(root: StartNode<T>)
|
local function update<T>(root: StartNode<T>)
|
||||||
|
|
|
||||||
|
|
@ -1805,7 +1805,7 @@ TEST("batch()", wrap_root(function()
|
||||||
local derive = vide.derive
|
local derive = vide.derive
|
||||||
local batch = vide.batch
|
local batch = vide.batch
|
||||||
|
|
||||||
do CASE "child evaluation halted"
|
do CASE "evaluation deferred"
|
||||||
local a = source(0)
|
local a = source(0)
|
||||||
|
|
||||||
local count = { b = 0, b2 = 0, c = 0 }
|
local count = { b = 0, b2 = 0, c = 0 }
|
||||||
|
|
@ -1840,7 +1840,47 @@ TEST("batch()", wrap_root(function()
|
||||||
CHECK(c() == 5)
|
CHECK(c() == 5)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- todo: test batch call in recursive set
|
do CASE "recursive call"
|
||||||
|
local a1 = source(0)
|
||||||
|
local a2 = source(0)
|
||||||
|
local a3 = source(0)
|
||||||
|
|
||||||
|
local count = { b1 = 0, b2 = 0, b3 = 0 }
|
||||||
|
|
||||||
|
local b1 = derive(function()
|
||||||
|
count.b1 += 1
|
||||||
|
return a1() + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
local b2 = derive(function()
|
||||||
|
count.b2 += 1
|
||||||
|
return a2() + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
local b3 = derive(function()
|
||||||
|
count.b3 += 1
|
||||||
|
return a3() + 1
|
||||||
|
end)
|
||||||
|
|
||||||
|
batch(function()
|
||||||
|
a1(1)
|
||||||
|
batch(function()
|
||||||
|
a2(2)
|
||||||
|
end)
|
||||||
|
a3(3)
|
||||||
|
CHECK(count.b1 == 1)
|
||||||
|
CHECK(count.b2 == 1)
|
||||||
|
CHECK(count.b3 == 1)
|
||||||
|
end)
|
||||||
|
|
||||||
|
CHECK(count.b1 == 2)
|
||||||
|
CHECK(count.b2 == 2)
|
||||||
|
CHECK(count.b3 == 2)
|
||||||
|
|
||||||
|
CHECK(b1() == 2)
|
||||||
|
CHECK(b2() == 3)
|
||||||
|
CHECK(b3() == 4)
|
||||||
|
end
|
||||||
end))
|
end))
|
||||||
|
|
||||||
TEST("read()", wrap_root(function()
|
TEST("read()", wrap_root(function()
|
||||||
|
|
|
||||||
8
todo.md
8
todo.md
|
|
@ -1,10 +1,4 @@
|
||||||
# todo
|
# todo
|
||||||
|
|
||||||
- optimize wide graph updating
|
- improve error traces
|
||||||
- implement from solid:
|
|
||||||
- stores
|
|
||||||
- portals
|
|
||||||
- batch()
|
|
||||||
- optimize `indexes()` double-diffing
|
|
||||||
- cleanup source and tests
|
|
||||||
- prevent redundant re-eval of nodes in a complex diamond graph
|
- prevent redundant re-eval of nodes in a complex diamond graph
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue