roblox-opencode 1.0.0 → 1.0.2
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 +877 -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 +1618 -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,211 +1,211 @@
|
|
|
1
|
-
--!strict
|
|
2
|
-
--!nolint LocalUnused
|
|
3
|
-
--!nolint LocalShadow
|
|
4
|
-
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
-
|
|
6
|
-
--[[
|
|
7
|
-
Breaks down an input table into reactive sub-objects for each pair.
|
|
8
|
-
]]
|
|
9
|
-
|
|
10
|
-
local Package = script.Parent.Parent.Parent
|
|
11
|
-
local Types = require(Package.Types)
|
|
12
|
-
local External = require(Package.External)
|
|
13
|
-
-- Graph
|
|
14
|
-
local depend = require(Package.Graph.depend)
|
|
15
|
-
-- State
|
|
16
|
-
local peek = require(Package.State.peek)
|
|
17
|
-
local castToState = require(Package.State.castToState)
|
|
18
|
-
local ForTypes = require(Package.State.For.ForTypes)
|
|
19
|
-
-- Memory
|
|
20
|
-
local doCleanup = require(Package.Memory.doCleanup)
|
|
21
|
-
local deriveScope = require(Package.Memory.deriveScope)
|
|
22
|
-
local scopePool = require(Package.Memory.scopePool)
|
|
23
|
-
-- Utility
|
|
24
|
-
local nameOf = require(Package.Utility.nameOf)
|
|
25
|
-
local nicknames = require(Package.Utility.nicknames)
|
|
26
|
-
|
|
27
|
-
type Self<S, KI, KO, VI, VO> = ForTypes.Disassembly<S, KI, KO, VI, KO> & {
|
|
28
|
-
scope: (S & Types.Scope<unknown>)?,
|
|
29
|
-
_inputTable: Types.UsedAs<{[KI]: VI}>,
|
|
30
|
-
_constructor: (
|
|
31
|
-
Types.Scope<S>,
|
|
32
|
-
initialKey: KI,
|
|
33
|
-
initialValue: VI
|
|
34
|
-
) -> ForTypes.SubObject<S, KI, KO, VI, VO>,
|
|
35
|
-
_subObjects: {[ForTypes.SubObject<S, KI, KO, VI, VO>]: true}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
local class = {}
|
|
40
|
-
class.type = "Graph"
|
|
41
|
-
class.kind = "For.Disassembly"
|
|
42
|
-
class.timeliness = "lazy"
|
|
43
|
-
|
|
44
|
-
local METATABLE = table.freeze {__index = class}
|
|
45
|
-
|
|
46
|
-
local function Disassembly<S, KI, KO, VI, VO>(
|
|
47
|
-
scope: S & Types.Scope<unknown>,
|
|
48
|
-
inputTable: Types.UsedAs<{[KI]: VI}>,
|
|
49
|
-
constructor: (
|
|
50
|
-
Types.Scope<S>,
|
|
51
|
-
initialKey: KI,
|
|
52
|
-
initialValue: VI
|
|
53
|
-
) -> ForTypes.SubObject<S, KI, KO, VI, VO>
|
|
54
|
-
): ForTypes.Disassembly<S, KI, KO, VI, KO>
|
|
55
|
-
local createdAt = os.clock()
|
|
56
|
-
local self = setmetatable(
|
|
57
|
-
{
|
|
58
|
-
createdAt = createdAt,
|
|
59
|
-
dependencySet = {},
|
|
60
|
-
dependentSet = {},
|
|
61
|
-
scope = scope,
|
|
62
|
-
validity = "invalid",
|
|
63
|
-
_inputTable = inputTable,
|
|
64
|
-
_constructor = constructor,
|
|
65
|
-
_subObjects = {}
|
|
66
|
-
},
|
|
67
|
-
METATABLE
|
|
68
|
-
) :: any
|
|
69
|
-
|
|
70
|
-
local destroy = function()
|
|
71
|
-
self.scope = nil
|
|
72
|
-
for dependency in pairs(self.dependencySet) do
|
|
73
|
-
dependency.dependentSet[self] = nil
|
|
74
|
-
end
|
|
75
|
-
for subObject in self._subObjects do
|
|
76
|
-
if subObject.maybeScope ~= nil then
|
|
77
|
-
doCleanup(subObject.maybeScope)
|
|
78
|
-
subObject.maybeScope = nil
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
self.oldestTask = destroy
|
|
83
|
-
nicknames[self.oldestTask] = "For (internal disassembler)"
|
|
84
|
-
table.insert(scope, destroy)
|
|
85
|
-
|
|
86
|
-
return self
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
function class.populate<S, KI, KO, VI, VO>(
|
|
90
|
-
self: Self<S, KI, KO, VI, VO>,
|
|
91
|
-
use: Types.Use,
|
|
92
|
-
output: {[KO]: VO}
|
|
93
|
-
): ()
|
|
94
|
-
local minArrayIndex = math.huge
|
|
95
|
-
local maxArrayIndex = -math.huge
|
|
96
|
-
local hasHoles = false
|
|
97
|
-
for subObject in self._subObjects do
|
|
98
|
-
local outputKey, outputValue = subObject:useOutputPair(use)
|
|
99
|
-
if outputKey == nil or outputValue == nil then
|
|
100
|
-
hasHoles = true
|
|
101
|
-
continue
|
|
102
|
-
elseif output[outputKey] ~= nil then
|
|
103
|
-
External.logErrorNonFatal("forKeyCollision", nil, tostring(outputKey))
|
|
104
|
-
continue
|
|
105
|
-
end
|
|
106
|
-
output[outputKey] = outputValue
|
|
107
|
-
if typeof(outputKey) == "number" then
|
|
108
|
-
minArrayIndex = math.min(minArrayIndex, outputKey)
|
|
109
|
-
maxArrayIndex = math.max(maxArrayIndex, outputKey)
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
-- Be careful of NaN here
|
|
113
|
-
if hasHoles and maxArrayIndex > minArrayIndex then
|
|
114
|
-
local output: {[number]: VO} = output :: any
|
|
115
|
-
local moveToIndex = minArrayIndex
|
|
116
|
-
for moveFromIndex = minArrayIndex, maxArrayIndex do
|
|
117
|
-
local outputValue = output[moveFromIndex]
|
|
118
|
-
if outputValue == nil then
|
|
119
|
-
continue
|
|
120
|
-
end
|
|
121
|
-
-- The ordering is important in case the indices are the same
|
|
122
|
-
output[moveFromIndex] = nil
|
|
123
|
-
output[moveToIndex] = outputValue
|
|
124
|
-
moveToIndex += 1
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
function class._evaluate<S, KI, KO, VI, VO>(
|
|
130
|
-
self: Self<S, KI, KO, VI, VO>
|
|
131
|
-
): boolean
|
|
132
|
-
local outerScope = self.scope :: S & Types.Scope<unknown>
|
|
133
|
-
local inputState = castToState(self._inputTable)
|
|
134
|
-
if inputState ~= nil then
|
|
135
|
-
if inputState.scope == nil then
|
|
136
|
-
External.logError(
|
|
137
|
-
"useAfterDestroy",
|
|
138
|
-
nil,
|
|
139
|
-
`The input {nameOf(inputState, "table")}`,
|
|
140
|
-
`the For object that is watching it`
|
|
141
|
-
)
|
|
142
|
-
end
|
|
143
|
-
depend(self, inputState)
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
local pendingPairs = {} :: {[KI]: VI}
|
|
147
|
-
for key, value in peek(self._inputTable) do
|
|
148
|
-
pendingPairs[key] = value
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
local newSubObjects = {} :: typeof(self._subObjects)
|
|
152
|
-
|
|
153
|
-
for subObject in self._subObjects do
|
|
154
|
-
local reused = false
|
|
155
|
-
local oldInputKey = subObject.inputKey
|
|
156
|
-
local oldInputValue = subObject.inputValue
|
|
157
|
-
local newInputKey: KI
|
|
158
|
-
-- Reuse when the keys are identical.
|
|
159
|
-
if not subObject.roamKeys and pendingPairs[oldInputKey] ~= nil then
|
|
160
|
-
reused = true
|
|
161
|
-
newInputKey = oldInputKey
|
|
162
|
-
else -- Try and reuse some other pair instead.
|
|
163
|
-
for pendingKey, pendingValue in pendingPairs do
|
|
164
|
-
reused = true
|
|
165
|
-
newInputKey = pendingKey
|
|
166
|
-
if subObject.roamValues then
|
|
167
|
-
break
|
|
168
|
-
end
|
|
169
|
-
if pendingValue == oldInputValue then
|
|
170
|
-
-- If the values are the same, then no need to update those,
|
|
171
|
-
-- so prefer this choice to any other.
|
|
172
|
-
break
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
if reused then
|
|
177
|
-
local newInputValue = pendingPairs[newInputKey]
|
|
178
|
-
newSubObjects[subObject] = true
|
|
179
|
-
if newInputKey ~= oldInputKey then
|
|
180
|
-
subObject.inputKey = newInputKey
|
|
181
|
-
subObject:invalidateInputKey()
|
|
182
|
-
end
|
|
183
|
-
if newInputValue ~= oldInputValue then
|
|
184
|
-
subObject.inputValue = newInputValue
|
|
185
|
-
subObject:invalidateInputValue()
|
|
186
|
-
end
|
|
187
|
-
pendingPairs[newInputKey] = nil
|
|
188
|
-
else -- Too many sub objects for the number of pairs.
|
|
189
|
-
if subObject.maybeScope ~= nil then
|
|
190
|
-
doCleanup(subObject.maybeScope)
|
|
191
|
-
subObject.maybeScope = nil
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
-- Generate new objects if needed to cover the remaining pending pairs.
|
|
197
|
-
for pendingKey, pendingValue in pendingPairs do
|
|
198
|
-
local subObject = self._constructor(deriveScope(outerScope), pendingKey, pendingValue)
|
|
199
|
-
if subObject.maybeScope ~= nil then
|
|
200
|
-
subObject.maybeScope = scopePool.giveIfEmpty(subObject.maybeScope)
|
|
201
|
-
end
|
|
202
|
-
newSubObjects[subObject] = true
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
self._subObjects = newSubObjects
|
|
206
|
-
|
|
207
|
-
return true
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
table.freeze(class)
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Breaks down an input table into reactive sub-objects for each pair.
|
|
8
|
+
]]
|
|
9
|
+
|
|
10
|
+
local Package = script.Parent.Parent.Parent
|
|
11
|
+
local Types = require(Package.Types)
|
|
12
|
+
local External = require(Package.External)
|
|
13
|
+
-- Graph
|
|
14
|
+
local depend = require(Package.Graph.depend)
|
|
15
|
+
-- State
|
|
16
|
+
local peek = require(Package.State.peek)
|
|
17
|
+
local castToState = require(Package.State.castToState)
|
|
18
|
+
local ForTypes = require(Package.State.For.ForTypes)
|
|
19
|
+
-- Memory
|
|
20
|
+
local doCleanup = require(Package.Memory.doCleanup)
|
|
21
|
+
local deriveScope = require(Package.Memory.deriveScope)
|
|
22
|
+
local scopePool = require(Package.Memory.scopePool)
|
|
23
|
+
-- Utility
|
|
24
|
+
local nameOf = require(Package.Utility.nameOf)
|
|
25
|
+
local nicknames = require(Package.Utility.nicknames)
|
|
26
|
+
|
|
27
|
+
type Self<S, KI, KO, VI, VO> = ForTypes.Disassembly<S, KI, KO, VI, KO> & {
|
|
28
|
+
scope: (S & Types.Scope<unknown>)?,
|
|
29
|
+
_inputTable: Types.UsedAs<{[KI]: VI}>,
|
|
30
|
+
_constructor: (
|
|
31
|
+
Types.Scope<S>,
|
|
32
|
+
initialKey: KI,
|
|
33
|
+
initialValue: VI
|
|
34
|
+
) -> ForTypes.SubObject<S, KI, KO, VI, VO>,
|
|
35
|
+
_subObjects: {[ForTypes.SubObject<S, KI, KO, VI, VO>]: true}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
local class = {}
|
|
40
|
+
class.type = "Graph"
|
|
41
|
+
class.kind = "For.Disassembly"
|
|
42
|
+
class.timeliness = "lazy"
|
|
43
|
+
|
|
44
|
+
local METATABLE = table.freeze {__index = class}
|
|
45
|
+
|
|
46
|
+
local function Disassembly<S, KI, KO, VI, VO>(
|
|
47
|
+
scope: S & Types.Scope<unknown>,
|
|
48
|
+
inputTable: Types.UsedAs<{[KI]: VI}>,
|
|
49
|
+
constructor: (
|
|
50
|
+
Types.Scope<S>,
|
|
51
|
+
initialKey: KI,
|
|
52
|
+
initialValue: VI
|
|
53
|
+
) -> ForTypes.SubObject<S, KI, KO, VI, VO>
|
|
54
|
+
): ForTypes.Disassembly<S, KI, KO, VI, KO>
|
|
55
|
+
local createdAt = os.clock()
|
|
56
|
+
local self = setmetatable(
|
|
57
|
+
{
|
|
58
|
+
createdAt = createdAt,
|
|
59
|
+
dependencySet = {},
|
|
60
|
+
dependentSet = {},
|
|
61
|
+
scope = scope,
|
|
62
|
+
validity = "invalid",
|
|
63
|
+
_inputTable = inputTable,
|
|
64
|
+
_constructor = constructor,
|
|
65
|
+
_subObjects = {}
|
|
66
|
+
},
|
|
67
|
+
METATABLE
|
|
68
|
+
) :: any
|
|
69
|
+
|
|
70
|
+
local destroy = function()
|
|
71
|
+
self.scope = nil
|
|
72
|
+
for dependency in pairs(self.dependencySet) do
|
|
73
|
+
dependency.dependentSet[self] = nil
|
|
74
|
+
end
|
|
75
|
+
for subObject in self._subObjects do
|
|
76
|
+
if subObject.maybeScope ~= nil then
|
|
77
|
+
doCleanup(subObject.maybeScope)
|
|
78
|
+
subObject.maybeScope = nil
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
self.oldestTask = destroy
|
|
83
|
+
nicknames[self.oldestTask] = "For (internal disassembler)"
|
|
84
|
+
table.insert(scope, destroy)
|
|
85
|
+
|
|
86
|
+
return self
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
function class.populate<S, KI, KO, VI, VO>(
|
|
90
|
+
self: Self<S, KI, KO, VI, VO>,
|
|
91
|
+
use: Types.Use,
|
|
92
|
+
output: {[KO]: VO}
|
|
93
|
+
): ()
|
|
94
|
+
local minArrayIndex = math.huge
|
|
95
|
+
local maxArrayIndex = -math.huge
|
|
96
|
+
local hasHoles = false
|
|
97
|
+
for subObject in self._subObjects do
|
|
98
|
+
local outputKey, outputValue = subObject:useOutputPair(use)
|
|
99
|
+
if outputKey == nil or outputValue == nil then
|
|
100
|
+
hasHoles = true
|
|
101
|
+
continue
|
|
102
|
+
elseif output[outputKey] ~= nil then
|
|
103
|
+
External.logErrorNonFatal("forKeyCollision", nil, tostring(outputKey))
|
|
104
|
+
continue
|
|
105
|
+
end
|
|
106
|
+
output[outputKey] = outputValue
|
|
107
|
+
if typeof(outputKey) == "number" then
|
|
108
|
+
minArrayIndex = math.min(minArrayIndex, outputKey)
|
|
109
|
+
maxArrayIndex = math.max(maxArrayIndex, outputKey)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
-- Be careful of NaN here
|
|
113
|
+
if hasHoles and maxArrayIndex > minArrayIndex then
|
|
114
|
+
local output: {[number]: VO} = output :: any
|
|
115
|
+
local moveToIndex = minArrayIndex
|
|
116
|
+
for moveFromIndex = minArrayIndex, maxArrayIndex do
|
|
117
|
+
local outputValue = output[moveFromIndex]
|
|
118
|
+
if outputValue == nil then
|
|
119
|
+
continue
|
|
120
|
+
end
|
|
121
|
+
-- The ordering is important in case the indices are the same
|
|
122
|
+
output[moveFromIndex] = nil
|
|
123
|
+
output[moveToIndex] = outputValue
|
|
124
|
+
moveToIndex += 1
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
function class._evaluate<S, KI, KO, VI, VO>(
|
|
130
|
+
self: Self<S, KI, KO, VI, VO>
|
|
131
|
+
): boolean
|
|
132
|
+
local outerScope = self.scope :: S & Types.Scope<unknown>
|
|
133
|
+
local inputState = castToState(self._inputTable)
|
|
134
|
+
if inputState ~= nil then
|
|
135
|
+
if inputState.scope == nil then
|
|
136
|
+
External.logError(
|
|
137
|
+
"useAfterDestroy",
|
|
138
|
+
nil,
|
|
139
|
+
`The input {nameOf(inputState, "table")}`,
|
|
140
|
+
`the For object that is watching it`
|
|
141
|
+
)
|
|
142
|
+
end
|
|
143
|
+
depend(self, inputState)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
local pendingPairs = {} :: {[KI]: VI}
|
|
147
|
+
for key, value in peek(self._inputTable) do
|
|
148
|
+
pendingPairs[key] = value
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
local newSubObjects = {} :: typeof(self._subObjects)
|
|
152
|
+
|
|
153
|
+
for subObject in self._subObjects do
|
|
154
|
+
local reused = false
|
|
155
|
+
local oldInputKey = subObject.inputKey
|
|
156
|
+
local oldInputValue = subObject.inputValue
|
|
157
|
+
local newInputKey: KI
|
|
158
|
+
-- Reuse when the keys are identical.
|
|
159
|
+
if not subObject.roamKeys and pendingPairs[oldInputKey] ~= nil then
|
|
160
|
+
reused = true
|
|
161
|
+
newInputKey = oldInputKey
|
|
162
|
+
else -- Try and reuse some other pair instead.
|
|
163
|
+
for pendingKey, pendingValue in pendingPairs do
|
|
164
|
+
reused = true
|
|
165
|
+
newInputKey = pendingKey
|
|
166
|
+
if subObject.roamValues then
|
|
167
|
+
break
|
|
168
|
+
end
|
|
169
|
+
if pendingValue == oldInputValue then
|
|
170
|
+
-- If the values are the same, then no need to update those,
|
|
171
|
+
-- so prefer this choice to any other.
|
|
172
|
+
break
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
if reused then
|
|
177
|
+
local newInputValue = pendingPairs[newInputKey]
|
|
178
|
+
newSubObjects[subObject] = true
|
|
179
|
+
if newInputKey ~= oldInputKey then
|
|
180
|
+
subObject.inputKey = newInputKey
|
|
181
|
+
subObject:invalidateInputKey()
|
|
182
|
+
end
|
|
183
|
+
if newInputValue ~= oldInputValue then
|
|
184
|
+
subObject.inputValue = newInputValue
|
|
185
|
+
subObject:invalidateInputValue()
|
|
186
|
+
end
|
|
187
|
+
pendingPairs[newInputKey] = nil
|
|
188
|
+
else -- Too many sub objects for the number of pairs.
|
|
189
|
+
if subObject.maybeScope ~= nil then
|
|
190
|
+
doCleanup(subObject.maybeScope)
|
|
191
|
+
subObject.maybeScope = nil
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
-- Generate new objects if needed to cover the remaining pending pairs.
|
|
197
|
+
for pendingKey, pendingValue in pendingPairs do
|
|
198
|
+
local subObject = self._constructor(deriveScope(outerScope), pendingKey, pendingValue)
|
|
199
|
+
if subObject.maybeScope ~= nil then
|
|
200
|
+
subObject.maybeScope = scopePool.giveIfEmpty(subObject.maybeScope)
|
|
201
|
+
end
|
|
202
|
+
newSubObjects[subObject] = true
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
self._subObjects = newSubObjects
|
|
206
|
+
|
|
207
|
+
return true
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
table.freeze(class)
|
|
211
211
|
return Disassembly
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
--!strict
|
|
2
|
-
--!nolint LocalUnused
|
|
3
|
-
--!nolint LocalShadow
|
|
4
|
-
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
-
|
|
6
|
-
--[[
|
|
7
|
-
Stores types that are commonly used between For objects.
|
|
8
|
-
]]
|
|
9
|
-
|
|
10
|
-
local Package = script.Parent.Parent.Parent
|
|
11
|
-
local Types = require(Package.Types)
|
|
12
|
-
|
|
13
|
-
export type SubObject<S, KI, KO, VI, VO> = {
|
|
14
|
-
-- Not all sub objects need to store a scope, for example if the scope
|
|
15
|
-
-- remains empty, it'll be given back to the scope pool.
|
|
16
|
-
maybeScope: Types.Scope<S>?,
|
|
17
|
-
inputKey: KI,
|
|
18
|
-
inputValue: VI,
|
|
19
|
-
roamKeys: boolean,
|
|
20
|
-
roamValues: boolean,
|
|
21
|
-
invalidateInputKey: (SubObject<S, KI, KO, VI, VO>) -> (),
|
|
22
|
-
invalidateInputValue: (SubObject<S, KI, KO, VI, VO>) -> (),
|
|
23
|
-
useOutputPair: (SubObject<S, KI, KO, VI, VO>, Types.Use) -> (KO?, VO?)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type Disassembly<S, KI, KO, VI, VO> = Types.GraphObject & {
|
|
27
|
-
populate: (Disassembly<S, KI, KO, VI, VO>, Types.Use, output: {[KO]: VO}) -> ()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return nil
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Stores types that are commonly used between For objects.
|
|
8
|
+
]]
|
|
9
|
+
|
|
10
|
+
local Package = script.Parent.Parent.Parent
|
|
11
|
+
local Types = require(Package.Types)
|
|
12
|
+
|
|
13
|
+
export type SubObject<S, KI, KO, VI, VO> = {
|
|
14
|
+
-- Not all sub objects need to store a scope, for example if the scope
|
|
15
|
+
-- remains empty, it'll be given back to the scope pool.
|
|
16
|
+
maybeScope: Types.Scope<S>?,
|
|
17
|
+
inputKey: KI,
|
|
18
|
+
inputValue: VI,
|
|
19
|
+
roamKeys: boolean,
|
|
20
|
+
roamValues: boolean,
|
|
21
|
+
invalidateInputKey: (SubObject<S, KI, KO, VI, VO>) -> (),
|
|
22
|
+
invalidateInputValue: (SubObject<S, KI, KO, VI, VO>) -> (),
|
|
23
|
+
useOutputPair: (SubObject<S, KI, KO, VI, VO>, Types.Use) -> (KO?, VO?)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type Disassembly<S, KI, KO, VI, VO> = Types.GraphObject & {
|
|
27
|
+
populate: (Disassembly<S, KI, KO, VI, VO>, Types.Use, output: {[KO]: VO}) -> ()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return nil
|