instanceTrackerUtil
A simple utility module for working with instances and their properties.
NOTE
This utility works in conjuction with the Property class.
-- Example type writer effect
local name = Property.new("newText")
instanceTrackerUtil.setProps(textLabel, {
Name = instanceTrackerUtil.bind(name, function(name)
local goalLength = string.len(name)
local timeToTake = goalLength / 30
local accumulated = 0
return function(updatedName)
if timeToTake < accumulated then return nil end
accumulated += RunService.Heartbeat:Wait()
return string.sub(name, 1, math.floor((accumulated / timeToTake) * goalLength))
end
end)
})
Types
TransformerBinder
interface
TransformerBinder {
}
Functions
track
Starts tracking the given instance so that the utility can easily cleanup once this instance is untracked. The
cleanupCallback
is called instanceTrackerUtil.untrack
is called on the instance.
instanceTrackerUtil.track(screenGui.Frame, function(frame)
frame:TweenPosition(UDim2.fromScale(1, 0))
end)
bind
instanceTrackerUtil.
bind
(
property:
Property.Property
,
transformer:
(
newValue:
any
,
oldValue:
any?
)
→
any
) →
TransformerBinder
Returns a transformer binder, to be used by instanceTrackerUtil.setProps
,
the value of property
is wrapped onto transformer
.
bindToInstanceProperty
Returns a transformer binder, to be used by instanceTrackerUtil.setProps
,
the value of property
of instance
is wrapped onto transformer
.
local name = Property.new("newText")
instanceTrackerUtil.setProps(textLabel, {
Text = instanceTrackerUtil.bindToInstanceProperty(Workspace.Baseplate, "Transparency", function(newTransparency, oldTransparency)
return tostring(newTransparency)
end)
})
Workspace.Baseplate.Transparency = 1
task.defer(function()
print(textLabel.Text) --> "1"
end)
bindToInstanceAttribute
Returns a transformer binder, to be used by instanceTrackerUtil.setProps
,
the attribute (attribute
)of
instanceis wrapped onto
transformer`.
local name = Property.new("newText")
instanceTrackerUtil.setProps(textLabel, {
Text = instanceTrackerUtil.bindToInstanceAttribute(Workspace.Baseplate, "SomeAttribute", function(newAttributeValue, oldAttributeValue)
return newAttributeValue
end)
})
Workspace.Baseplate:SetAttribute("SomeAttribute", "TestText")
task.defer(function()
print(textLabel.Text) --> "TestText"
end)
setProps
Initializes the given instance with props
. If properties are specified in props
, the
instance property will be bind to the *value of the property.
Returns a cleanup function which when called, will destroy all properties bound to the instance.
local textProp = Property.new("someText")
local nameProp = Property.new("test")
instanceTrackerUtil.setProps(textLabel, {
Text = textProp,
TextStrokeTransparency = 1,
-- Bind the "Name" property of the textlabel to a callback
-- which will be called every time the "name" property's value
-- changes (and is called initially), you can return a new value
-- from the callback using the given property value, which'll be
-- applied to the instance's property itself.
Name = instanceTrackerUtil.bind(nameProp, function(name)
return name .. "_Cool"
end)
})
print(textLabel.Name) --> "test_Cool"
nameProp:set("nope")
print(textLabel.Name) --> "nope_Cool"
text:set("eyes")
print(textLabel.Text) --> "eyes"
You can also treat the bound function as a higher order function and return another function from it which will be called indefinitely until it returns an explicit nil value or the prop reupdates. The function is just passed the latest value of the property and the old value of the property, and it's return value is used as the new value of the property.
NOTE
The property is updated to the non-nil return value of the function, however it is bulk updated so no on update signals are fired (which effectively prevents the higher order function from being unnecessarily recalled).
- You can use this to implement cool animations, for e.g a type writer effect:
-- Example type writer effect
local nameProp = Property.new("newText")
instanceTrackerUtil.setProps(textLabel, {
Name = instanceTrackerUtil.bind(nameProp, function(name)
local goalLength = string.len(name)
local timeToTake = goalLength / 30
local accumulated = 0
return function(updatedName)
-- We are done with the time writer effect, let's return a nil value to stop
-- this function from being called.
if timeToTake < accumulated then return nil end
accumulated += RunService.Heartbeat:Wait()
return string.sub(name, 1, math.floor((accumulated / timeToTake) * goalLength))
end
end)
})
- Tweening:
local GOAL_TRANSPARENCY = 1
local transparencyProp = Property.new(0)
local function lerp(n, g, a)
return n + (g - n) * a
end
local function close(n, g)
return (n - g) < 0.001
end
instanceTrackerUtil.setProps(Workspace.Baseplate, {
Transparency = instanceTrackerUtil.bind(transparencyProp, function()
return function(updatedTransparency)
if close(updatedTransparency, GOAL_TRANSPARENCY) then return nil end
return lerp(updatedTransparency, GOAL_TRANSPARENCY, RunService.Heartbeat:Wait() * 2)
end
end)
})
untrack
Cleans up the given instance and untracks it, if it was previously being tracked. If a cleanup callback for the given instance exists, it will be called. Additionally, all property objects used for the properties of the descendants of the given instance will have their connections cleaned up.
local myPart = workspace.MyPart
local brickColor = Property.new(BrickColor.Red())
local transparency = Property.new(0)
-- Bind the "BrickColor" property of myPart to the above property:
instanceTrackerUtil.setProps(myPart, {BrickColor = brickColor})
-- Bind the "Transparency" property of myPart.SomeOtherPart to the above property:
instanceTrackerUtil.setProps(myPart.SomeOtherPart, {Transparency = transparency})
-- Track myPart:
instanceTrackerUtil.track(myPart, function()
-- the transparency and brickColor property will soon have their connections cleaned up, so allow
-- them to be set to their default values (myPart's brick color will now turn white
-- and myPart.SomeOtherPart's transparency will now be set to 0)
brickColor:set(BrickColor.White())
transparency:set(0)
end)
task.wait(5)
instanceTrackerUtil.untrack(myPart)