Skip to content
Merged

[Tag] #423

Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion aftman.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
# To add a new tool, add an entry to this table.
[tools]
rojo = "rojo-rbx/rojo@7.4.1"
selene = "Kampfkarren/selene@0.26.1"
selene = "Kampfkarren/selene@0.26.1"
Comment thread
dphfox marked this conversation as resolved.
luau-lsp = "JohnnyMorganz/luau-lsp@1.38.1"
61 changes: 61 additions & 0 deletions src/Instances/Tag.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
--!strict
--!nolint LocalUnused
--!nolint LocalShadow
local task = nil -- Disable usage of Roblox's task scheduler

--[[
A special key for property tables, which allows users to apply custom
CollectionService tags to instances
]]

local Package = script.Parent.Parent
local Types = require(Package.Types)
-- Memory
local checkLifetime = require(Package.Memory.checkLifetime)
-- Graph
local Observer = require(Package.Graph.Observer)
-- State
local castToState = require(Package.State.castToState)
local peek = require(Package.State.peek)

local keyCache: { [string]: Types.SpecialKey } = {}

-- TODO: should this accept tagName: UsedAs<string>?
local function Tag(tagName: string): Types.SpecialKey
local key = keyCache[tagName]
if key == nil then
key = {
type = "SpecialKey",
kind = "Tag",
stage = "self",
apply = function(self: Types.SpecialKey, scope: Types.Scope<unknown>, value: unknown, applyTo: Instance)
if castToState(value) then
local value = value :: Types.StateObject<unknown>
checkLifetime.bOutlivesA(
scope,
applyTo,
value.scope,
value.oldestTask,
checkLifetime.formatters.boundTag,
tagName
)
Observer(scope, value :: any):onBind(function()
if peek(value) == true then
applyTo:AddTag(tagName)
elseif applyTo:HasTag(tagName) then
applyTo:RemoveTag(tagName)
end
end)
else
if value == true then
applyTo:AddTag(tagName)
end
end
end,
}
keyCache[tagName] = key
end
return key
end

return Tag
10 changes: 10 additions & 0 deletions src/Memory/checkLifetime.luau
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ function checkLifetime.formatters.boundAttribute(
return `The {boundName} (bound to the {attribute} attribute)`, `the {selfName} instance`
end

function checkLifetime.formatters.boundTag(
instance: Instance,
bound: unknown,
tag: string
): (string, string)
local selfName = instance.Name
local boundName = nameOf(bound, "value")
return `The {boundName} (bound to the {tag} CollectionService tag)`, `the {selfName} instance`
end

function checkLifetime.formatters.propertyOutputsTo(
instance: Instance,
bound: unknown,
Expand Down
1 change: 1 addition & 0 deletions src/Types.luau
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ export type Fusion = {
Attribute: (attributeName: string) -> SpecialKey,
AttributeChange: (attributeName: string) -> SpecialKey,
AttributeOut: (attributeName: string) -> SpecialKey,
Tag: (tagName: string) -> SpecialKey,
}

export type ExternalProvider = {
Expand Down
7 changes: 4 additions & 3 deletions src/init.luau
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ do
External.setExternalProvider(RobloxExternal)
end

local Fusion: Fusion = table.freeze {
local Fusion: Fusion = table.freeze({
-- General
version = {major = 0, minor = 4, isRelease = false},
version = { major = 0, minor = 4, isRelease = false },
Contextual = require(script.Utility.Contextual),
Safe = require(script.Utility.Safe),

Expand Down Expand Up @@ -73,10 +73,11 @@ local Fusion: Fusion = table.freeze {
OnChange = require(script.Instances.OnChange),
OnEvent = require(script.Instances.OnEvent),
Out = require(script.Instances.Out),
Tag = require(script.Instances.Tag),

-- Animation
Tween = require(script.Animation.Tween),
Spring = require(script.Animation.Spring),
}
})

return Fusion