Computed
Import Weave.Computed
from the Weave module.
1 2 |
|
Computed
values are used to calculate new values.
local health = Value.new(100)
local healthDisplay = Computed.new(function()
return "Current Health: " .. health:get()
end)
healthDisplay:get() --> "Current Health: 100"
✨ Computed
values update automatically ✨
health:set(99)
healthDisplay:get() --> "Current Health: 99"

Computed
values update automaticallyUsage¶
Computed.new
to make a new Computed
value.
local quantity = Value.new(1)
local cost = Value.new(2)
local totalPrice = Computed.new(function()
return cost:get() * quantity:get()
end)
You can get the computed's current value using :get()
:
totalPrice:get() --> 2
The Computed
function runs again when any of its dependencies change
quantity:set(2)
totalPrice:get() --> 4
cost:set(10)
totalPrice:get() --> 20
.Changed
¶
Just like Value
, when Computed
changes .Changed
is fired.
local double = Computed.new(function()
return number:get() * 2
end)
double.Changed:Connect(onDoubleChanged)
Note: You can also use :get()
to get the updated value.
When To Use This¶
Computed
values make it easier to calculate new state from existing state.
Derived values show up a lot in games.
For example, you might want to insert a number into a string to display in the UI.
A warning about delays in computed callbacks
One small caveat of computeds is that you must return the value immediately. If you need to send a request to the server or perform a long-running calculation, you shouldn't use computeds.
The reason for this is consistency between variables. When all computeds run
immediately (i.e. without yielding), all of your variables will behave consistently:
local numCoins = Value.new(50)
local isEnoughCoins = Computed.new(function()
return numCoins:get() > 25
end)
local message = Computed.new(function()
if isEnoughCoins:get() then
return numCoins:get() .. " is enough coins."
else
return numCoins:get() .. " is NOT enough coins."
end
end)
message:get() --> 50 is enough coins.
numCoins:set(2)
message:get() --> 2 is NOT enough coins.
If a delay is introduced, then inconsistencies and nonsense values could quickly appear:
local numCoins = Value.new(50)
local isEnoughCoins = Computed.new(function()
task.wait(5) -- Don't do this! This is just for the example
return numCoins:get() > 25
end)
local message = Computed.new(function()
if isEnoughCoins:get() then
return `{numCoins:get()} is enough coins.`
else
return `{numCoins:get()} is NOT enough coins.`
end
end)
print(message:get()) --> 50 is enough coins.
numCoins:set(2)
print(message:get()) --> 2 is enough coins.
For this reason, yielding in computed callbacks is disallowed.
If you have to introduce a delay, for example when invoking a RemoteFunction, consider using values and connecting to the Changed event.
local numCoins = Value.new(50)
local isEnoughCoins = Value.new(nil)
local function updateIsEnoughCoins()
isEnoughCoins:set(nil) -- indicate that we're calculating the value
task.wait(5) -- this is now ok
isEnoughCoins:set(numCoins:get() > 25)
end
task.spawn(updateIsEnoughCoins)
numCoins.Changed:Connect(updateIsEnoughCoins)
local message = Computed.new(function()
if isEnoughCoins:get() == nil then
return "Loading..."
elseif isEnoughCoins:get() then
return numCoins:get() .. " is enough coins."
else
return numCoins:get() .. " is NOT enough coins."
end
end)
print(message:get()) --> 50 is enough coins.
numCoins:set(2)
print(message:get()) --> Loading...
task.wait(5)
print(message:get()) --> 2 is NOT enough coins.