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,232 +1,232 @@
|
|
|
1
|
-
-- ClientComm
|
|
2
|
-
-- Stephen Leitnick
|
|
3
|
-
-- December 20, 2021
|
|
4
|
-
|
|
5
|
-
local Comm = require(script.Parent)
|
|
6
|
-
local Types = require(script.Parent.Parent.Types)
|
|
7
|
-
local Util = require(script.Parent.Parent.Util)
|
|
8
|
-
|
|
9
|
-
--[=[
|
|
10
|
-
@class ClientComm
|
|
11
|
-
@client
|
|
12
|
-
]=]
|
|
13
|
-
local ClientComm = {}
|
|
14
|
-
ClientComm.__index = ClientComm
|
|
15
|
-
|
|
16
|
-
--[=[
|
|
17
|
-
@within ClientComm
|
|
18
|
-
@type ClientMiddlewareFn (args: {any}) -> (shouldContinue: boolean, ...: any)
|
|
19
|
-
The middleware function takes the arguments (as a table array), and should
|
|
20
|
-
return `true|false` to indicate if the process should continue.
|
|
21
|
-
|
|
22
|
-
If returning `false`, the optional varargs after the `false` are used as the new return values
|
|
23
|
-
to whatever was calling the middleware.
|
|
24
|
-
]=]
|
|
25
|
-
--[=[
|
|
26
|
-
@within ClientComm
|
|
27
|
-
@type ClientMiddleware {ClientMiddlewareFn}
|
|
28
|
-
Array of middleware functions.
|
|
29
|
-
]=]
|
|
30
|
-
|
|
31
|
-
--[=[
|
|
32
|
-
@return ClientComm
|
|
33
|
-
Constructs a ClientComm object.
|
|
34
|
-
|
|
35
|
-
If `usePromise` is set to `true`, then `GetFunction` will generate a function that returns a Promise
|
|
36
|
-
that resolves with the server response. If set to `false`, the function will act like a normal
|
|
37
|
-
call to a RemoteFunction and yield until the function responds.
|
|
38
|
-
|
|
39
|
-
```lua
|
|
40
|
-
local clientComm = ClientComm.new(game:GetService("ReplicatedStorage"), true)
|
|
41
|
-
|
|
42
|
-
-- If using a unique namespace with ServerComm, include it as second argument:
|
|
43
|
-
local clientComm = ClientComm.new(game:GetService("ReplicatedStorage"), true, "MyNamespace")
|
|
44
|
-
```
|
|
45
|
-
]=]
|
|
46
|
-
function ClientComm.new(parent: Instance, usePromise: boolean, namespace: string?)
|
|
47
|
-
assert(not Util.IsServer, "ClientComm must be constructed from the client")
|
|
48
|
-
assert(typeof(parent) == "Instance", "Parent must be of type Instance")
|
|
49
|
-
local ns = Util.DefaultCommFolderName
|
|
50
|
-
if namespace then
|
|
51
|
-
ns = namespace
|
|
52
|
-
end
|
|
53
|
-
local folder: Instance? = parent:WaitForChild(ns, Util.WaitForChildTimeout)
|
|
54
|
-
assert(folder ~= nil, "Could not find namespace for ClientComm in parent: " .. ns)
|
|
55
|
-
local self = setmetatable({}, ClientComm)
|
|
56
|
-
self._instancesFolder = folder
|
|
57
|
-
self._usePromise = usePromise
|
|
58
|
-
return self
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
--[=[
|
|
62
|
-
@param name string
|
|
63
|
-
@param inboundMiddleware ClientMiddleware?
|
|
64
|
-
@param outboundMiddleware ClientMiddleware?
|
|
65
|
-
@return (...: any) -> any
|
|
66
|
-
|
|
67
|
-
Generates a function on the matching RemoteFunction generated with ServerComm. The function
|
|
68
|
-
can then be called to invoke the server. If this `ClientComm` object was created with
|
|
69
|
-
the `usePromise` parameter set to `true`, then this generated function will return
|
|
70
|
-
a Promise when called.
|
|
71
|
-
|
|
72
|
-
```lua
|
|
73
|
-
-- Server-side:
|
|
74
|
-
local serverComm = ServerComm.new(someParent)
|
|
75
|
-
serverComm:BindFunction("MyFunction", function(player, msg)
|
|
76
|
-
return msg:upper()
|
|
77
|
-
end)
|
|
78
|
-
|
|
79
|
-
-- Client-side:
|
|
80
|
-
local clientComm = ClientComm.new(someParent)
|
|
81
|
-
local myFunc = clientComm:GetFunction("MyFunction")
|
|
82
|
-
local uppercase = myFunc("hello world")
|
|
83
|
-
print(uppercase) --> HELLO WORLD
|
|
84
|
-
|
|
85
|
-
-- Client-side, using promises:
|
|
86
|
-
local clientComm = ClientComm.new(someParent, true)
|
|
87
|
-
local myFunc = clientComm:GetFunction("MyFunction")
|
|
88
|
-
myFunc("hi there"):andThen(function(msg)
|
|
89
|
-
print(msg) --> HI THERE
|
|
90
|
-
end):catch(function(err)
|
|
91
|
-
print("Error:", err)
|
|
92
|
-
end)
|
|
93
|
-
```
|
|
94
|
-
]=]
|
|
95
|
-
function ClientComm:GetFunction(
|
|
96
|
-
name: string,
|
|
97
|
-
inboundMiddleware: Types.ClientMiddleware?,
|
|
98
|
-
outboundMiddleware: Types.ClientMiddleware?
|
|
99
|
-
)
|
|
100
|
-
return Comm.GetFunction(self._instancesFolder, name, self._usePromise, inboundMiddleware, outboundMiddleware)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
--[=[
|
|
104
|
-
@param name string
|
|
105
|
-
@param inboundMiddleware ClientMiddleware?
|
|
106
|
-
@param outboundMiddleware ClientMiddleware?
|
|
107
|
-
@return ClientRemoteSignal
|
|
108
|
-
Returns a new ClientRemoteSignal that mirrors the matching RemoteSignal created by
|
|
109
|
-
ServerComm with the same matching `name`.
|
|
110
|
-
|
|
111
|
-
```lua
|
|
112
|
-
local mySignal = clientComm:GetSignal("MySignal")
|
|
113
|
-
|
|
114
|
-
-- Listen for data from the server:
|
|
115
|
-
mySignal:Connect(function(message)
|
|
116
|
-
print("Received message from server:", message)
|
|
117
|
-
end)
|
|
118
|
-
|
|
119
|
-
-- Send data to the server:
|
|
120
|
-
mySignal:Fire("Hello!")
|
|
121
|
-
```
|
|
122
|
-
]=]
|
|
123
|
-
function ClientComm:GetSignal(
|
|
124
|
-
name: string,
|
|
125
|
-
inboundMiddleware: Types.ClientMiddleware?,
|
|
126
|
-
outboundMiddleware: Types.ClientMiddleware?
|
|
127
|
-
)
|
|
128
|
-
return Comm.GetSignal(self._instancesFolder, name, inboundMiddleware, outboundMiddleware)
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
--[=[
|
|
132
|
-
@param name string
|
|
133
|
-
@param inboundMiddleware ClientMiddleware?
|
|
134
|
-
@param outboundMiddleware ClientMiddleware?
|
|
135
|
-
@return ClientRemoteProperty
|
|
136
|
-
Returns a new ClientRemoteProperty that mirrors the matching RemoteProperty created by
|
|
137
|
-
ServerComm with the same matching `name`.
|
|
138
|
-
|
|
139
|
-
Take a look at the ClientRemoteProperty documentation for more info, such as
|
|
140
|
-
understanding how to wait for data to be ready.
|
|
141
|
-
|
|
142
|
-
```lua
|
|
143
|
-
local mapInfo = clientComm:GetProperty("MapInfo")
|
|
144
|
-
|
|
145
|
-
-- Observe the initial value of mapInfo, and all subsequent changes:
|
|
146
|
-
mapInfo:Observe(function(info)
|
|
147
|
-
print("Current map info", info)
|
|
148
|
-
end)
|
|
149
|
-
|
|
150
|
-
-- Check to see if data is initially ready:
|
|
151
|
-
if mapInfo:IsReady() then
|
|
152
|
-
-- Get the data:
|
|
153
|
-
local info = mapInfo:Get()
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
-- Get a promise that resolves once the data is ready (resolves immediately if already ready):
|
|
157
|
-
mapInfo:OnReady():andThen(function(info)
|
|
158
|
-
print("Map info is ready with info", info)
|
|
159
|
-
end)
|
|
160
|
-
|
|
161
|
-
-- Same as above, but yields thread:
|
|
162
|
-
local success, info = mapInfo:OnReady():await()
|
|
163
|
-
```
|
|
164
|
-
]=]
|
|
165
|
-
function ClientComm:GetProperty(
|
|
166
|
-
name: string,
|
|
167
|
-
inboundMiddleware: Types.ClientMiddleware?,
|
|
168
|
-
outboundMiddleware: Types.ClientMiddleware?
|
|
169
|
-
)
|
|
170
|
-
return Comm.GetProperty(self._instancesFolder, name, inboundMiddleware, outboundMiddleware)
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
--[=[
|
|
174
|
-
@param inboundMiddleware ClientMiddleware?
|
|
175
|
-
@param outboundMiddleware ClientMiddleware?
|
|
176
|
-
@return table
|
|
177
|
-
Returns an object which maps RemoteFunctions as methods
|
|
178
|
-
and RemoteEvents as fields.
|
|
179
|
-
```lua
|
|
180
|
-
-- Server-side:
|
|
181
|
-
serverComm:BindFunction("Test", function(player) end)
|
|
182
|
-
serverComm:CreateSignal("MySignal")
|
|
183
|
-
serverComm:CreateProperty("MyProperty", 10)
|
|
184
|
-
|
|
185
|
-
-- Client-side
|
|
186
|
-
local obj = clientComm:BuildObject()
|
|
187
|
-
obj:Test()
|
|
188
|
-
obj.MySignal:Connect(function(data) end)
|
|
189
|
-
obj.MyProperty:Observe(function(value) end)
|
|
190
|
-
```
|
|
191
|
-
]=]
|
|
192
|
-
function ClientComm:BuildObject(inboundMiddleware: Types.ClientMiddleware?, outboundMiddleware: Types.ClientMiddleware?)
|
|
193
|
-
local obj = {}
|
|
194
|
-
local rfFolder = self._instancesFolder:FindFirstChild("RF")
|
|
195
|
-
local reFolder = self._instancesFolder:FindFirstChild("RE")
|
|
196
|
-
local rpFolder = self._instancesFolder:FindFirstChild("RP")
|
|
197
|
-
if rfFolder then
|
|
198
|
-
for _, rf in rfFolder:GetChildren() do
|
|
199
|
-
if not rf:IsA("RemoteFunction") then
|
|
200
|
-
continue
|
|
201
|
-
end
|
|
202
|
-
local f = self:GetFunction(rf.Name, inboundMiddleware, outboundMiddleware)
|
|
203
|
-
obj[rf.Name] = function(_self, ...)
|
|
204
|
-
return f(...)
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
if reFolder then
|
|
209
|
-
for _, re in reFolder:GetChildren() do
|
|
210
|
-
if (not re:IsA("RemoteEvent")) and (not re:IsA("UnreliableRemoteEvent")) then
|
|
211
|
-
continue
|
|
212
|
-
end
|
|
213
|
-
obj[re.Name] = self:GetSignal(re.Name, inboundMiddleware, outboundMiddleware)
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
if rpFolder then
|
|
217
|
-
for _, re in rpFolder:GetChildren() do
|
|
218
|
-
if not re:IsA("RemoteEvent") then
|
|
219
|
-
continue
|
|
220
|
-
end
|
|
221
|
-
obj[re.Name] = self:GetProperty(re.Name, inboundMiddleware, outboundMiddleware)
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
return obj
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
--[=[
|
|
228
|
-
Destroys the ClientComm object.
|
|
229
|
-
]=]
|
|
230
|
-
function ClientComm:Destroy() end
|
|
231
|
-
|
|
232
|
-
return ClientComm
|
|
1
|
+
-- ClientComm
|
|
2
|
+
-- Stephen Leitnick
|
|
3
|
+
-- December 20, 2021
|
|
4
|
+
|
|
5
|
+
local Comm = require(script.Parent)
|
|
6
|
+
local Types = require(script.Parent.Parent.Types)
|
|
7
|
+
local Util = require(script.Parent.Parent.Util)
|
|
8
|
+
|
|
9
|
+
--[=[
|
|
10
|
+
@class ClientComm
|
|
11
|
+
@client
|
|
12
|
+
]=]
|
|
13
|
+
local ClientComm = {}
|
|
14
|
+
ClientComm.__index = ClientComm
|
|
15
|
+
|
|
16
|
+
--[=[
|
|
17
|
+
@within ClientComm
|
|
18
|
+
@type ClientMiddlewareFn (args: {any}) -> (shouldContinue: boolean, ...: any)
|
|
19
|
+
The middleware function takes the arguments (as a table array), and should
|
|
20
|
+
return `true|false` to indicate if the process should continue.
|
|
21
|
+
|
|
22
|
+
If returning `false`, the optional varargs after the `false` are used as the new return values
|
|
23
|
+
to whatever was calling the middleware.
|
|
24
|
+
]=]
|
|
25
|
+
--[=[
|
|
26
|
+
@within ClientComm
|
|
27
|
+
@type ClientMiddleware {ClientMiddlewareFn}
|
|
28
|
+
Array of middleware functions.
|
|
29
|
+
]=]
|
|
30
|
+
|
|
31
|
+
--[=[
|
|
32
|
+
@return ClientComm
|
|
33
|
+
Constructs a ClientComm object.
|
|
34
|
+
|
|
35
|
+
If `usePromise` is set to `true`, then `GetFunction` will generate a function that returns a Promise
|
|
36
|
+
that resolves with the server response. If set to `false`, the function will act like a normal
|
|
37
|
+
call to a RemoteFunction and yield until the function responds.
|
|
38
|
+
|
|
39
|
+
```lua
|
|
40
|
+
local clientComm = ClientComm.new(game:GetService("ReplicatedStorage"), true)
|
|
41
|
+
|
|
42
|
+
-- If using a unique namespace with ServerComm, include it as second argument:
|
|
43
|
+
local clientComm = ClientComm.new(game:GetService("ReplicatedStorage"), true, "MyNamespace")
|
|
44
|
+
```
|
|
45
|
+
]=]
|
|
46
|
+
function ClientComm.new(parent: Instance, usePromise: boolean, namespace: string?)
|
|
47
|
+
assert(not Util.IsServer, "ClientComm must be constructed from the client")
|
|
48
|
+
assert(typeof(parent) == "Instance", "Parent must be of type Instance")
|
|
49
|
+
local ns = Util.DefaultCommFolderName
|
|
50
|
+
if namespace then
|
|
51
|
+
ns = namespace
|
|
52
|
+
end
|
|
53
|
+
local folder: Instance? = parent:WaitForChild(ns, Util.WaitForChildTimeout)
|
|
54
|
+
assert(folder ~= nil, "Could not find namespace for ClientComm in parent: " .. ns)
|
|
55
|
+
local self = setmetatable({}, ClientComm)
|
|
56
|
+
self._instancesFolder = folder
|
|
57
|
+
self._usePromise = usePromise
|
|
58
|
+
return self
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
--[=[
|
|
62
|
+
@param name string
|
|
63
|
+
@param inboundMiddleware ClientMiddleware?
|
|
64
|
+
@param outboundMiddleware ClientMiddleware?
|
|
65
|
+
@return (...: any) -> any
|
|
66
|
+
|
|
67
|
+
Generates a function on the matching RemoteFunction generated with ServerComm. The function
|
|
68
|
+
can then be called to invoke the server. If this `ClientComm` object was created with
|
|
69
|
+
the `usePromise` parameter set to `true`, then this generated function will return
|
|
70
|
+
a Promise when called.
|
|
71
|
+
|
|
72
|
+
```lua
|
|
73
|
+
-- Server-side:
|
|
74
|
+
local serverComm = ServerComm.new(someParent)
|
|
75
|
+
serverComm:BindFunction("MyFunction", function(player, msg)
|
|
76
|
+
return msg:upper()
|
|
77
|
+
end)
|
|
78
|
+
|
|
79
|
+
-- Client-side:
|
|
80
|
+
local clientComm = ClientComm.new(someParent)
|
|
81
|
+
local myFunc = clientComm:GetFunction("MyFunction")
|
|
82
|
+
local uppercase = myFunc("hello world")
|
|
83
|
+
print(uppercase) --> HELLO WORLD
|
|
84
|
+
|
|
85
|
+
-- Client-side, using promises:
|
|
86
|
+
local clientComm = ClientComm.new(someParent, true)
|
|
87
|
+
local myFunc = clientComm:GetFunction("MyFunction")
|
|
88
|
+
myFunc("hi there"):andThen(function(msg)
|
|
89
|
+
print(msg) --> HI THERE
|
|
90
|
+
end):catch(function(err)
|
|
91
|
+
print("Error:", err)
|
|
92
|
+
end)
|
|
93
|
+
```
|
|
94
|
+
]=]
|
|
95
|
+
function ClientComm:GetFunction(
|
|
96
|
+
name: string,
|
|
97
|
+
inboundMiddleware: Types.ClientMiddleware?,
|
|
98
|
+
outboundMiddleware: Types.ClientMiddleware?
|
|
99
|
+
)
|
|
100
|
+
return Comm.GetFunction(self._instancesFolder, name, self._usePromise, inboundMiddleware, outboundMiddleware)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
--[=[
|
|
104
|
+
@param name string
|
|
105
|
+
@param inboundMiddleware ClientMiddleware?
|
|
106
|
+
@param outboundMiddleware ClientMiddleware?
|
|
107
|
+
@return ClientRemoteSignal
|
|
108
|
+
Returns a new ClientRemoteSignal that mirrors the matching RemoteSignal created by
|
|
109
|
+
ServerComm with the same matching `name`.
|
|
110
|
+
|
|
111
|
+
```lua
|
|
112
|
+
local mySignal = clientComm:GetSignal("MySignal")
|
|
113
|
+
|
|
114
|
+
-- Listen for data from the server:
|
|
115
|
+
mySignal:Connect(function(message)
|
|
116
|
+
print("Received message from server:", message)
|
|
117
|
+
end)
|
|
118
|
+
|
|
119
|
+
-- Send data to the server:
|
|
120
|
+
mySignal:Fire("Hello!")
|
|
121
|
+
```
|
|
122
|
+
]=]
|
|
123
|
+
function ClientComm:GetSignal(
|
|
124
|
+
name: string,
|
|
125
|
+
inboundMiddleware: Types.ClientMiddleware?,
|
|
126
|
+
outboundMiddleware: Types.ClientMiddleware?
|
|
127
|
+
)
|
|
128
|
+
return Comm.GetSignal(self._instancesFolder, name, inboundMiddleware, outboundMiddleware)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
--[=[
|
|
132
|
+
@param name string
|
|
133
|
+
@param inboundMiddleware ClientMiddleware?
|
|
134
|
+
@param outboundMiddleware ClientMiddleware?
|
|
135
|
+
@return ClientRemoteProperty
|
|
136
|
+
Returns a new ClientRemoteProperty that mirrors the matching RemoteProperty created by
|
|
137
|
+
ServerComm with the same matching `name`.
|
|
138
|
+
|
|
139
|
+
Take a look at the ClientRemoteProperty documentation for more info, such as
|
|
140
|
+
understanding how to wait for data to be ready.
|
|
141
|
+
|
|
142
|
+
```lua
|
|
143
|
+
local mapInfo = clientComm:GetProperty("MapInfo")
|
|
144
|
+
|
|
145
|
+
-- Observe the initial value of mapInfo, and all subsequent changes:
|
|
146
|
+
mapInfo:Observe(function(info)
|
|
147
|
+
print("Current map info", info)
|
|
148
|
+
end)
|
|
149
|
+
|
|
150
|
+
-- Check to see if data is initially ready:
|
|
151
|
+
if mapInfo:IsReady() then
|
|
152
|
+
-- Get the data:
|
|
153
|
+
local info = mapInfo:Get()
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
-- Get a promise that resolves once the data is ready (resolves immediately if already ready):
|
|
157
|
+
mapInfo:OnReady():andThen(function(info)
|
|
158
|
+
print("Map info is ready with info", info)
|
|
159
|
+
end)
|
|
160
|
+
|
|
161
|
+
-- Same as above, but yields thread:
|
|
162
|
+
local success, info = mapInfo:OnReady():await()
|
|
163
|
+
```
|
|
164
|
+
]=]
|
|
165
|
+
function ClientComm:GetProperty(
|
|
166
|
+
name: string,
|
|
167
|
+
inboundMiddleware: Types.ClientMiddleware?,
|
|
168
|
+
outboundMiddleware: Types.ClientMiddleware?
|
|
169
|
+
)
|
|
170
|
+
return Comm.GetProperty(self._instancesFolder, name, inboundMiddleware, outboundMiddleware)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
--[=[
|
|
174
|
+
@param inboundMiddleware ClientMiddleware?
|
|
175
|
+
@param outboundMiddleware ClientMiddleware?
|
|
176
|
+
@return table
|
|
177
|
+
Returns an object which maps RemoteFunctions as methods
|
|
178
|
+
and RemoteEvents as fields.
|
|
179
|
+
```lua
|
|
180
|
+
-- Server-side:
|
|
181
|
+
serverComm:BindFunction("Test", function(player) end)
|
|
182
|
+
serverComm:CreateSignal("MySignal")
|
|
183
|
+
serverComm:CreateProperty("MyProperty", 10)
|
|
184
|
+
|
|
185
|
+
-- Client-side
|
|
186
|
+
local obj = clientComm:BuildObject()
|
|
187
|
+
obj:Test()
|
|
188
|
+
obj.MySignal:Connect(function(data) end)
|
|
189
|
+
obj.MyProperty:Observe(function(value) end)
|
|
190
|
+
```
|
|
191
|
+
]=]
|
|
192
|
+
function ClientComm:BuildObject(inboundMiddleware: Types.ClientMiddleware?, outboundMiddleware: Types.ClientMiddleware?)
|
|
193
|
+
local obj = {}
|
|
194
|
+
local rfFolder = self._instancesFolder:FindFirstChild("RF")
|
|
195
|
+
local reFolder = self._instancesFolder:FindFirstChild("RE")
|
|
196
|
+
local rpFolder = self._instancesFolder:FindFirstChild("RP")
|
|
197
|
+
if rfFolder then
|
|
198
|
+
for _, rf in rfFolder:GetChildren() do
|
|
199
|
+
if not rf:IsA("RemoteFunction") then
|
|
200
|
+
continue
|
|
201
|
+
end
|
|
202
|
+
local f = self:GetFunction(rf.Name, inboundMiddleware, outboundMiddleware)
|
|
203
|
+
obj[rf.Name] = function(_self, ...)
|
|
204
|
+
return f(...)
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
if reFolder then
|
|
209
|
+
for _, re in reFolder:GetChildren() do
|
|
210
|
+
if (not re:IsA("RemoteEvent")) and (not re:IsA("UnreliableRemoteEvent")) then
|
|
211
|
+
continue
|
|
212
|
+
end
|
|
213
|
+
obj[re.Name] = self:GetSignal(re.Name, inboundMiddleware, outboundMiddleware)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
if rpFolder then
|
|
217
|
+
for _, re in rpFolder:GetChildren() do
|
|
218
|
+
if not re:IsA("RemoteEvent") then
|
|
219
|
+
continue
|
|
220
|
+
end
|
|
221
|
+
obj[re.Name] = self:GetProperty(re.Name, inboundMiddleware, outboundMiddleware)
|
|
222
|
+
end
|
|
223
|
+
end
|
|
224
|
+
return obj
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
--[=[
|
|
228
|
+
Destroys the ClientComm object.
|
|
229
|
+
]=]
|
|
230
|
+
function ClientComm:Destroy() end
|
|
231
|
+
|
|
232
|
+
return ClientComm
|