mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-23 14:15:24 +00:00
plugin: Add support for pausing updates tracked by InstanceMap
This commit is contained in:
@@ -5,16 +5,28 @@ local Log = require(script.Parent.Parent.Log)
|
|||||||
keep track of every instance we know about.
|
keep track of every instance we know about.
|
||||||
|
|
||||||
TODO: Track ancestry to catch when stuff moves?
|
TODO: Track ancestry to catch when stuff moves?
|
||||||
TODO: Ability to pause change tracking for preventing feedback.
|
|
||||||
]]
|
]]
|
||||||
local InstanceMap = {}
|
local InstanceMap = {}
|
||||||
InstanceMap.__index = InstanceMap
|
InstanceMap.__index = InstanceMap
|
||||||
|
|
||||||
function InstanceMap.new(onInstanceChanged)
|
function InstanceMap.new(onInstanceChanged)
|
||||||
local self = {
|
local self = {
|
||||||
|
-- A map from IDs to instances.
|
||||||
fromIds = {},
|
fromIds = {},
|
||||||
|
|
||||||
|
-- A map from instances to IDs.
|
||||||
fromInstances = {},
|
fromInstances = {},
|
||||||
|
|
||||||
|
-- A set of all instances that updates should be paused for. This set
|
||||||
|
-- should generally be empty, and will be filled by pauseInstance
|
||||||
|
-- temporarily.
|
||||||
|
pausedUpdateInstances = {},
|
||||||
|
|
||||||
|
-- A map from instances to a signal or list of signals connected to it.
|
||||||
instancesToSignal = {},
|
instancesToSignal = {},
|
||||||
|
|
||||||
|
-- Callback that's invoked whenever an instance is changed and it was
|
||||||
|
-- not paused.
|
||||||
onInstanceChanged = onInstanceChanged,
|
onInstanceChanged = onInstanceChanged,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +131,32 @@ function InstanceMap:destroyId(id)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Pause updates for an instance momentarily and invoke a callback.
|
||||||
|
|
||||||
|
If the callback throws an error, InstanceMap will still be kept in a
|
||||||
|
consistent state.
|
||||||
|
]]
|
||||||
|
function InstanceMap:pauseInstance(instance, callback)
|
||||||
|
local id = self.fromInstances[instance]
|
||||||
|
|
||||||
|
-- If we don't know about this instance, ignore it and do not invoke the
|
||||||
|
-- callback.
|
||||||
|
if id == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self.pausedUpdateInstances[instance] = true
|
||||||
|
local success, result = xpcall(callback, debug.traceback)
|
||||||
|
self.pausedUpdateInstances[instance] = false
|
||||||
|
|
||||||
|
if success then
|
||||||
|
return result
|
||||||
|
else
|
||||||
|
error(result, 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function InstanceMap:__connectSignals(instance)
|
function InstanceMap:__connectSignals(instance)
|
||||||
-- ValueBase instances have an overriden version of the Changed signal that
|
-- ValueBase instances have an overriden version of the Changed signal that
|
||||||
-- only detects changes to their Value property.
|
-- only detects changes to their Value property.
|
||||||
@@ -151,9 +189,15 @@ end
|
|||||||
function InstanceMap:__maybeFireInstanceChanged(instance, propertyName)
|
function InstanceMap:__maybeFireInstanceChanged(instance, propertyName)
|
||||||
Log.trace("{}.{} changed", instance:GetFullName(), propertyName)
|
Log.trace("{}.{} changed", instance:GetFullName(), propertyName)
|
||||||
|
|
||||||
if self.onInstanceChanged ~= nil then
|
if self.pausedUpdateInstances[instance] then
|
||||||
self.onInstanceChanged(instance, propertyName)
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if self.onInstanceChanged == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self.onInstanceChanged(instance, propertyName)
|
||||||
end
|
end
|
||||||
|
|
||||||
function InstanceMap:__disconnectSignals(instance)
|
function InstanceMap:__disconnectSignals(instance)
|
||||||
|
|||||||
Reference in New Issue
Block a user