Skip to content

Commit

Permalink
Do not defer property and child assignments anymore
Browse files Browse the repository at this point in the history
  • Loading branch information
dphfox committed Apr 15, 2024
1 parent d3b43f8 commit 0550bf0
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 50 deletions.
6 changes: 3 additions & 3 deletions docs/tutorials/roblox/hydration.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ and hiding buttons.
</figure>

Fusion provides a `Hydrate` function for hydrating an instance using a table
of properties. If you pass in Fusion objects, changes will be applied on the
next frame:
of properties. If you pass in Fusion objects, changes will be applied
immediately:

```Lua
local showUI = scope:Value(false)
Expand Down Expand Up @@ -73,7 +73,7 @@ local instance = scope:Hydrate(workspace.Part) {

If you pass in constant values for properties, they'll be applied to the
instance directly. However, if you pass in a Fusion object (like `Value`), then
changes will be applied on the next frame:
changes will be applied immediately:

```Lua
local message = scope:Value("Loading...")
Expand Down
16 changes: 3 additions & 13 deletions src/Instances/Attribute.luau
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ local task = nil -- Disable usage of Roblox's task scheduler

local Package = script.Parent.Parent
local Types = require(Package.Types)
local External = require(Package.External)
local logError = require(Package.Logging.logError)
local logWarn = require(Package.Logging.logWarn)
local isState = require(Package.State.isState)
Expand Down Expand Up @@ -38,18 +37,9 @@ local function Attribute(
elseif whichLivesLonger(scope, applyTo, value.scope, value) == "definitely-a" then
logWarn("possiblyOutlives", `The {value.kind} object, bound to [Attribute "{attributeName}"],`, `the {applyTo.ClassName} instance`)
end
local didDefer = false
local function update()
if not didDefer then
didDefer = true
External.doTaskDeferred(function()
didDefer = false
applyTo:SetAttribute(attributeName, peek(value))
end)
end
end
applyTo:SetAttribute(attributeName, peek(value))
table.insert(scope, Observer(scope, value :: any):onChange(update))
Observer(scope, value :: any):onBind(function()
applyTo:SetAttribute(attributeName, peek(value))
end)
else
applyTo:SetAttribute(attributeName, value)
end
Expand Down
19 changes: 1 addition & 18 deletions src/Instances/Children.luau
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,10 @@ return {
local newScopes: {[Types.StateObject<unknown>]: Types.Scope<unknown>} = {}
local oldScopes: {[Types.StateObject<unknown>]: Types.Scope<unknown>} = {}

local updateQueued = false
local queueUpdate: () -> ()

-- Rescans this key's value to find new instances to parent and state objects
-- to observe for changes; then unparents instances no longer found and
-- disconnects observers for state objects no longer present.
local function updateChildren()
if not updateQueued then
return -- this update may have been canceled by destruction, etc.
end
updateQueued = false

oldParented, newParented = newParented, oldParented
oldScopes, newScopes = newScopes, oldScopes
table.clear(newParented)
Expand Down Expand Up @@ -97,7 +89,7 @@ return {
if childScope == nil then
-- wasn't previously present
childScope = {}
Observer(childScope, child):onChange(queueUpdate)
Observer(childScope, child):onChange(updateChildren)
else
-- previously here; we want to reuse, so remove from old
-- set so we don't encounter it during unparenting
Expand Down Expand Up @@ -148,21 +140,12 @@ return {
end
end

queueUpdate = function()
if not updateQueued then
updateQueued = true
External.doTaskDeferred(updateChildren)
end
end

table.insert(scope, function()
value = nil
updateQueued = true
updateChildren()
end)

-- perform initial child parenting
updateQueued = true
updateChildren()
end
} :: Types.SpecialKey
20 changes: 4 additions & 16 deletions src/Instances/applyInstanceProps.luau
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ local task = nil -- Disable usage of Roblox's task scheduler

local Package = script.Parent.Parent
local Types = require(Package.Types)
local External = require(Package.External)
local isState = require(Package.State.isState)
local logError = require(Package.Logging.logError)
local logWarn = require(Package.Logging.logWarn)
Expand Down Expand Up @@ -81,21 +80,10 @@ local function bindProperty(
elseif whichLivesLonger(scope, instance, value.scope, value) == "definitely-a" then
logWarn("possiblyOutlives", `The {value.kind} object, bound to {property},`, `the {instance.ClassName} instance`)
end

-- value is a state object - assign and observe for changes
local willUpdate = false
local function updateLater()
if not willUpdate then
willUpdate = true
External.doTaskDeferred(function()
willUpdate = false
setProperty(instance, property, peek(value))
end)
end
end

setProperty(instance, property, peek(value))
table.insert(scope, Observer(scope, value :: any):onChange(updateLater))
-- value is a state object - bind to changes
Observer(scope, value :: any):onBind(function()
setProperty(instance, property, peek(value))
end)
else
-- value is a constant - assign once only
setProperty(instance, property, value)
Expand Down

0 comments on commit 0550bf0

Please sign in to comment.