roblox-opencode 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -122
- package/commands/setup-game.md +108 -108
- package/commands/sync-check.md +53 -53
- package/core/roblox-core.md +93 -93
- package/dist/server.js +189 -167
- package/package.json +35 -35
- package/skills/roblox-analytics/SKILL.md +277 -277
- package/skills/roblox-analytics/references/event-batcher.luau +75 -75
- package/skills/roblox-animation-vfx/SKILL.md +1325 -1325
- package/skills/roblox-architecture/SKILL.md +863 -863
- package/skills/roblox-architecture/references/combat-systems.md +1381 -1381
- package/skills/roblox-code-review/SKILL.md +686 -686
- package/skills/roblox-data/SKILL.md +889 -889
- package/skills/roblox-data/references/inventory-systems.md +1729 -1729
- package/skills/roblox-debug/SKILL.md +98 -98
- package/skills/roblox-gui/SKILL.md +1103 -1103
- package/skills/roblox-gui-fusion/SKILL.md +150 -150
- package/skills/roblox-gui-fusion/references/inventory.luau +427 -427
- package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -579
- package/skills/roblox-gui-fusion/references/shop.luau +411 -411
- package/skills/roblox-luau-mastery/SKILL.md +1519 -1519
- package/skills/roblox-monetization/SKILL.md +1084 -1084
- package/skills/roblox-monetization/references/process-receipt.luau +131 -131
- package/skills/roblox-networking/SKILL.md +669 -669
- package/skills/roblox-networking/references/remote-validator.luau +193 -193
- package/skills/roblox-publish-checklist/SKILL.md +127 -127
- package/skills/roblox-runtime/SKILL.md +753 -753
- package/skills/roblox-sharp-edges/SKILL.md +294 -294
- package/skills/roblox-sync/SKILL.md +126 -126
- package/skills/roblox-testing/SKILL.md +943 -943
- package/skills/roblox-tooling/SKILL.md +149 -149
- package/vendor/LICENSES/ProfileStore-LICENSE +201 -201
- package/vendor/LICENSES/RbxUtil-LICENSE +7 -7
- package/vendor/LICENSES/promise-LICENSE +20 -20
- package/vendor/LICENSES/t-LICENSE +21 -21
- package/vendor/LICENSES/testez-LICENSE +200 -200
- package/vendor/README.md +83 -83
- package/vendor/fusion/Animation/ExternalTime.luau +83 -83
- package/vendor/fusion/Animation/Spring.luau +321 -321
- package/vendor/fusion/Animation/Stopwatch.luau +127 -127
- package/vendor/fusion/Animation/Tween.luau +187 -187
- package/vendor/fusion/Animation/getTweenDuration.luau +27 -27
- package/vendor/fusion/Animation/getTweenRatio.luau +47 -47
- package/vendor/fusion/Animation/lerpType.luau +163 -163
- package/vendor/fusion/Animation/packType.luau +99 -99
- package/vendor/fusion/Animation/springCoefficients.luau +80 -80
- package/vendor/fusion/Animation/unpackType.luau +102 -102
- package/vendor/fusion/Colour/Oklab.luau +70 -70
- package/vendor/fusion/Colour/sRGB.luau +54 -54
- package/vendor/fusion/External.luau +167 -167
- package/vendor/fusion/ExternalDebug.luau +69 -69
- package/vendor/fusion/Graph/Observer.luau +113 -113
- package/vendor/fusion/Graph/castToGraph.luau +28 -28
- package/vendor/fusion/Graph/change.luau +80 -80
- package/vendor/fusion/Graph/depend.luau +32 -32
- package/vendor/fusion/Graph/evaluate.luau +55 -55
- package/vendor/fusion/Instances/Attribute.luau +57 -57
- package/vendor/fusion/Instances/AttributeChange.luau +46 -46
- package/vendor/fusion/Instances/AttributeOut.luau +63 -63
- package/vendor/fusion/Instances/Child.luau +21 -21
- package/vendor/fusion/Instances/Children.luau +147 -147
- package/vendor/fusion/Instances/Hydrate.luau +32 -32
- package/vendor/fusion/Instances/New.luau +52 -52
- package/vendor/fusion/Instances/OnChange.luau +49 -49
- package/vendor/fusion/Instances/OnEvent.luau +53 -53
- package/vendor/fusion/Instances/Out.luau +69 -69
- package/vendor/fusion/Instances/applyInstanceProps.luau +148 -148
- package/vendor/fusion/Instances/defaultProps.luau +194 -194
- package/vendor/fusion/LICENSE +21 -21
- package/vendor/fusion/Logging/formatError.luau +48 -48
- package/vendor/fusion/Logging/messages.luau +51 -51
- package/vendor/fusion/Logging/parseError.luau +24 -24
- package/vendor/fusion/Memory/checkLifetime.luau +133 -133
- package/vendor/fusion/Memory/deriveScope.luau +23 -23
- package/vendor/fusion/Memory/deriveScopeImpl.luau +44 -44
- package/vendor/fusion/Memory/doCleanup.luau +78 -78
- package/vendor/fusion/Memory/innerScope.luau +33 -33
- package/vendor/fusion/Memory/legacyCleanup.luau +17 -17
- package/vendor/fusion/Memory/needsDestruction.luau +16 -16
- package/vendor/fusion/Memory/poisonScope.luau +33 -33
- package/vendor/fusion/Memory/scopePool.luau +54 -54
- package/vendor/fusion/Memory/scoped.luau +26 -26
- package/vendor/fusion/Memory/whichLivesLonger.luau +74 -74
- package/vendor/fusion/RobloxExternal.luau +97 -97
- package/vendor/fusion/State/Computed.luau +138 -138
- package/vendor/fusion/State/For/Disassembly.luau +210 -210
- package/vendor/fusion/State/For/ForTypes.luau +30 -30
- package/vendor/fusion/State/For/init.luau +109 -109
- package/vendor/fusion/State/ForKeys.luau +93 -93
- package/vendor/fusion/State/ForPairs.luau +96 -96
- package/vendor/fusion/State/ForValues.luau +93 -93
- package/vendor/fusion/State/Value.luau +87 -87
- package/vendor/fusion/State/castToState.luau +25 -25
- package/vendor/fusion/State/peek.luau +30 -30
- package/vendor/fusion/Types.luau +314 -314
- package/vendor/fusion/Utility/Contextual.luau +90 -90
- package/vendor/fusion/Utility/Safe.luau +22 -22
- package/vendor/fusion/Utility/isSimilar.luau +29 -29
- package/vendor/fusion/Utility/merge.luau +35 -35
- package/vendor/fusion/Utility/nameOf.luau +34 -34
- package/vendor/fusion/Utility/never.luau +13 -13
- package/vendor/fusion/Utility/nicknames.luau +10 -10
- package/vendor/fusion/Utility/xtypeof.luau +26 -26
- package/vendor/fusion/init.luau +82 -82
- package/vendor/profilestore/init.luau +2242 -2242
- package/vendor/promise/init.luau +1982 -1982
- package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -25
- package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -228
- package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -269
- package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -223
- package/vendor/rbxutil/buffer-util/Types.luau +60 -60
- package/vendor/rbxutil/buffer-util/index.d.ts +153 -153
- package/vendor/rbxutil/buffer-util/init.luau +41 -41
- package/vendor/rbxutil/buffer-util/package.json +16 -16
- package/vendor/rbxutil/buffer-util/wally.toml +9 -9
- package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -232
- package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -156
- package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -109
- package/vendor/rbxutil/comm/Client/init.luau +135 -135
- package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -295
- package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -211
- package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -211
- package/vendor/rbxutil/comm/Server/init.luau +140 -140
- package/vendor/rbxutil/comm/Types.luau +18 -18
- package/vendor/rbxutil/comm/Util.luau +27 -27
- package/vendor/rbxutil/comm/init.luau +35 -35
- package/vendor/rbxutil/comm/wally.toml +13 -13
- package/vendor/rbxutil/component/init.luau +759 -759
- package/vendor/rbxutil/component/init.test.luau +311 -311
- package/vendor/rbxutil/component/wally.toml +14 -14
- package/vendor/rbxutil/concur/init.luau +542 -542
- package/vendor/rbxutil/concur/init.test.luau +364 -364
- package/vendor/rbxutil/concur/wally.toml +8 -8
- package/vendor/rbxutil/enum-list/init.luau +101 -101
- package/vendor/rbxutil/enum-list/init.test.luau +91 -91
- package/vendor/rbxutil/enum-list/wally.toml +8 -8
- package/vendor/rbxutil/find/index.d.ts +20 -20
- package/vendor/rbxutil/find/init.luau +44 -44
- package/vendor/rbxutil/find/package.json +17 -17
- package/vendor/rbxutil/find/wally.toml +8 -8
- package/vendor/rbxutil/input/Gamepad.luau +559 -559
- package/vendor/rbxutil/input/Keyboard.luau +124 -124
- package/vendor/rbxutil/input/Mouse.luau +278 -278
- package/vendor/rbxutil/input/PreferredInput.luau +91 -91
- package/vendor/rbxutil/input/Touch.luau +120 -120
- package/vendor/rbxutil/input/init.luau +33 -33
- package/vendor/rbxutil/input/wally.toml +12 -12
- package/vendor/rbxutil/loader/index.d.ts +15 -15
- package/vendor/rbxutil/loader/init.luau +137 -137
- package/vendor/rbxutil/loader/wally.toml +8 -8
- package/vendor/rbxutil/log/index.d.ts +38 -38
- package/vendor/rbxutil/log/init.luau +746 -746
- package/vendor/rbxutil/log/wally.toml +8 -8
- package/vendor/rbxutil/net/init.luau +190 -190
- package/vendor/rbxutil/net/wally.toml +8 -8
- package/vendor/rbxutil/option/index.d.ts +44 -44
- package/vendor/rbxutil/option/init.luau +489 -489
- package/vendor/rbxutil/option/init.test.luau +342 -342
- package/vendor/rbxutil/option/wally.toml +8 -8
- package/vendor/rbxutil/pid/index.d.ts +53 -53
- package/vendor/rbxutil/pid/init.luau +195 -195
- package/vendor/rbxutil/pid/package.json +16 -16
- package/vendor/rbxutil/pid/wally.toml +9 -9
- package/vendor/rbxutil/quaternion/index.d.ts +117 -117
- package/vendor/rbxutil/quaternion/init.luau +570 -570
- package/vendor/rbxutil/quaternion/package.json +16 -16
- package/vendor/rbxutil/quaternion/wally.toml +9 -9
- package/vendor/rbxutil/query/index.d.ts +43 -43
- package/vendor/rbxutil/query/init.luau +117 -117
- package/vendor/rbxutil/query/package.json +18 -18
- package/vendor/rbxutil/query/wally.toml +9 -9
- package/vendor/rbxutil/sequent/index.d.ts +28 -28
- package/vendor/rbxutil/sequent/init.luau +340 -340
- package/vendor/rbxutil/sequent/package.json +16 -16
- package/vendor/rbxutil/sequent/wally.toml +9 -9
- package/vendor/rbxutil/ser/init.luau +175 -175
- package/vendor/rbxutil/ser/init.test.luau +50 -50
- package/vendor/rbxutil/ser/wally.toml +11 -11
- package/vendor/rbxutil/shake/index.d.ts +36 -36
- package/vendor/rbxutil/shake/init.luau +532 -532
- package/vendor/rbxutil/shake/init.test.luau +267 -267
- package/vendor/rbxutil/shake/package.json +16 -16
- package/vendor/rbxutil/shake/wally.toml +9 -9
- package/vendor/rbxutil/signal/index.d.ts +100 -100
- package/vendor/rbxutil/signal/init.luau +432 -432
- package/vendor/rbxutil/signal/init.test.luau +190 -190
- package/vendor/rbxutil/signal/package.json +17 -17
- package/vendor/rbxutil/signal/wally.toml +9 -9
- package/vendor/rbxutil/silo/TableWatcher.luau +65 -65
- package/vendor/rbxutil/silo/Util.luau +55 -55
- package/vendor/rbxutil/silo/init.luau +338 -338
- package/vendor/rbxutil/silo/init.test.luau +215 -215
- package/vendor/rbxutil/silo/wally.toml +8 -8
- package/vendor/rbxutil/spring/index.d.ts +40 -40
- package/vendor/rbxutil/spring/init.luau +97 -97
- package/vendor/rbxutil/spring/package.json +17 -17
- package/vendor/rbxutil/spring/wally.toml +8 -8
- package/vendor/rbxutil/stream/index.d.ts +88 -88
- package/vendor/rbxutil/stream/init.luau +597 -597
- package/vendor/rbxutil/stream/package.json +18 -18
- package/vendor/rbxutil/stream/wally.toml +9 -9
- package/vendor/rbxutil/streamable/Streamable.luau +202 -202
- package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -80
- package/vendor/rbxutil/streamable/init.luau +8 -8
- package/vendor/rbxutil/streamable/wally.toml +12 -12
- package/vendor/rbxutil/symbol/init.luau +56 -56
- package/vendor/rbxutil/symbol/init.test.luau +37 -37
- package/vendor/rbxutil/symbol/wally.toml +8 -8
- package/vendor/rbxutil/table-util/init.luau +938 -938
- package/vendor/rbxutil/table-util/init.test.luau +439 -439
- package/vendor/rbxutil/task-queue/index.d.ts +27 -27
- package/vendor/rbxutil/task-queue/init.luau +97 -97
- package/vendor/rbxutil/task-queue/wally.toml +8 -8
- package/vendor/rbxutil/timer/index.d.ts +81 -81
- package/vendor/rbxutil/timer/init.luau +249 -249
- package/vendor/rbxutil/timer/init.test.luau +73 -73
- package/vendor/rbxutil/timer/wally.toml +11 -11
- package/vendor/rbxutil/tree/index.d.ts +15 -15
- package/vendor/rbxutil/tree/init.luau +137 -137
- package/vendor/rbxutil/tree/wally.toml +8 -8
- package/vendor/rbxutil/trove/index.d.ts +46 -46
- package/vendor/rbxutil/trove/init.luau +787 -787
- package/vendor/rbxutil/trove/init.test.luau +203 -203
- package/vendor/rbxutil/trove/wally.toml +8 -8
- package/vendor/rbxutil/typed-remote/init.luau +196 -196
- package/vendor/rbxutil/typed-remote/wally.toml +8 -8
- package/vendor/rbxutil/wait-for/index.d.ts +17 -17
- package/vendor/rbxutil/wait-for/init.luau +257 -257
- package/vendor/rbxutil/wait-for/init.test.luau +182 -182
- package/vendor/rbxutil/wait-for/wally.toml +11 -11
- package/vendor/t/t.lua +1350 -1350
- package/vendor/testez/Context.lua +26 -26
- package/vendor/testez/Expectation.lua +311 -311
- package/vendor/testez/ExpectationContext.lua +38 -38
- package/vendor/testez/LifecycleHooks.lua +89 -89
- package/vendor/testez/Reporters/TeamCityReporter.lua +101 -101
- package/vendor/testez/Reporters/TextReporter.lua +105 -105
- package/vendor/testez/Reporters/TextReporterQuiet.lua +96 -96
- package/vendor/testez/TestBootstrap.lua +146 -146
- package/vendor/testez/TestEnum.lua +27 -27
- package/vendor/testez/TestPlan.lua +304 -304
- package/vendor/testez/TestPlanner.lua +39 -39
- package/vendor/testez/TestResults.lua +111 -111
- package/vendor/testez/TestRunner.lua +188 -188
- package/vendor/testez/TestSession.lua +243 -243
- package/vendor/testez/init.lua +39 -39
|
@@ -1,340 +1,340 @@
|
|
|
1
|
-
export type Sequent<T> = {
|
|
2
|
-
Fire: (self: Sequent<T>, T) -> (),
|
|
3
|
-
Connect: (self: Sequent<T>, callback: (SequentEvent<T>) -> ()) -> SequentConnection,
|
|
4
|
-
Once: (self: Sequent<T>, callback: (SequentEvent<T>) -> ()) -> SequentConnection,
|
|
5
|
-
Cancel: (self: Sequent<T>) -> (),
|
|
6
|
-
Destroy: (self: Sequent<T>) -> (),
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
--[=[
|
|
10
|
-
@interface SequentConnection
|
|
11
|
-
@within Sequent
|
|
12
|
-
.Connected boolean
|
|
13
|
-
.Disconnect (self: SequentConnection) -> ()
|
|
14
|
-
|
|
15
|
-
```lua
|
|
16
|
-
print(sequent.Connected)
|
|
17
|
-
sequent:Disconnect()
|
|
18
|
-
```
|
|
19
|
-
]=]
|
|
20
|
-
export type SequentConnection = {
|
|
21
|
-
Connected: boolean,
|
|
22
|
-
Disconnect: (self: SequentConnection) -> (),
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
--[=[
|
|
26
|
-
@interface SequentEvent<T>
|
|
27
|
-
@within Sequent
|
|
28
|
-
.Value T
|
|
29
|
-
.Cancellable boolean
|
|
30
|
-
.Cancel (self: SequentEvent<T>) -> ()
|
|
31
|
-
|
|
32
|
-
Events are passed to connected callbacks when sequents are fired. Events
|
|
33
|
-
can be cancelled as well, which prevents the event from propagating to
|
|
34
|
-
other connected callbacks during the same firing. This can be used to
|
|
35
|
-
sink events if desired.
|
|
36
|
-
|
|
37
|
-
```lua
|
|
38
|
-
sequent:Connect(function(event)
|
|
39
|
-
print(event.Value)
|
|
40
|
-
event:Cancel()
|
|
41
|
-
end, 0)
|
|
42
|
-
```
|
|
43
|
-
]=]
|
|
44
|
-
export type SequentEvent<T> = {
|
|
45
|
-
Value: T,
|
|
46
|
-
Cancellable: boolean,
|
|
47
|
-
Cancel: (self: SequentEvent<T>) -> (),
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
type InternalSequentConnection = SequentConnection & {
|
|
51
|
-
_priority: number,
|
|
52
|
-
_sequent: Sequent<unknown>,
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
-----------------------------------------------------------------------------
|
|
56
|
-
-- Connection
|
|
57
|
-
local SequentConnection = {}
|
|
58
|
-
SequentConnection.__index = SequentConnection
|
|
59
|
-
|
|
60
|
-
function SequentConnection:Disconnect()
|
|
61
|
-
self._sequent:_disconnect(self)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
-----------------------------------------------------------------------------
|
|
65
|
-
-- Sequent
|
|
66
|
-
|
|
67
|
-
--[=[
|
|
68
|
-
@interface Priority
|
|
69
|
-
@within Sequent
|
|
70
|
-
.Highest math.huge
|
|
71
|
-
.High 1000
|
|
72
|
-
.Normal 0
|
|
73
|
-
.Low -1000
|
|
74
|
-
.Lowest -math.huge
|
|
75
|
-
|
|
76
|
-
```lua
|
|
77
|
-
sequent:Connect(fn, Sequent.Priority.Highest)
|
|
78
|
-
```
|
|
79
|
-
]=]
|
|
80
|
-
local Priority = {
|
|
81
|
-
Highest = math.huge,
|
|
82
|
-
High = 1000,
|
|
83
|
-
Normal = 0,
|
|
84
|
-
Low = -1000,
|
|
85
|
-
Lowest = -math.huge,
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
--[=[
|
|
89
|
-
@class Sequent
|
|
90
|
-
|
|
91
|
-
Sequent is a signal-like structure that executes connections in a serial nature. Each
|
|
92
|
-
connection must fully complete before the next is run. Connections can be prioritized
|
|
93
|
-
and cancelled.
|
|
94
|
-
|
|
95
|
-
```lua
|
|
96
|
-
local sequent = Sequent.new()
|
|
97
|
-
|
|
98
|
-
sequent:Connect(
|
|
99
|
-
function(event)
|
|
100
|
-
print("Got value", event.Value)
|
|
101
|
-
event:Cancel()
|
|
102
|
-
end,
|
|
103
|
-
Sequent.Priority.Highest,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
sequent:Connect(
|
|
107
|
-
function(event)
|
|
108
|
-
print("This won't print!")
|
|
109
|
-
end,
|
|
110
|
-
Sequent.Priority.Lowest,
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
sequent:Fire("Test")
|
|
114
|
-
```
|
|
115
|
-
]=]
|
|
116
|
-
local Sequent = {}
|
|
117
|
-
Sequent.__index = Sequent
|
|
118
|
-
|
|
119
|
-
--[=[
|
|
120
|
-
Constructs a new Sequent. If `cancellable` is `true`, then
|
|
121
|
-
connected handlers can cancel event propagation.
|
|
122
|
-
]=]
|
|
123
|
-
function Sequent.new<T>(cancellable: boolean?): Sequent<T>
|
|
124
|
-
local self = setmetatable({
|
|
125
|
-
_connections = {},
|
|
126
|
-
_firing = false,
|
|
127
|
-
_queuedDisconnect = false,
|
|
128
|
-
|
|
129
|
-
_firingThread = nil,
|
|
130
|
-
_taskThread = nil,
|
|
131
|
-
|
|
132
|
-
_cancellable = not not cancellable,
|
|
133
|
-
}, Sequent)
|
|
134
|
-
|
|
135
|
-
return self
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
--[=[
|
|
139
|
-
@yields
|
|
140
|
-
Fires the Sequent with the given value.
|
|
141
|
-
|
|
142
|
-
This method will yield until all connections complete. Errors will
|
|
143
|
-
bubble up if they occur within a connection.
|
|
144
|
-
]=]
|
|
145
|
-
function Sequent:Fire<T>(value: T)
|
|
146
|
-
assert(not self._firing, "cannot fire while already firing")
|
|
147
|
-
self._firing = true
|
|
148
|
-
|
|
149
|
-
local cancelled = false
|
|
150
|
-
local event: SequentEvent<T> = table.freeze({
|
|
151
|
-
Value = value,
|
|
152
|
-
Cancellable = self._cancellable,
|
|
153
|
-
Cancel = function(_evt)
|
|
154
|
-
if not self._cancellable then
|
|
155
|
-
warn("attempted to cancel non-cancellable event")
|
|
156
|
-
return
|
|
157
|
-
end
|
|
158
|
-
cancelled = true
|
|
159
|
-
end,
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
local thread = coroutine.running()
|
|
163
|
-
self._firingThread = thread
|
|
164
|
-
for _, connection in self._connections do
|
|
165
|
-
if not connection.Connected then
|
|
166
|
-
continue
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
-- Run the task:
|
|
170
|
-
local success, err = nil, nil
|
|
171
|
-
local taskThread = task.spawn(function()
|
|
172
|
-
self._taskThread = coroutine.running()
|
|
173
|
-
|
|
174
|
-
local s, e = pcall(function()
|
|
175
|
-
connection._callback(event)
|
|
176
|
-
end)
|
|
177
|
-
|
|
178
|
-
self._taskThread = nil
|
|
179
|
-
|
|
180
|
-
-- Resume the parent thread if it yielded:
|
|
181
|
-
if coroutine.status(thread) == "suspended" then
|
|
182
|
-
task.spawn(thread, s, e)
|
|
183
|
-
else
|
|
184
|
-
success, err = s, e
|
|
185
|
-
end
|
|
186
|
-
end)
|
|
187
|
-
|
|
188
|
-
-- If the task thread yielded, yield this thread too:
|
|
189
|
-
if success == nil then
|
|
190
|
-
success, err = coroutine.yield()
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
self._firingThread = nil
|
|
194
|
-
|
|
195
|
-
-- Throw error if the task failed:
|
|
196
|
-
if not success then
|
|
197
|
-
error(debug.traceback(taskThread, tostring(err)))
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
if cancelled then
|
|
201
|
-
break
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
-- If connections were disconnected while firing connections, disconnect them now:
|
|
206
|
-
if self._queuedDisconnect then
|
|
207
|
-
self._queuedDisconnect = false
|
|
208
|
-
for i = #self._connections, 1, -1 do
|
|
209
|
-
local connection = self._connections[i]
|
|
210
|
-
if not connection.Connected then
|
|
211
|
-
self:_removeConnection(connection)
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
self._firing = false
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
--[=[
|
|
220
|
-
Returns `true` if the Sequent is currently firing.
|
|
221
|
-
]=]
|
|
222
|
-
function Sequent:IsFiring(): boolean
|
|
223
|
-
return self._firing
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
--[=[
|
|
227
|
-
Connects a callback to the Sequent, which gets called anytime `Fire`
|
|
228
|
-
is called.
|
|
229
|
-
|
|
230
|
-
The given `priority` indicates the firing priority of the callback. Higher
|
|
231
|
-
priority values will be run first. There are a few defaults available via
|
|
232
|
-
`Sequent.Priority`.
|
|
233
|
-
]=]
|
|
234
|
-
function Sequent:Connect(callback: (...unknown) -> (), priority: number): SequentConnection
|
|
235
|
-
assert(not self._firing, "cannot connect while firing")
|
|
236
|
-
|
|
237
|
-
local connection = setmetatable({
|
|
238
|
-
Connected = true,
|
|
239
|
-
_callback = callback,
|
|
240
|
-
_priority = priority,
|
|
241
|
-
_sequent = self,
|
|
242
|
-
}, SequentConnection)
|
|
243
|
-
|
|
244
|
-
-- Find the correct index to remain sorted by priority:
|
|
245
|
-
local idx = #self._connections + 1
|
|
246
|
-
for i, c: InternalSequentConnection in self._connections do
|
|
247
|
-
if c._priority < priority then
|
|
248
|
-
idx = i
|
|
249
|
-
break
|
|
250
|
-
end
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
table.insert(self._connections, idx, connection)
|
|
254
|
-
|
|
255
|
-
return connection
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
--[=[
|
|
259
|
-
`Once()` is the same as `Connect()`, except the connection is automatically
|
|
260
|
-
disconnected after being fired once.
|
|
261
|
-
]=]
|
|
262
|
-
function Sequent:Once(callback: (...unknown) -> (), priority: number): SequentConnection
|
|
263
|
-
local connection: SequentConnection
|
|
264
|
-
|
|
265
|
-
connection = self:Connect(function(...)
|
|
266
|
-
if not connection.Connected then
|
|
267
|
-
return
|
|
268
|
-
end
|
|
269
|
-
connection:Disconnect()
|
|
270
|
-
callback(...)
|
|
271
|
-
end, priority)
|
|
272
|
-
|
|
273
|
-
return connection
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
--[=[
|
|
277
|
-
Cancels a currently-firing Sequent.
|
|
278
|
-
]=]
|
|
279
|
-
function Sequent:Cancel()
|
|
280
|
-
if not self._firing then
|
|
281
|
-
return
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
if self._taskThread == coroutine.running() then
|
|
285
|
-
error("cannot cancel sequent from connected task", 2)
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
if self._taskThread then
|
|
289
|
-
-- pcall needed as the task thread may have yielded from a call to
|
|
290
|
-
-- a roblox service, which will throw an error when calling task.cancel:
|
|
291
|
-
pcall(function()
|
|
292
|
-
task.cancel(self._taskThread)
|
|
293
|
-
end)
|
|
294
|
-
self._taskThread = nil
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
if self._firingThread then
|
|
298
|
-
local thread = self._firingThread
|
|
299
|
-
self._firingThread = nil
|
|
300
|
-
task.spawn(thread, true)
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
--[=[
|
|
305
|
-
Cleans up the Sequent. All connections are disconnected. The Sequent is cancelled
|
|
306
|
-
if it is currently firing.
|
|
307
|
-
]=]
|
|
308
|
-
function Sequent:Destroy()
|
|
309
|
-
self:Cancel()
|
|
310
|
-
|
|
311
|
-
for _, connection in self._connections do
|
|
312
|
-
connection.Connected = false
|
|
313
|
-
end
|
|
314
|
-
end
|
|
315
|
-
|
|
316
|
-
function Sequent:_disconnect(connection)
|
|
317
|
-
if not connection.Connected then
|
|
318
|
-
return
|
|
319
|
-
end
|
|
320
|
-
connection.Connected = false
|
|
321
|
-
|
|
322
|
-
if self._firing then
|
|
323
|
-
self._queuedDisconnect = true
|
|
324
|
-
return
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
self:_removeConnection(connection)
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
function Sequent:_removeConnection(connection)
|
|
331
|
-
local idx = table.find(self._connections, connection)
|
|
332
|
-
if idx then
|
|
333
|
-
table.remove(self._connections, idx)
|
|
334
|
-
end
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
return table.freeze({
|
|
338
|
-
new = Sequent.new,
|
|
339
|
-
Priority = Priority,
|
|
340
|
-
})
|
|
1
|
+
export type Sequent<T> = {
|
|
2
|
+
Fire: (self: Sequent<T>, T) -> (),
|
|
3
|
+
Connect: (self: Sequent<T>, callback: (SequentEvent<T>) -> ()) -> SequentConnection,
|
|
4
|
+
Once: (self: Sequent<T>, callback: (SequentEvent<T>) -> ()) -> SequentConnection,
|
|
5
|
+
Cancel: (self: Sequent<T>) -> (),
|
|
6
|
+
Destroy: (self: Sequent<T>) -> (),
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
--[=[
|
|
10
|
+
@interface SequentConnection
|
|
11
|
+
@within Sequent
|
|
12
|
+
.Connected boolean
|
|
13
|
+
.Disconnect (self: SequentConnection) -> ()
|
|
14
|
+
|
|
15
|
+
```lua
|
|
16
|
+
print(sequent.Connected)
|
|
17
|
+
sequent:Disconnect()
|
|
18
|
+
```
|
|
19
|
+
]=]
|
|
20
|
+
export type SequentConnection = {
|
|
21
|
+
Connected: boolean,
|
|
22
|
+
Disconnect: (self: SequentConnection) -> (),
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
--[=[
|
|
26
|
+
@interface SequentEvent<T>
|
|
27
|
+
@within Sequent
|
|
28
|
+
.Value T
|
|
29
|
+
.Cancellable boolean
|
|
30
|
+
.Cancel (self: SequentEvent<T>) -> ()
|
|
31
|
+
|
|
32
|
+
Events are passed to connected callbacks when sequents are fired. Events
|
|
33
|
+
can be cancelled as well, which prevents the event from propagating to
|
|
34
|
+
other connected callbacks during the same firing. This can be used to
|
|
35
|
+
sink events if desired.
|
|
36
|
+
|
|
37
|
+
```lua
|
|
38
|
+
sequent:Connect(function(event)
|
|
39
|
+
print(event.Value)
|
|
40
|
+
event:Cancel()
|
|
41
|
+
end, 0)
|
|
42
|
+
```
|
|
43
|
+
]=]
|
|
44
|
+
export type SequentEvent<T> = {
|
|
45
|
+
Value: T,
|
|
46
|
+
Cancellable: boolean,
|
|
47
|
+
Cancel: (self: SequentEvent<T>) -> (),
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type InternalSequentConnection = SequentConnection & {
|
|
51
|
+
_priority: number,
|
|
52
|
+
_sequent: Sequent<unknown>,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
-----------------------------------------------------------------------------
|
|
56
|
+
-- Connection
|
|
57
|
+
local SequentConnection = {}
|
|
58
|
+
SequentConnection.__index = SequentConnection
|
|
59
|
+
|
|
60
|
+
function SequentConnection:Disconnect()
|
|
61
|
+
self._sequent:_disconnect(self)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
-----------------------------------------------------------------------------
|
|
65
|
+
-- Sequent
|
|
66
|
+
|
|
67
|
+
--[=[
|
|
68
|
+
@interface Priority
|
|
69
|
+
@within Sequent
|
|
70
|
+
.Highest math.huge
|
|
71
|
+
.High 1000
|
|
72
|
+
.Normal 0
|
|
73
|
+
.Low -1000
|
|
74
|
+
.Lowest -math.huge
|
|
75
|
+
|
|
76
|
+
```lua
|
|
77
|
+
sequent:Connect(fn, Sequent.Priority.Highest)
|
|
78
|
+
```
|
|
79
|
+
]=]
|
|
80
|
+
local Priority = {
|
|
81
|
+
Highest = math.huge,
|
|
82
|
+
High = 1000,
|
|
83
|
+
Normal = 0,
|
|
84
|
+
Low = -1000,
|
|
85
|
+
Lowest = -math.huge,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
--[=[
|
|
89
|
+
@class Sequent
|
|
90
|
+
|
|
91
|
+
Sequent is a signal-like structure that executes connections in a serial nature. Each
|
|
92
|
+
connection must fully complete before the next is run. Connections can be prioritized
|
|
93
|
+
and cancelled.
|
|
94
|
+
|
|
95
|
+
```lua
|
|
96
|
+
local sequent = Sequent.new()
|
|
97
|
+
|
|
98
|
+
sequent:Connect(
|
|
99
|
+
function(event)
|
|
100
|
+
print("Got value", event.Value)
|
|
101
|
+
event:Cancel()
|
|
102
|
+
end,
|
|
103
|
+
Sequent.Priority.Highest,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
sequent:Connect(
|
|
107
|
+
function(event)
|
|
108
|
+
print("This won't print!")
|
|
109
|
+
end,
|
|
110
|
+
Sequent.Priority.Lowest,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
sequent:Fire("Test")
|
|
114
|
+
```
|
|
115
|
+
]=]
|
|
116
|
+
local Sequent = {}
|
|
117
|
+
Sequent.__index = Sequent
|
|
118
|
+
|
|
119
|
+
--[=[
|
|
120
|
+
Constructs a new Sequent. If `cancellable` is `true`, then
|
|
121
|
+
connected handlers can cancel event propagation.
|
|
122
|
+
]=]
|
|
123
|
+
function Sequent.new<T>(cancellable: boolean?): Sequent<T>
|
|
124
|
+
local self = setmetatable({
|
|
125
|
+
_connections = {},
|
|
126
|
+
_firing = false,
|
|
127
|
+
_queuedDisconnect = false,
|
|
128
|
+
|
|
129
|
+
_firingThread = nil,
|
|
130
|
+
_taskThread = nil,
|
|
131
|
+
|
|
132
|
+
_cancellable = not not cancellable,
|
|
133
|
+
}, Sequent)
|
|
134
|
+
|
|
135
|
+
return self
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
--[=[
|
|
139
|
+
@yields
|
|
140
|
+
Fires the Sequent with the given value.
|
|
141
|
+
|
|
142
|
+
This method will yield until all connections complete. Errors will
|
|
143
|
+
bubble up if they occur within a connection.
|
|
144
|
+
]=]
|
|
145
|
+
function Sequent:Fire<T>(value: T)
|
|
146
|
+
assert(not self._firing, "cannot fire while already firing")
|
|
147
|
+
self._firing = true
|
|
148
|
+
|
|
149
|
+
local cancelled = false
|
|
150
|
+
local event: SequentEvent<T> = table.freeze({
|
|
151
|
+
Value = value,
|
|
152
|
+
Cancellable = self._cancellable,
|
|
153
|
+
Cancel = function(_evt)
|
|
154
|
+
if not self._cancellable then
|
|
155
|
+
warn("attempted to cancel non-cancellable event")
|
|
156
|
+
return
|
|
157
|
+
end
|
|
158
|
+
cancelled = true
|
|
159
|
+
end,
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
local thread = coroutine.running()
|
|
163
|
+
self._firingThread = thread
|
|
164
|
+
for _, connection in self._connections do
|
|
165
|
+
if not connection.Connected then
|
|
166
|
+
continue
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
-- Run the task:
|
|
170
|
+
local success, err = nil, nil
|
|
171
|
+
local taskThread = task.spawn(function()
|
|
172
|
+
self._taskThread = coroutine.running()
|
|
173
|
+
|
|
174
|
+
local s, e = pcall(function()
|
|
175
|
+
connection._callback(event)
|
|
176
|
+
end)
|
|
177
|
+
|
|
178
|
+
self._taskThread = nil
|
|
179
|
+
|
|
180
|
+
-- Resume the parent thread if it yielded:
|
|
181
|
+
if coroutine.status(thread) == "suspended" then
|
|
182
|
+
task.spawn(thread, s, e)
|
|
183
|
+
else
|
|
184
|
+
success, err = s, e
|
|
185
|
+
end
|
|
186
|
+
end)
|
|
187
|
+
|
|
188
|
+
-- If the task thread yielded, yield this thread too:
|
|
189
|
+
if success == nil then
|
|
190
|
+
success, err = coroutine.yield()
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
self._firingThread = nil
|
|
194
|
+
|
|
195
|
+
-- Throw error if the task failed:
|
|
196
|
+
if not success then
|
|
197
|
+
error(debug.traceback(taskThread, tostring(err)))
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
if cancelled then
|
|
201
|
+
break
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
-- If connections were disconnected while firing connections, disconnect them now:
|
|
206
|
+
if self._queuedDisconnect then
|
|
207
|
+
self._queuedDisconnect = false
|
|
208
|
+
for i = #self._connections, 1, -1 do
|
|
209
|
+
local connection = self._connections[i]
|
|
210
|
+
if not connection.Connected then
|
|
211
|
+
self:_removeConnection(connection)
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
self._firing = false
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
--[=[
|
|
220
|
+
Returns `true` if the Sequent is currently firing.
|
|
221
|
+
]=]
|
|
222
|
+
function Sequent:IsFiring(): boolean
|
|
223
|
+
return self._firing
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
--[=[
|
|
227
|
+
Connects a callback to the Sequent, which gets called anytime `Fire`
|
|
228
|
+
is called.
|
|
229
|
+
|
|
230
|
+
The given `priority` indicates the firing priority of the callback. Higher
|
|
231
|
+
priority values will be run first. There are a few defaults available via
|
|
232
|
+
`Sequent.Priority`.
|
|
233
|
+
]=]
|
|
234
|
+
function Sequent:Connect(callback: (...unknown) -> (), priority: number): SequentConnection
|
|
235
|
+
assert(not self._firing, "cannot connect while firing")
|
|
236
|
+
|
|
237
|
+
local connection = setmetatable({
|
|
238
|
+
Connected = true,
|
|
239
|
+
_callback = callback,
|
|
240
|
+
_priority = priority,
|
|
241
|
+
_sequent = self,
|
|
242
|
+
}, SequentConnection)
|
|
243
|
+
|
|
244
|
+
-- Find the correct index to remain sorted by priority:
|
|
245
|
+
local idx = #self._connections + 1
|
|
246
|
+
for i, c: InternalSequentConnection in self._connections do
|
|
247
|
+
if c._priority < priority then
|
|
248
|
+
idx = i
|
|
249
|
+
break
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
table.insert(self._connections, idx, connection)
|
|
254
|
+
|
|
255
|
+
return connection
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
--[=[
|
|
259
|
+
`Once()` is the same as `Connect()`, except the connection is automatically
|
|
260
|
+
disconnected after being fired once.
|
|
261
|
+
]=]
|
|
262
|
+
function Sequent:Once(callback: (...unknown) -> (), priority: number): SequentConnection
|
|
263
|
+
local connection: SequentConnection
|
|
264
|
+
|
|
265
|
+
connection = self:Connect(function(...)
|
|
266
|
+
if not connection.Connected then
|
|
267
|
+
return
|
|
268
|
+
end
|
|
269
|
+
connection:Disconnect()
|
|
270
|
+
callback(...)
|
|
271
|
+
end, priority)
|
|
272
|
+
|
|
273
|
+
return connection
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
--[=[
|
|
277
|
+
Cancels a currently-firing Sequent.
|
|
278
|
+
]=]
|
|
279
|
+
function Sequent:Cancel()
|
|
280
|
+
if not self._firing then
|
|
281
|
+
return
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
if self._taskThread == coroutine.running() then
|
|
285
|
+
error("cannot cancel sequent from connected task", 2)
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
if self._taskThread then
|
|
289
|
+
-- pcall needed as the task thread may have yielded from a call to
|
|
290
|
+
-- a roblox service, which will throw an error when calling task.cancel:
|
|
291
|
+
pcall(function()
|
|
292
|
+
task.cancel(self._taskThread)
|
|
293
|
+
end)
|
|
294
|
+
self._taskThread = nil
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
if self._firingThread then
|
|
298
|
+
local thread = self._firingThread
|
|
299
|
+
self._firingThread = nil
|
|
300
|
+
task.spawn(thread, true)
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
--[=[
|
|
305
|
+
Cleans up the Sequent. All connections are disconnected. The Sequent is cancelled
|
|
306
|
+
if it is currently firing.
|
|
307
|
+
]=]
|
|
308
|
+
function Sequent:Destroy()
|
|
309
|
+
self:Cancel()
|
|
310
|
+
|
|
311
|
+
for _, connection in self._connections do
|
|
312
|
+
connection.Connected = false
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
function Sequent:_disconnect(connection)
|
|
317
|
+
if not connection.Connected then
|
|
318
|
+
return
|
|
319
|
+
end
|
|
320
|
+
connection.Connected = false
|
|
321
|
+
|
|
322
|
+
if self._firing then
|
|
323
|
+
self._queuedDisconnect = true
|
|
324
|
+
return
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
self:_removeConnection(connection)
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
function Sequent:_removeConnection(connection)
|
|
331
|
+
local idx = table.find(self._connections, connection)
|
|
332
|
+
if idx then
|
|
333
|
+
table.remove(self._connections, idx)
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
return table.freeze({
|
|
338
|
+
new = Sequent.new,
|
|
339
|
+
Priority = Priority,
|
|
340
|
+
})
|