Bag
local Bag = require("@game/ReplicatedStorage/Twill").Bag
local bag = Bag.new()
bag:Connect(part.Touched, onTouched)bag:Add(model)bag:Destroy()Closing order and failure
Section titled “Closing order and failure”A bag closes newest first. Anything added later is closed before what it was built on.
Every cleanup runs inside its own pcall. One that raises is collected and the
drain continues, so a single failure cannot strand the entries queued behind it.
Failures are reported through the log after the bag is empty, one line each.
Adding to a bag from inside one of its own cleanups is allowed. The addition is closed in the same pass.
Destroy on a bag that is already destroyed does nothing.
What a bag can close
Section titled “What a bag can close”Add works out how to close most things on its own.
| Given | Closed by |
|---|---|
Instance | Destroy |
RBXScriptConnection | Disconnect |
function | Calling it |
thread | task.cancel, skipped when the thread is already dead |
table | The first of Destroy, Disconnect, destroy, disconnect it carries |
Anything else needs the closing method named. Pass the method name as the second
argument, or true for a function or thread.
A thread cancelling itself is deferred rather than cancelled in place.
Naming an entry
Section titled “Naming an entry”The third argument to Add is a key. Adding again under the same key closes
whatever held it before.
bag:Add(track, nil, "walk")bag:Add(otherTrack, nil, "walk")The first track is closed when the second takes the name. Get reads what a key
holds without letting it out.
Attaching to an instance
Section titled “Attaching to an instance”AttachTo turns ownership the other way round: the instance going closes the
bag, rather than the bag closing the instance.
An instance that is not in game closes the bag immediately, and AttachTo
answers nil. A bag can be attached to one instance at a time; attaching again
detaches first.
Bag.new
Section titled “Bag.new”[Server] | [Client]
Makes an empty bag.
function Bag.new(): BagBag.Is
Section titled “Bag.Is”[Server] | [Client]
Answers whether a value is one of these bags.
function Bag.Is(value: any): booleanBag:Add
Section titled “Bag:Add”[Server] | [Client]
Holds an object until the bag closes, and hands it straight back.
function Bag:Add<T>(object: T, method: (string | boolean)?, key: any?): TParameters
| Name | Type | Description |
|---|---|---|
object | T | An instance, connection, function, thread, or object. |
method | (string | boolean)? | The name of the method that closes it, or true for a function or thread. Worked out when left out. |
key | any? | A name for it. Closes whatever held that name before. |
Returns
T - The object that was passed in.
Throws when the bag has been destroyed, when nothing was passed, when the bag is passed to itself, and when nothing says how the object closes.
Bag:Connect
Section titled “Bag:Connect”[Server] | [Client]
Connects a signal and holds the connection.
function Bag:Connect(signal: any, callback: (...any) -> ()): anyTakes an RBXScriptSignal or any object carrying Connect, which includes
Signal. Throws on anything else.
Bag:Once
Section titled “Bag:Once”[Server] | [Client]
Connects a signal for one firing, letting the entry go the moment it fires.
function Bag:Once(signal: any, callback: (...any) -> ()): anyThe entry leaves the bag when it fires, so a bag holding many one-shot listeners does not grow.
Bag:Task
Section titled “Bag:Task”[Server] | [Client]
Runs a callback on its own thread, cancelled if it is still going when the bag closes.
function Bag:Task(callback: (...any) -> (), ...: any): threadBag:Delay
Section titled “Bag:Delay”[Server] | [Client]
Runs a callback later, cancelled outright if the bag closes first.
function Bag:Delay(seconds: number, callback: (...any) -> (), ...: any): threadBag:Bind
Section titled “Bag:Bind”[Client]
Binds a callback to render step, unbound by name when the bag closes.
function Bag:Bind(name: string, priority: number, callback: (delta: number) -> ())Throws on the server.
Bag:Clone
Section titled “Bag:Clone”[Server] | [Client]
Clones an instance and holds the copy. The original is left alone.
function Bag:Clone<T>(instance: T & Instance): TBag:Extend
Section titled “Bag:Extend”[Server] | [Client]
Makes a bag inside this one, closing when this one does.
function Bag:Extend(): BagBag:Get
Section titled “Bag:Get”[Server] | [Client]
Returns what is held under a name, without letting it out.
function Bag:Get(key: any): anyBag:Remove
Section titled “Bag:Remove”[Server] | [Client]
Closes one entry now and lets it out, leaving the rest of the bag alone.
function Bag:Remove(what: any): booleanTakes the key it was named with, or the object itself. Answers false when the
bag was not holding it.
Bag:Release
Section titled “Bag:Release”[Server] | [Client]
Lets one entry out without closing it, handing ownership back to the caller.
function Bag:Release(what: any): booleanBag:Count
Section titled “Bag:Count”[Server] | [Client]
Returns how many things the bag is holding.
function Bag:Count(): numberBag:IsEmpty
Section titled “Bag:IsEmpty”[Server] | [Client]
Answers whether the bag is holding nothing at all.
function Bag:IsEmpty(): booleanBag:IsDestroyed
Section titled “Bag:IsDestroyed”[Server] | [Client]
Answers whether the bag has been destroyed and can no longer be added to.
function Bag:IsDestroyed(): booleanBag:AttachTo
Section titled “Bag:AttachTo”[Server] | [Client]
Closes the bag when an instance goes.
function Bag:AttachTo(instance: Instance): anyReturns
any - The connection watching the instance, or nil when the bag closed at
once because the instance is not in game.
Throws when the value is not an instance.
Bag:Detach
Section titled “Bag:Detach”[Server] | [Client]
Stops watching whatever instance the bag was attached to, leaving the bag open.
function Bag:Detach()Bag:Clean
Section titled “Bag:Clean”[Server] | [Client]
Closes everything held and leaves the bag ready to be used again.
function Bag:Clean()Bag:Destroy
Section titled “Bag:Destroy”[Server] | [Client]
Closes everything held and makes the bag unusable.
function Bag:Destroy()