Currently, when binding state to a property, changes are deferred until the next render step. Also, when listening for property changes with OnChange, we connect to GetPropertyChangeSignal on the instance.
The combination of these two things is that OnChange only fires on the next render step after the state changes, not immediately when the state object actually changes.
As mentioned in the docs, this can lead to subtle off-by-one-frame errors that are non-obvious. To demonstrate with a (pretty unrealistic) example:
local originalState = State(0)
local syncedState = State(0)
local instance1 = New "NumberValue" {
Value = originalState,
[OnChange "Value"] = function(newValue)
syncedState:set(newValue)
end
}
local instance2 = New "NumberValue" {
-- problem: because `syncedState` is set on the render step after `originalState` is set,
-- this change will be deferred another render step, meaning this instance will lag
-- behind by one frame
Value = syncedState
}
When not using OnChange (or OnEvent "Changed" for that matter), deferred updating is almost certainly desirable. However, when using OnChange, it may not always be desirable for this reason.
Should deferred updating be disabled for properties which have OnChange listeners/instances with Changed listeners?
Points to consider:
- Fusion only knows about event and property change handlers it connects via
New - it's impossible to know if other connections exist, which could lead to unexpected behaviour
- Deferred updating is done to improve performance; by disabling it, would we be introducing notable unnecessary overhead?
I'm currently leaning towards 'no', but it'd be interesting to hear other people's thoughts on this anyway.
Currently, when binding state to a property, changes are deferred until the next render step. Also, when listening for property changes with OnChange, we connect to GetPropertyChangeSignal on the instance.
The combination of these two things is that OnChange only fires on the next render step after the state changes, not immediately when the state object actually changes.
As mentioned in the docs, this can lead to subtle off-by-one-frame errors that are non-obvious. To demonstrate with a (pretty unrealistic) example:
When not using OnChange (or OnEvent "Changed" for that matter), deferred updating is almost certainly desirable. However, when using OnChange, it may not always be desirable for this reason.
Should deferred updating be disabled for properties which have OnChange listeners/instances with Changed listeners?
Points to consider:
New- it's impossible to know if other connections exist, which could lead to unexpected behaviourI'm currently leaning towards 'no', but it'd be interesting to hear other people's thoughts on this anyway.