roblox-opencode 1.0.0
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 +122 -0
- package/commands/setup-game.md +108 -0
- package/commands/sync-check.md +53 -0
- package/core/roblox-core.md +93 -0
- package/dist/server.js +167 -0
- package/package.json +35 -0
- package/skills/roblox-analytics/SKILL.md +277 -0
- package/skills/roblox-analytics/references/event-batcher.luau +75 -0
- package/skills/roblox-animation-vfx/SKILL.md +1325 -0
- package/skills/roblox-architecture/SKILL.md +863 -0
- package/skills/roblox-architecture/references/combat-systems.md +1381 -0
- package/skills/roblox-code-review/SKILL.md +687 -0
- package/skills/roblox-data/SKILL.md +889 -0
- package/skills/roblox-data/references/inventory-systems.md +1729 -0
- package/skills/roblox-debug/SKILL.md +99 -0
- package/skills/roblox-gui/SKILL.md +1103 -0
- package/skills/roblox-gui-fusion/SKILL.md +150 -0
- package/skills/roblox-gui-fusion/references/inventory.luau +427 -0
- package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -0
- package/skills/roblox-gui-fusion/references/shop.luau +411 -0
- package/skills/roblox-luau-mastery/SKILL.md +1519 -0
- package/skills/roblox-monetization/SKILL.md +1084 -0
- package/skills/roblox-monetization/references/process-receipt.luau +131 -0
- package/skills/roblox-networking/SKILL.md +669 -0
- package/skills/roblox-networking/references/remote-validator.luau +193 -0
- package/skills/roblox-publish-checklist/SKILL.md +128 -0
- package/skills/roblox-runtime/SKILL.md +753 -0
- package/skills/roblox-sharp-edges/SKILL.md +295 -0
- package/skills/roblox-sync/SKILL.md +126 -0
- package/skills/roblox-testing/SKILL.md +943 -0
- package/skills/roblox-tooling/SKILL.md +150 -0
- package/vendor/LICENSES/ProfileStore-LICENSE +201 -0
- package/vendor/LICENSES/RbxUtil-LICENSE +7 -0
- package/vendor/LICENSES/promise-LICENSE +21 -0
- package/vendor/LICENSES/t-LICENSE +21 -0
- package/vendor/LICENSES/testez-LICENSE +201 -0
- package/vendor/README.md +84 -0
- package/vendor/fusion/Animation/ExternalTime.luau +84 -0
- package/vendor/fusion/Animation/Spring.luau +322 -0
- package/vendor/fusion/Animation/Stopwatch.luau +128 -0
- package/vendor/fusion/Animation/Tween.luau +187 -0
- package/vendor/fusion/Animation/getTweenDuration.luau +27 -0
- package/vendor/fusion/Animation/getTweenRatio.luau +47 -0
- package/vendor/fusion/Animation/lerpType.luau +164 -0
- package/vendor/fusion/Animation/packType.luau +100 -0
- package/vendor/fusion/Animation/springCoefficients.luau +80 -0
- package/vendor/fusion/Animation/unpackType.luau +103 -0
- package/vendor/fusion/Colour/Oklab.luau +70 -0
- package/vendor/fusion/Colour/sRGB.luau +55 -0
- package/vendor/fusion/External.luau +168 -0
- package/vendor/fusion/ExternalDebug.luau +70 -0
- package/vendor/fusion/Graph/Observer.luau +114 -0
- package/vendor/fusion/Graph/castToGraph.luau +29 -0
- package/vendor/fusion/Graph/change.luau +81 -0
- package/vendor/fusion/Graph/depend.luau +33 -0
- package/vendor/fusion/Graph/evaluate.luau +56 -0
- package/vendor/fusion/Instances/Attribute.luau +58 -0
- package/vendor/fusion/Instances/AttributeChange.luau +47 -0
- package/vendor/fusion/Instances/AttributeOut.luau +63 -0
- package/vendor/fusion/Instances/Child.luau +21 -0
- package/vendor/fusion/Instances/Children.luau +148 -0
- package/vendor/fusion/Instances/Hydrate.luau +33 -0
- package/vendor/fusion/Instances/New.luau +53 -0
- package/vendor/fusion/Instances/OnChange.luau +50 -0
- package/vendor/fusion/Instances/OnEvent.luau +54 -0
- package/vendor/fusion/Instances/Out.luau +69 -0
- package/vendor/fusion/Instances/applyInstanceProps.luau +149 -0
- package/vendor/fusion/Instances/defaultProps.luau +194 -0
- package/vendor/fusion/LICENSE +21 -0
- package/vendor/fusion/Logging/formatError.luau +49 -0
- package/vendor/fusion/Logging/messages.luau +52 -0
- package/vendor/fusion/Logging/parseError.luau +25 -0
- package/vendor/fusion/Memory/checkLifetime.luau +134 -0
- package/vendor/fusion/Memory/deriveScope.luau +24 -0
- package/vendor/fusion/Memory/deriveScopeImpl.luau +45 -0
- package/vendor/fusion/Memory/doCleanup.luau +79 -0
- package/vendor/fusion/Memory/innerScope.luau +34 -0
- package/vendor/fusion/Memory/legacyCleanup.luau +18 -0
- package/vendor/fusion/Memory/needsDestruction.luau +17 -0
- package/vendor/fusion/Memory/poisonScope.luau +34 -0
- package/vendor/fusion/Memory/scopePool.luau +55 -0
- package/vendor/fusion/Memory/scoped.luau +27 -0
- package/vendor/fusion/Memory/whichLivesLonger.luau +75 -0
- package/vendor/fusion/RobloxExternal.luau +98 -0
- package/vendor/fusion/State/Computed.luau +139 -0
- package/vendor/fusion/State/For/Disassembly.luau +211 -0
- package/vendor/fusion/State/For/ForTypes.luau +30 -0
- package/vendor/fusion/State/For/init.luau +110 -0
- package/vendor/fusion/State/ForKeys.luau +94 -0
- package/vendor/fusion/State/ForPairs.luau +97 -0
- package/vendor/fusion/State/ForValues.luau +94 -0
- package/vendor/fusion/State/Value.luau +88 -0
- package/vendor/fusion/State/castToState.luau +26 -0
- package/vendor/fusion/State/peek.luau +31 -0
- package/vendor/fusion/State/updateAll.luau +1 -0
- package/vendor/fusion/Types.luau +314 -0
- package/vendor/fusion/Utility/Contextual.luau +91 -0
- package/vendor/fusion/Utility/Safe.luau +23 -0
- package/vendor/fusion/Utility/isSimilar.luau +29 -0
- package/vendor/fusion/Utility/merge.luau +35 -0
- package/vendor/fusion/Utility/nameOf.luau +35 -0
- package/vendor/fusion/Utility/never.luau +14 -0
- package/vendor/fusion/Utility/nicknames.luau +11 -0
- package/vendor/fusion/Utility/xtypeof.luau +27 -0
- package/vendor/fusion/init.luau +82 -0
- package/vendor/profilestore/init.luau +2243 -0
- package/vendor/promise/init.luau +1982 -0
- package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -0
- package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -0
- package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -0
- package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -0
- package/vendor/rbxutil/buffer-util/Types.luau +60 -0
- package/vendor/rbxutil/buffer-util/index.d.ts +153 -0
- package/vendor/rbxutil/buffer-util/init.luau +41 -0
- package/vendor/rbxutil/buffer-util/package.json +16 -0
- package/vendor/rbxutil/buffer-util/wally.toml +9 -0
- package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -0
- package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -0
- package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -0
- package/vendor/rbxutil/comm/Client/init.luau +135 -0
- package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -0
- package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -0
- package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -0
- package/vendor/rbxutil/comm/Server/init.luau +140 -0
- package/vendor/rbxutil/comm/Types.luau +18 -0
- package/vendor/rbxutil/comm/Util.luau +27 -0
- package/vendor/rbxutil/comm/init.luau +35 -0
- package/vendor/rbxutil/comm/wally.toml +13 -0
- package/vendor/rbxutil/component/init.luau +759 -0
- package/vendor/rbxutil/component/init.test.luau +311 -0
- package/vendor/rbxutil/component/wally.toml +14 -0
- package/vendor/rbxutil/concur/init.luau +542 -0
- package/vendor/rbxutil/concur/init.test.luau +364 -0
- package/vendor/rbxutil/concur/wally.toml +8 -0
- package/vendor/rbxutil/enum-list/init.luau +101 -0
- package/vendor/rbxutil/enum-list/init.test.luau +91 -0
- package/vendor/rbxutil/enum-list/wally.toml +8 -0
- package/vendor/rbxutil/find/index.d.ts +20 -0
- package/vendor/rbxutil/find/init.luau +44 -0
- package/vendor/rbxutil/find/package.json +17 -0
- package/vendor/rbxutil/find/wally.toml +8 -0
- package/vendor/rbxutil/input/Gamepad.luau +559 -0
- package/vendor/rbxutil/input/Keyboard.luau +124 -0
- package/vendor/rbxutil/input/Mouse.luau +278 -0
- package/vendor/rbxutil/input/PreferredInput.luau +91 -0
- package/vendor/rbxutil/input/Touch.luau +120 -0
- package/vendor/rbxutil/input/init.luau +33 -0
- package/vendor/rbxutil/input/wally.toml +12 -0
- package/vendor/rbxutil/loader/index.d.ts +15 -0
- package/vendor/rbxutil/loader/init.luau +137 -0
- package/vendor/rbxutil/loader/wally.toml +8 -0
- package/vendor/rbxutil/log/index.d.ts +38 -0
- package/vendor/rbxutil/log/init.luau +746 -0
- package/vendor/rbxutil/log/wally.toml +8 -0
- package/vendor/rbxutil/net/init.luau +190 -0
- package/vendor/rbxutil/net/wally.toml +8 -0
- package/vendor/rbxutil/option/index.d.ts +44 -0
- package/vendor/rbxutil/option/init.luau +489 -0
- package/vendor/rbxutil/option/init.test.luau +342 -0
- package/vendor/rbxutil/option/wally.toml +8 -0
- package/vendor/rbxutil/pid/index.d.ts +53 -0
- package/vendor/rbxutil/pid/init.luau +195 -0
- package/vendor/rbxutil/pid/package.json +16 -0
- package/vendor/rbxutil/pid/wally.toml +9 -0
- package/vendor/rbxutil/quaternion/index.d.ts +117 -0
- package/vendor/rbxutil/quaternion/init.luau +570 -0
- package/vendor/rbxutil/quaternion/package.json +16 -0
- package/vendor/rbxutil/quaternion/wally.toml +9 -0
- package/vendor/rbxutil/query/index.d.ts +43 -0
- package/vendor/rbxutil/query/init.luau +117 -0
- package/vendor/rbxutil/query/package.json +18 -0
- package/vendor/rbxutil/query/wally.toml +9 -0
- package/vendor/rbxutil/sequent/index.d.ts +28 -0
- package/vendor/rbxutil/sequent/init.luau +340 -0
- package/vendor/rbxutil/sequent/package.json +16 -0
- package/vendor/rbxutil/sequent/wally.toml +9 -0
- package/vendor/rbxutil/ser/init.luau +175 -0
- package/vendor/rbxutil/ser/init.test.luau +50 -0
- package/vendor/rbxutil/ser/wally.toml +11 -0
- package/vendor/rbxutil/shake/index.d.ts +36 -0
- package/vendor/rbxutil/shake/init.luau +532 -0
- package/vendor/rbxutil/shake/init.test.luau +267 -0
- package/vendor/rbxutil/shake/package.json +16 -0
- package/vendor/rbxutil/shake/wally.toml +9 -0
- package/vendor/rbxutil/signal/index.d.ts +100 -0
- package/vendor/rbxutil/signal/init.luau +432 -0
- package/vendor/rbxutil/signal/init.test.luau +190 -0
- package/vendor/rbxutil/signal/package.json +17 -0
- package/vendor/rbxutil/signal/wally.toml +9 -0
- package/vendor/rbxutil/silo/TableWatcher.luau +65 -0
- package/vendor/rbxutil/silo/Util.luau +55 -0
- package/vendor/rbxutil/silo/init.luau +338 -0
- package/vendor/rbxutil/silo/init.test.luau +215 -0
- package/vendor/rbxutil/silo/wally.toml +8 -0
- package/vendor/rbxutil/spring/index.d.ts +40 -0
- package/vendor/rbxutil/spring/init.luau +97 -0
- package/vendor/rbxutil/spring/package.json +17 -0
- package/vendor/rbxutil/spring/wally.toml +8 -0
- package/vendor/rbxutil/stream/index.d.ts +88 -0
- package/vendor/rbxutil/stream/init.luau +597 -0
- package/vendor/rbxutil/stream/package.json +18 -0
- package/vendor/rbxutil/stream/wally.toml +9 -0
- package/vendor/rbxutil/streamable/Streamable.luau +202 -0
- package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -0
- package/vendor/rbxutil/streamable/init.luau +8 -0
- package/vendor/rbxutil/streamable/wally.toml +12 -0
- package/vendor/rbxutil/symbol/init.luau +56 -0
- package/vendor/rbxutil/symbol/init.test.luau +37 -0
- package/vendor/rbxutil/symbol/wally.toml +8 -0
- package/vendor/rbxutil/table-util/init.luau +938 -0
- package/vendor/rbxutil/table-util/init.test.luau +439 -0
- package/vendor/rbxutil/table-util/wally.toml +8 -0
- package/vendor/rbxutil/task-queue/index.d.ts +27 -0
- package/vendor/rbxutil/task-queue/init.luau +97 -0
- package/vendor/rbxutil/task-queue/wally.toml +8 -0
- package/vendor/rbxutil/timer/index.d.ts +81 -0
- package/vendor/rbxutil/timer/init.luau +249 -0
- package/vendor/rbxutil/timer/init.test.luau +73 -0
- package/vendor/rbxutil/timer/wally.toml +11 -0
- package/vendor/rbxutil/tree/index.d.ts +15 -0
- package/vendor/rbxutil/tree/init.luau +137 -0
- package/vendor/rbxutil/tree/wally.toml +8 -0
- package/vendor/rbxutil/trove/index.d.ts +46 -0
- package/vendor/rbxutil/trove/init.luau +787 -0
- package/vendor/rbxutil/trove/init.test.luau +203 -0
- package/vendor/rbxutil/trove/wally.toml +8 -0
- package/vendor/rbxutil/typed-remote/init.luau +196 -0
- package/vendor/rbxutil/typed-remote/wally.toml +8 -0
- package/vendor/rbxutil/wait-for/index.d.ts +17 -0
- package/vendor/rbxutil/wait-for/init.luau +257 -0
- package/vendor/rbxutil/wait-for/init.test.luau +182 -0
- package/vendor/rbxutil/wait-for/wally.toml +11 -0
- package/vendor/t/t.lua +1350 -0
- package/vendor/testez/Context.lua +26 -0
- package/vendor/testez/Expectation.lua +311 -0
- package/vendor/testez/ExpectationContext.lua +38 -0
- package/vendor/testez/LifecycleHooks.lua +89 -0
- package/vendor/testez/Reporters/TeamCityReporter.lua +102 -0
- package/vendor/testez/Reporters/TextReporter.lua +106 -0
- package/vendor/testez/Reporters/TextReporterQuiet.lua +97 -0
- package/vendor/testez/TestBootstrap.lua +147 -0
- package/vendor/testez/TestEnum.lua +28 -0
- package/vendor/testez/TestPlan.lua +304 -0
- package/vendor/testez/TestPlanner.lua +40 -0
- package/vendor/testez/TestResults.lua +112 -0
- package/vendor/testez/TestRunner.lua +188 -0
- package/vendor/testez/TestSession.lua +243 -0
- package/vendor/testez/init.lua +40 -0
|
@@ -0,0 +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)
|
|
211
|
+
return Disassembly
|
|
@@ -0,0 +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
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
The generic implementation for all `For` objects.
|
|
8
|
+
]]
|
|
9
|
+
|
|
10
|
+
local Package = script.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
|
+
-- Utility
|
|
20
|
+
local never = require(Package.Utility.never)
|
|
21
|
+
local nicknames = require(Package.Utility.nicknames)
|
|
22
|
+
|
|
23
|
+
local Disassembly = require(Package.State.For.Disassembly)
|
|
24
|
+
|
|
25
|
+
type Self<S, KI, KO, VI, VO> = Types.For<KO, VO> & {
|
|
26
|
+
_disassembly: ForTypes.Disassembly<S, KI, KO, VI, VO>
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
local class = {}
|
|
30
|
+
class.type = "State"
|
|
31
|
+
class.kind = "For"
|
|
32
|
+
class.timeliness = "lazy"
|
|
33
|
+
|
|
34
|
+
local METATABLE = table.freeze {__index = class}
|
|
35
|
+
|
|
36
|
+
local function For<S, KI, KO, VI, VO>(
|
|
37
|
+
scope: Types.Scope<S>,
|
|
38
|
+
inputTable: Types.UsedAs<{[KI]: VI}>,
|
|
39
|
+
constructor: (
|
|
40
|
+
Types.Scope<S>,
|
|
41
|
+
initialKey: KI,
|
|
42
|
+
initialValue: VI
|
|
43
|
+
) -> ForTypes.SubObject<S, KI, KO, VI, VO>
|
|
44
|
+
): Types.For<KO, VO>
|
|
45
|
+
local createdAt = os.clock()
|
|
46
|
+
local self: Self<S, KI, KO, VI, VO> = setmetatable(
|
|
47
|
+
{
|
|
48
|
+
createdAt = createdAt,
|
|
49
|
+
dependencySet = {},
|
|
50
|
+
dependentSet = {},
|
|
51
|
+
scope = scope,
|
|
52
|
+
validity = "invalid",
|
|
53
|
+
_EXTREMELY_DANGEROUS_usedAsValue = {},
|
|
54
|
+
_disassembly = Disassembly(
|
|
55
|
+
scope,
|
|
56
|
+
inputTable,
|
|
57
|
+
constructor
|
|
58
|
+
)
|
|
59
|
+
},
|
|
60
|
+
METATABLE
|
|
61
|
+
) :: any
|
|
62
|
+
|
|
63
|
+
local destroy = function()
|
|
64
|
+
self.scope = nil
|
|
65
|
+
for dependency in pairs(self.dependencySet) do
|
|
66
|
+
dependency.dependentSet[self] = nil
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
self.oldestTask = destroy
|
|
70
|
+
nicknames[self.oldestTask] = "For"
|
|
71
|
+
table.insert(scope, destroy)
|
|
72
|
+
|
|
73
|
+
return self
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
function class.get<S, KI, KO, VI, VO>(
|
|
77
|
+
_self: Self<S, KI, KO, VI, VO>
|
|
78
|
+
): never
|
|
79
|
+
External.logError("stateGetWasRemoved")
|
|
80
|
+
return never()
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
function class._evaluate<S, KI, KO, VI, VO>(
|
|
84
|
+
self: Self<S, KI, KO, VI, VO>
|
|
85
|
+
): boolean
|
|
86
|
+
if self.scope == nil then
|
|
87
|
+
return false
|
|
88
|
+
end
|
|
89
|
+
local outerScope = self.scope :: S & Types.Scope<unknown>
|
|
90
|
+
|
|
91
|
+
depend(self, self._disassembly)
|
|
92
|
+
table.clear(self._EXTREMELY_DANGEROUS_usedAsValue)
|
|
93
|
+
self._disassembly:populate(
|
|
94
|
+
function<T>(
|
|
95
|
+
maybeState: Types.UsedAs<T>
|
|
96
|
+
): T
|
|
97
|
+
local state = castToState(maybeState)
|
|
98
|
+
if state ~= nil then
|
|
99
|
+
depend(self, state)
|
|
100
|
+
end
|
|
101
|
+
return peek(maybeState)
|
|
102
|
+
end,
|
|
103
|
+
self._EXTREMELY_DANGEROUS_usedAsValue
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
return true
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
table.freeze(class)
|
|
110
|
+
return For
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Constructs and returns a new For state object which processes keys and
|
|
8
|
+
preserves values.
|
|
9
|
+
|
|
10
|
+
https://elttob.uk/Fusion/0.3/api-reference/state/members/forkeys/
|
|
11
|
+
|
|
12
|
+
TODO: the sub objects constructed here can be more efficiently implemented
|
|
13
|
+
as a dedicated state object.
|
|
14
|
+
]]
|
|
15
|
+
|
|
16
|
+
local Package = script.Parent.Parent
|
|
17
|
+
local Types = require(Package.Types)
|
|
18
|
+
local External = require(Package.External)
|
|
19
|
+
-- Memory
|
|
20
|
+
local doCleanup = require(Package.Memory.doCleanup)
|
|
21
|
+
-- State
|
|
22
|
+
local For = require(Package.State.For)
|
|
23
|
+
local Value = require(Package.State.Value)
|
|
24
|
+
local Computed = require(Package.State.Computed)
|
|
25
|
+
local ForTypes = require(Package.State.For.ForTypes)
|
|
26
|
+
-- Logging
|
|
27
|
+
local parseError = require(Package.Logging.parseError)
|
|
28
|
+
|
|
29
|
+
local SUB_OBJECT_META = {
|
|
30
|
+
__index = {
|
|
31
|
+
roamKeys = false,
|
|
32
|
+
roamValues = true,
|
|
33
|
+
invalidateInputKey = function(self): ()
|
|
34
|
+
self._inputKeyState:set(self.inputKey)
|
|
35
|
+
end,
|
|
36
|
+
invalidateInputValue = function(self): ()
|
|
37
|
+
-- do nothing
|
|
38
|
+
end,
|
|
39
|
+
useOutputPair = function(self, use)
|
|
40
|
+
return use(self._outputKeyState), self.inputValue
|
|
41
|
+
end
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
local function SubObject<KI, KO, V, S>(
|
|
46
|
+
scope: Types.Scope<S>,
|
|
47
|
+
initialKey: KI,
|
|
48
|
+
initialValue: V,
|
|
49
|
+
processor: (Types.Use, Types.Scope<S>, KI) -> KO
|
|
50
|
+
): ForTypes.SubObject<S, KI, KO, V, V>
|
|
51
|
+
local self = {}
|
|
52
|
+
self.maybeScope = scope
|
|
53
|
+
self.inputKey = initialKey
|
|
54
|
+
self.inputValue = initialValue
|
|
55
|
+
self._inputKeyState = Value(scope, initialKey)
|
|
56
|
+
self._processor = processor
|
|
57
|
+
self._outputKeyState = Computed(scope, function(use, scope): KO?
|
|
58
|
+
local inputKey = use(self._inputKeyState)
|
|
59
|
+
local ok, outputKey = xpcall(self._processor, parseError, use, scope, inputKey)
|
|
60
|
+
if ok then
|
|
61
|
+
return outputKey
|
|
62
|
+
else
|
|
63
|
+
local error: Types.Error = outputKey :: any
|
|
64
|
+
error.context = `while processing key {tostring(inputKey)}`
|
|
65
|
+
External.logErrorNonFatal("callbackError", error)
|
|
66
|
+
doCleanup(scope)
|
|
67
|
+
table.clear(scope)
|
|
68
|
+
return nil
|
|
69
|
+
end
|
|
70
|
+
end)
|
|
71
|
+
return setmetatable(self, SUB_OBJECT_META) :: any
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
local function ForKeys<KI, KO, V, S>(
|
|
75
|
+
scope: Types.Scope<S>,
|
|
76
|
+
inputTable: Types.UsedAs<{[KI]: V}>,
|
|
77
|
+
processor: (Types.Use, Types.Scope<S>, KI) -> KO,
|
|
78
|
+
destructor: unknown?
|
|
79
|
+
): Types.For<KO, V>
|
|
80
|
+
if typeof(inputTable) == "function" then
|
|
81
|
+
External.logError("scopeMissing", nil, "ForKeys", "myScope:ForKeys(inputTable, function(scope, use, key) ... end)")
|
|
82
|
+
elseif destructor ~= nil then
|
|
83
|
+
External.logWarn("destructorRedundant", "ForKeys")
|
|
84
|
+
end
|
|
85
|
+
return For(
|
|
86
|
+
scope,
|
|
87
|
+
inputTable,
|
|
88
|
+
function(scope, initialKey, initialValue)
|
|
89
|
+
return SubObject(scope, initialKey, initialValue, processor)
|
|
90
|
+
end
|
|
91
|
+
)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
return ForKeys :: Types.ForKeysConstructor
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Constructs and returns a new For state object which processes keys and
|
|
8
|
+
values in pairs.
|
|
9
|
+
|
|
10
|
+
https://elttob.uk/Fusion/0.3/api-reference/state/members/forpairs/
|
|
11
|
+
|
|
12
|
+
TODO: the sub objects constructed here can be more efficiently implemented
|
|
13
|
+
as a dedicated state object.
|
|
14
|
+
]]
|
|
15
|
+
|
|
16
|
+
local Package = script.Parent.Parent
|
|
17
|
+
local Types = require(Package.Types)
|
|
18
|
+
local External = require(Package.External)
|
|
19
|
+
-- State
|
|
20
|
+
local For = require(Package.State.For)
|
|
21
|
+
local Value = require(Package.State.Value)
|
|
22
|
+
local Computed = require(Package.State.Computed)
|
|
23
|
+
local ForTypes = require(Package.State.For.ForTypes)
|
|
24
|
+
-- Logging
|
|
25
|
+
local parseError = require(Package.Logging.parseError)
|
|
26
|
+
-- Memory
|
|
27
|
+
local doCleanup = require(Package.Memory.doCleanup)
|
|
28
|
+
|
|
29
|
+
local SUB_OBJECT_META = {
|
|
30
|
+
__index = {
|
|
31
|
+
roamKeys = false,
|
|
32
|
+
roamValues = false,
|
|
33
|
+
invalidateInputKey = function(self): ()
|
|
34
|
+
self._inputKeyState:set(self.inputKey)
|
|
35
|
+
end,
|
|
36
|
+
invalidateInputValue = function(self): ()
|
|
37
|
+
self._inputValueState:set(self.inputValue)
|
|
38
|
+
end,
|
|
39
|
+
useOutputPair = function(self, use)
|
|
40
|
+
local pair = use(self._outputPairState)
|
|
41
|
+
return pair.key, pair.value
|
|
42
|
+
end
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
local function SubObject<KI, KO, VI, VO, S>(
|
|
47
|
+
scope: Types.Scope<S>,
|
|
48
|
+
initialKey: KI,
|
|
49
|
+
initialValue: VI,
|
|
50
|
+
processor: (Types.Use, Types.Scope<S>, KI, VI) -> (KO, VO)
|
|
51
|
+
): ForTypes.SubObject<S, KI, KO, VI, VO>
|
|
52
|
+
local self = {}
|
|
53
|
+
self.maybeScope = scope
|
|
54
|
+
self.inputKey = initialKey
|
|
55
|
+
self.inputValue = initialValue
|
|
56
|
+
self._inputKeyState = Value(scope, initialKey)
|
|
57
|
+
self._inputValueState = Value(scope, initialValue)
|
|
58
|
+
self._processor = processor
|
|
59
|
+
self._outputPairState = Computed(scope, function(use, scope): {key: KO?, value: VO?}
|
|
60
|
+
local inputKey = use(self._inputKeyState)
|
|
61
|
+
local inputValue = use(self._inputValueState)
|
|
62
|
+
local ok, outputKey, outputValue = xpcall(self._processor, parseError, use, scope, inputKey, inputValue)
|
|
63
|
+
if ok then
|
|
64
|
+
return {key = outputKey, value = outputValue}
|
|
65
|
+
else
|
|
66
|
+
local error: Types.Error = outputKey :: any
|
|
67
|
+
error.context = `while processing key {tostring(inputValue)} and value {tostring(inputValue)}`
|
|
68
|
+
External.logErrorNonFatal("callbackError", error)
|
|
69
|
+
doCleanup(scope)
|
|
70
|
+
table.clear(scope)
|
|
71
|
+
return {key = nil, value = nil}
|
|
72
|
+
end
|
|
73
|
+
end)
|
|
74
|
+
return setmetatable(self, SUB_OBJECT_META) :: any
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
local function ForPairs<KI, KO, VI, VO, S>(
|
|
78
|
+
scope: Types.Scope<S>,
|
|
79
|
+
inputTable: Types.UsedAs<{[KI]: VI}>,
|
|
80
|
+
processor: (Types.Use, Types.Scope<S>, KI, VI) -> (KO, VO),
|
|
81
|
+
destructor: unknown?
|
|
82
|
+
): Types.For<KO, VO>
|
|
83
|
+
if typeof(inputTable) == "function" then
|
|
84
|
+
External.logError("scopeMissing", nil, "ForPairs", "myScope:ForPairs(inputTable, function(scope, use, key, value) ... end)")
|
|
85
|
+
elseif destructor ~= nil then
|
|
86
|
+
External.logWarn("destructorRedundant", "ForPairs")
|
|
87
|
+
end
|
|
88
|
+
return For(
|
|
89
|
+
scope,
|
|
90
|
+
inputTable,
|
|
91
|
+
function(scope, initialKey, initialValue)
|
|
92
|
+
return SubObject(scope, initialKey, initialValue, processor)
|
|
93
|
+
end
|
|
94
|
+
)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
return ForPairs :: Types.ForPairsConstructor
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
--!strict
|
|
2
|
+
--!nolint LocalUnused
|
|
3
|
+
--!nolint LocalShadow
|
|
4
|
+
local task = nil -- Disable usage of Roblox's task scheduler
|
|
5
|
+
|
|
6
|
+
--[[
|
|
7
|
+
Constructs and returns a new For state object which processes values and
|
|
8
|
+
preserves keys.
|
|
9
|
+
|
|
10
|
+
https://elttob.uk/Fusion/0.3/api-reference/state/members/forvalues/
|
|
11
|
+
|
|
12
|
+
TODO: the sub objects constructed here can be more efficiently implemented
|
|
13
|
+
as a dedicated state object.
|
|
14
|
+
]]
|
|
15
|
+
|
|
16
|
+
local Package = script.Parent.Parent
|
|
17
|
+
local Types = require(Package.Types)
|
|
18
|
+
local External = require(Package.External)
|
|
19
|
+
-- State
|
|
20
|
+
local For = require(Package.State.For)
|
|
21
|
+
local Value = require(Package.State.Value)
|
|
22
|
+
local Computed = require(Package.State.Computed)
|
|
23
|
+
local ForTypes = require(Package.State.For.ForTypes)
|
|
24
|
+
-- Logging
|
|
25
|
+
local parseError = require(Package.Logging.parseError)
|
|
26
|
+
-- Memory
|
|
27
|
+
local doCleanup = require(Package.Memory.doCleanup)
|
|
28
|
+
|
|
29
|
+
local SUB_OBJECT_META = {
|
|
30
|
+
__index = {
|
|
31
|
+
roamKeys = true,
|
|
32
|
+
roamValues = false,
|
|
33
|
+
invalidateInputKey = function(self): ()
|
|
34
|
+
-- do nothing
|
|
35
|
+
end,
|
|
36
|
+
invalidateInputValue = function(self): ()
|
|
37
|
+
self._inputValueState:set(self.inputValue)
|
|
38
|
+
end,
|
|
39
|
+
useOutputPair = function(self, use)
|
|
40
|
+
return self.inputKey, use(self._outputValueState)
|
|
41
|
+
end
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
local function SubObject<K, VI, VO, S>(
|
|
46
|
+
scope: Types.Scope<S>,
|
|
47
|
+
initialKey: K,
|
|
48
|
+
initialValue: VI,
|
|
49
|
+
processor: (Types.Use, Types.Scope<S>, VI) -> VO
|
|
50
|
+
): ForTypes.SubObject<S, K, K, VI, VO>
|
|
51
|
+
local self = {}
|
|
52
|
+
self.maybeScope = scope
|
|
53
|
+
self.inputKey = initialKey
|
|
54
|
+
self.inputValue = initialValue
|
|
55
|
+
self._inputValueState = Value(scope, initialValue)
|
|
56
|
+
self._processor = processor
|
|
57
|
+
self._outputValueState = Computed(scope, function(use, scope): VO?
|
|
58
|
+
local inputValue = use(self._inputValueState)
|
|
59
|
+
local ok, outputValue = xpcall(self._processor, parseError, use, scope, inputValue)
|
|
60
|
+
if ok then
|
|
61
|
+
return outputValue
|
|
62
|
+
else
|
|
63
|
+
local error: Types.Error = outputValue :: any
|
|
64
|
+
error.context = `while processing value {tostring(inputValue)}`
|
|
65
|
+
External.logErrorNonFatal("callbackError", error)
|
|
66
|
+
doCleanup(scope)
|
|
67
|
+
table.clear(scope)
|
|
68
|
+
return nil
|
|
69
|
+
end
|
|
70
|
+
end)
|
|
71
|
+
return setmetatable(self, SUB_OBJECT_META) :: any
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
local function ForValues<K, VI, VO, S>(
|
|
75
|
+
scope: Types.Scope<S>,
|
|
76
|
+
inputTable: Types.UsedAs<{[K]: VI}>,
|
|
77
|
+
processor: (Types.Use, Types.Scope<S>, VI) -> VO,
|
|
78
|
+
destructor: unknown?
|
|
79
|
+
): Types.For<K, VO>
|
|
80
|
+
if typeof(inputTable) == "function" then
|
|
81
|
+
External.logError("scopeMissing", nil, "ForValues", "myScope:ForValues(inputTable, function(scope, use, value) ... end)")
|
|
82
|
+
elseif destructor ~= nil then
|
|
83
|
+
External.logWarn("destructorRedundant", "ForValues")
|
|
84
|
+
end
|
|
85
|
+
return For(
|
|
86
|
+
scope,
|
|
87
|
+
inputTable,
|
|
88
|
+
function(scope, initialKey, initialValue)
|
|
89
|
+
return SubObject(scope, initialKey, initialValue, processor)
|
|
90
|
+
end
|
|
91
|
+
)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
return ForValues :: Types.ForValuesConstructor
|