This commit is contained in:
aaron 2023-09-12 23:12:24 +01:00
parent da40e05fd8
commit d353f71619
10 changed files with 214 additions and 160 deletions

View file

@ -8,95 +8,69 @@ used inside a function is updated, the whole function can be re-ran to recompute
its value.
```lua
local count = source(0)
local vide = require(vide)
local source = vide.source
local function text()
return "count: " .. count()
local function Counter()
local count = source(0)
local function doubled()
return count() * 2
end
return create "TextButton" {
Position = UDim2.fromOffset(300, 300),
Size = UDim2.fromOffset(200, 50),
Text = doubled,
Activated = function()
count(count() + 1)
end
}
end
create "TextLabel" {
Text = text
}
mount(function() return create "ScreenGui" { Counter {} } end, game.StarterGui)
```
Now the counter will increment in 2s each time it is clicked.
Sometimes when using expensive computations to derive state, you only want to
recalculate it once when a source state has changed
If you wrap a source with a regular function, its value will be recomputed
every time you call that function.
[`derive()`](../../api/reactivity-core.md#derive) accepts a functions whose
return value will be cached, so that subsequent calls of this derived source
will return the same cached value until one of its input sources have changed.
recalculate it once when a source state has changed. Although not needed in
most cases, you can use `derive()` to create a new source that will cache its
value, only recomputing when an input source has changed.
```lua
local vide = require(vide)
local source = vide.source
local derive = vide.derive
```
```lua
local count = source(0)
local function Counter()
local count = source(0)
local factorial = derive(function()
local n = 1
for i = 2, count() do
n *= i
end
return n
end)
local factorial = derive(function()
local n = 1
for i = 2, count() do
n *= i
end
return n
end)
return create "TextButton" {
Position = UDim2.fromOffset(300, 300),
Size = UDim2.fromOffset(200, 50),
Text = function()
return factorial() + factorial() + factorial()
end,
Activated = function()
count(count() + 1)
end
}
end
```
This can improve performance in cases where a source is read from multiple times
between recalculations, like in the example below:
```lua
create "TextLabel" {
Text = function()
return "factorial squared: " .. factorial() * factorial()
end
}
count(3) -- displays "factorial squared: 36"
count(4) -- displays "factorial squared: 576"
```
Vide knows what sources are being depended on by immediately running the
callback when deriving or binding sources. If a source is in a function but is
never referenced the first time it runs, Vide will not know to rerun the
function if that source changes.
An example to effect out for is when using sources within branches:
```lua
local condition = source(true)
local count1 = source(0)
local count2 = source(0)
local text = function()
if condition() then
return "text: " .. count1()
else
return "text: " .. count2()
end
end
```
In the above case, only `count1` will be referenced, meaning `text` will not be
aware of `count2` even if the condition is later set to false.
All sources to be tracked must be referenced the first time the function runs.
```lua
local condition = source(true)
local count1 = source(0)
local count2 = source(0)
local text = function()
local c1 = count1()
local c2 = count2()
if condition() then
return "text: " .. c1
else
return "text: " .. c2
end
end
```
between recalculations. In the above example, the factorial is only ever
calculated once each time the count changes.