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.
Files changed (248) hide show
  1. package/README.md +122 -0
  2. package/commands/setup-game.md +108 -0
  3. package/commands/sync-check.md +53 -0
  4. package/core/roblox-core.md +93 -0
  5. package/dist/server.js +167 -0
  6. package/package.json +35 -0
  7. package/skills/roblox-analytics/SKILL.md +277 -0
  8. package/skills/roblox-analytics/references/event-batcher.luau +75 -0
  9. package/skills/roblox-animation-vfx/SKILL.md +1325 -0
  10. package/skills/roblox-architecture/SKILL.md +863 -0
  11. package/skills/roblox-architecture/references/combat-systems.md +1381 -0
  12. package/skills/roblox-code-review/SKILL.md +687 -0
  13. package/skills/roblox-data/SKILL.md +889 -0
  14. package/skills/roblox-data/references/inventory-systems.md +1729 -0
  15. package/skills/roblox-debug/SKILL.md +99 -0
  16. package/skills/roblox-gui/SKILL.md +1103 -0
  17. package/skills/roblox-gui-fusion/SKILL.md +150 -0
  18. package/skills/roblox-gui-fusion/references/inventory.luau +427 -0
  19. package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -0
  20. package/skills/roblox-gui-fusion/references/shop.luau +411 -0
  21. package/skills/roblox-luau-mastery/SKILL.md +1519 -0
  22. package/skills/roblox-monetization/SKILL.md +1084 -0
  23. package/skills/roblox-monetization/references/process-receipt.luau +131 -0
  24. package/skills/roblox-networking/SKILL.md +669 -0
  25. package/skills/roblox-networking/references/remote-validator.luau +193 -0
  26. package/skills/roblox-publish-checklist/SKILL.md +128 -0
  27. package/skills/roblox-runtime/SKILL.md +753 -0
  28. package/skills/roblox-sharp-edges/SKILL.md +295 -0
  29. package/skills/roblox-sync/SKILL.md +126 -0
  30. package/skills/roblox-testing/SKILL.md +943 -0
  31. package/skills/roblox-tooling/SKILL.md +150 -0
  32. package/vendor/LICENSES/ProfileStore-LICENSE +201 -0
  33. package/vendor/LICENSES/RbxUtil-LICENSE +7 -0
  34. package/vendor/LICENSES/promise-LICENSE +21 -0
  35. package/vendor/LICENSES/t-LICENSE +21 -0
  36. package/vendor/LICENSES/testez-LICENSE +201 -0
  37. package/vendor/README.md +84 -0
  38. package/vendor/fusion/Animation/ExternalTime.luau +84 -0
  39. package/vendor/fusion/Animation/Spring.luau +322 -0
  40. package/vendor/fusion/Animation/Stopwatch.luau +128 -0
  41. package/vendor/fusion/Animation/Tween.luau +187 -0
  42. package/vendor/fusion/Animation/getTweenDuration.luau +27 -0
  43. package/vendor/fusion/Animation/getTweenRatio.luau +47 -0
  44. package/vendor/fusion/Animation/lerpType.luau +164 -0
  45. package/vendor/fusion/Animation/packType.luau +100 -0
  46. package/vendor/fusion/Animation/springCoefficients.luau +80 -0
  47. package/vendor/fusion/Animation/unpackType.luau +103 -0
  48. package/vendor/fusion/Colour/Oklab.luau +70 -0
  49. package/vendor/fusion/Colour/sRGB.luau +55 -0
  50. package/vendor/fusion/External.luau +168 -0
  51. package/vendor/fusion/ExternalDebug.luau +70 -0
  52. package/vendor/fusion/Graph/Observer.luau +114 -0
  53. package/vendor/fusion/Graph/castToGraph.luau +29 -0
  54. package/vendor/fusion/Graph/change.luau +81 -0
  55. package/vendor/fusion/Graph/depend.luau +33 -0
  56. package/vendor/fusion/Graph/evaluate.luau +56 -0
  57. package/vendor/fusion/Instances/Attribute.luau +58 -0
  58. package/vendor/fusion/Instances/AttributeChange.luau +47 -0
  59. package/vendor/fusion/Instances/AttributeOut.luau +63 -0
  60. package/vendor/fusion/Instances/Child.luau +21 -0
  61. package/vendor/fusion/Instances/Children.luau +148 -0
  62. package/vendor/fusion/Instances/Hydrate.luau +33 -0
  63. package/vendor/fusion/Instances/New.luau +53 -0
  64. package/vendor/fusion/Instances/OnChange.luau +50 -0
  65. package/vendor/fusion/Instances/OnEvent.luau +54 -0
  66. package/vendor/fusion/Instances/Out.luau +69 -0
  67. package/vendor/fusion/Instances/applyInstanceProps.luau +149 -0
  68. package/vendor/fusion/Instances/defaultProps.luau +194 -0
  69. package/vendor/fusion/LICENSE +21 -0
  70. package/vendor/fusion/Logging/formatError.luau +49 -0
  71. package/vendor/fusion/Logging/messages.luau +52 -0
  72. package/vendor/fusion/Logging/parseError.luau +25 -0
  73. package/vendor/fusion/Memory/checkLifetime.luau +134 -0
  74. package/vendor/fusion/Memory/deriveScope.luau +24 -0
  75. package/vendor/fusion/Memory/deriveScopeImpl.luau +45 -0
  76. package/vendor/fusion/Memory/doCleanup.luau +79 -0
  77. package/vendor/fusion/Memory/innerScope.luau +34 -0
  78. package/vendor/fusion/Memory/legacyCleanup.luau +18 -0
  79. package/vendor/fusion/Memory/needsDestruction.luau +17 -0
  80. package/vendor/fusion/Memory/poisonScope.luau +34 -0
  81. package/vendor/fusion/Memory/scopePool.luau +55 -0
  82. package/vendor/fusion/Memory/scoped.luau +27 -0
  83. package/vendor/fusion/Memory/whichLivesLonger.luau +75 -0
  84. package/vendor/fusion/RobloxExternal.luau +98 -0
  85. package/vendor/fusion/State/Computed.luau +139 -0
  86. package/vendor/fusion/State/For/Disassembly.luau +211 -0
  87. package/vendor/fusion/State/For/ForTypes.luau +30 -0
  88. package/vendor/fusion/State/For/init.luau +110 -0
  89. package/vendor/fusion/State/ForKeys.luau +94 -0
  90. package/vendor/fusion/State/ForPairs.luau +97 -0
  91. package/vendor/fusion/State/ForValues.luau +94 -0
  92. package/vendor/fusion/State/Value.luau +88 -0
  93. package/vendor/fusion/State/castToState.luau +26 -0
  94. package/vendor/fusion/State/peek.luau +31 -0
  95. package/vendor/fusion/State/updateAll.luau +1 -0
  96. package/vendor/fusion/Types.luau +314 -0
  97. package/vendor/fusion/Utility/Contextual.luau +91 -0
  98. package/vendor/fusion/Utility/Safe.luau +23 -0
  99. package/vendor/fusion/Utility/isSimilar.luau +29 -0
  100. package/vendor/fusion/Utility/merge.luau +35 -0
  101. package/vendor/fusion/Utility/nameOf.luau +35 -0
  102. package/vendor/fusion/Utility/never.luau +14 -0
  103. package/vendor/fusion/Utility/nicknames.luau +11 -0
  104. package/vendor/fusion/Utility/xtypeof.luau +27 -0
  105. package/vendor/fusion/init.luau +82 -0
  106. package/vendor/profilestore/init.luau +2243 -0
  107. package/vendor/promise/init.luau +1982 -0
  108. package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -0
  109. package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -0
  110. package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -0
  111. package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -0
  112. package/vendor/rbxutil/buffer-util/Types.luau +60 -0
  113. package/vendor/rbxutil/buffer-util/index.d.ts +153 -0
  114. package/vendor/rbxutil/buffer-util/init.luau +41 -0
  115. package/vendor/rbxutil/buffer-util/package.json +16 -0
  116. package/vendor/rbxutil/buffer-util/wally.toml +9 -0
  117. package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -0
  118. package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -0
  119. package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -0
  120. package/vendor/rbxutil/comm/Client/init.luau +135 -0
  121. package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -0
  122. package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -0
  123. package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -0
  124. package/vendor/rbxutil/comm/Server/init.luau +140 -0
  125. package/vendor/rbxutil/comm/Types.luau +18 -0
  126. package/vendor/rbxutil/comm/Util.luau +27 -0
  127. package/vendor/rbxutil/comm/init.luau +35 -0
  128. package/vendor/rbxutil/comm/wally.toml +13 -0
  129. package/vendor/rbxutil/component/init.luau +759 -0
  130. package/vendor/rbxutil/component/init.test.luau +311 -0
  131. package/vendor/rbxutil/component/wally.toml +14 -0
  132. package/vendor/rbxutil/concur/init.luau +542 -0
  133. package/vendor/rbxutil/concur/init.test.luau +364 -0
  134. package/vendor/rbxutil/concur/wally.toml +8 -0
  135. package/vendor/rbxutil/enum-list/init.luau +101 -0
  136. package/vendor/rbxutil/enum-list/init.test.luau +91 -0
  137. package/vendor/rbxutil/enum-list/wally.toml +8 -0
  138. package/vendor/rbxutil/find/index.d.ts +20 -0
  139. package/vendor/rbxutil/find/init.luau +44 -0
  140. package/vendor/rbxutil/find/package.json +17 -0
  141. package/vendor/rbxutil/find/wally.toml +8 -0
  142. package/vendor/rbxutil/input/Gamepad.luau +559 -0
  143. package/vendor/rbxutil/input/Keyboard.luau +124 -0
  144. package/vendor/rbxutil/input/Mouse.luau +278 -0
  145. package/vendor/rbxutil/input/PreferredInput.luau +91 -0
  146. package/vendor/rbxutil/input/Touch.luau +120 -0
  147. package/vendor/rbxutil/input/init.luau +33 -0
  148. package/vendor/rbxutil/input/wally.toml +12 -0
  149. package/vendor/rbxutil/loader/index.d.ts +15 -0
  150. package/vendor/rbxutil/loader/init.luau +137 -0
  151. package/vendor/rbxutil/loader/wally.toml +8 -0
  152. package/vendor/rbxutil/log/index.d.ts +38 -0
  153. package/vendor/rbxutil/log/init.luau +746 -0
  154. package/vendor/rbxutil/log/wally.toml +8 -0
  155. package/vendor/rbxutil/net/init.luau +190 -0
  156. package/vendor/rbxutil/net/wally.toml +8 -0
  157. package/vendor/rbxutil/option/index.d.ts +44 -0
  158. package/vendor/rbxutil/option/init.luau +489 -0
  159. package/vendor/rbxutil/option/init.test.luau +342 -0
  160. package/vendor/rbxutil/option/wally.toml +8 -0
  161. package/vendor/rbxutil/pid/index.d.ts +53 -0
  162. package/vendor/rbxutil/pid/init.luau +195 -0
  163. package/vendor/rbxutil/pid/package.json +16 -0
  164. package/vendor/rbxutil/pid/wally.toml +9 -0
  165. package/vendor/rbxutil/quaternion/index.d.ts +117 -0
  166. package/vendor/rbxutil/quaternion/init.luau +570 -0
  167. package/vendor/rbxutil/quaternion/package.json +16 -0
  168. package/vendor/rbxutil/quaternion/wally.toml +9 -0
  169. package/vendor/rbxutil/query/index.d.ts +43 -0
  170. package/vendor/rbxutil/query/init.luau +117 -0
  171. package/vendor/rbxutil/query/package.json +18 -0
  172. package/vendor/rbxutil/query/wally.toml +9 -0
  173. package/vendor/rbxutil/sequent/index.d.ts +28 -0
  174. package/vendor/rbxutil/sequent/init.luau +340 -0
  175. package/vendor/rbxutil/sequent/package.json +16 -0
  176. package/vendor/rbxutil/sequent/wally.toml +9 -0
  177. package/vendor/rbxutil/ser/init.luau +175 -0
  178. package/vendor/rbxutil/ser/init.test.luau +50 -0
  179. package/vendor/rbxutil/ser/wally.toml +11 -0
  180. package/vendor/rbxutil/shake/index.d.ts +36 -0
  181. package/vendor/rbxutil/shake/init.luau +532 -0
  182. package/vendor/rbxutil/shake/init.test.luau +267 -0
  183. package/vendor/rbxutil/shake/package.json +16 -0
  184. package/vendor/rbxutil/shake/wally.toml +9 -0
  185. package/vendor/rbxutil/signal/index.d.ts +100 -0
  186. package/vendor/rbxutil/signal/init.luau +432 -0
  187. package/vendor/rbxutil/signal/init.test.luau +190 -0
  188. package/vendor/rbxutil/signal/package.json +17 -0
  189. package/vendor/rbxutil/signal/wally.toml +9 -0
  190. package/vendor/rbxutil/silo/TableWatcher.luau +65 -0
  191. package/vendor/rbxutil/silo/Util.luau +55 -0
  192. package/vendor/rbxutil/silo/init.luau +338 -0
  193. package/vendor/rbxutil/silo/init.test.luau +215 -0
  194. package/vendor/rbxutil/silo/wally.toml +8 -0
  195. package/vendor/rbxutil/spring/index.d.ts +40 -0
  196. package/vendor/rbxutil/spring/init.luau +97 -0
  197. package/vendor/rbxutil/spring/package.json +17 -0
  198. package/vendor/rbxutil/spring/wally.toml +8 -0
  199. package/vendor/rbxutil/stream/index.d.ts +88 -0
  200. package/vendor/rbxutil/stream/init.luau +597 -0
  201. package/vendor/rbxutil/stream/package.json +18 -0
  202. package/vendor/rbxutil/stream/wally.toml +9 -0
  203. package/vendor/rbxutil/streamable/Streamable.luau +202 -0
  204. package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -0
  205. package/vendor/rbxutil/streamable/init.luau +8 -0
  206. package/vendor/rbxutil/streamable/wally.toml +12 -0
  207. package/vendor/rbxutil/symbol/init.luau +56 -0
  208. package/vendor/rbxutil/symbol/init.test.luau +37 -0
  209. package/vendor/rbxutil/symbol/wally.toml +8 -0
  210. package/vendor/rbxutil/table-util/init.luau +938 -0
  211. package/vendor/rbxutil/table-util/init.test.luau +439 -0
  212. package/vendor/rbxutil/table-util/wally.toml +8 -0
  213. package/vendor/rbxutil/task-queue/index.d.ts +27 -0
  214. package/vendor/rbxutil/task-queue/init.luau +97 -0
  215. package/vendor/rbxutil/task-queue/wally.toml +8 -0
  216. package/vendor/rbxutil/timer/index.d.ts +81 -0
  217. package/vendor/rbxutil/timer/init.luau +249 -0
  218. package/vendor/rbxutil/timer/init.test.luau +73 -0
  219. package/vendor/rbxutil/timer/wally.toml +11 -0
  220. package/vendor/rbxutil/tree/index.d.ts +15 -0
  221. package/vendor/rbxutil/tree/init.luau +137 -0
  222. package/vendor/rbxutil/tree/wally.toml +8 -0
  223. package/vendor/rbxutil/trove/index.d.ts +46 -0
  224. package/vendor/rbxutil/trove/init.luau +787 -0
  225. package/vendor/rbxutil/trove/init.test.luau +203 -0
  226. package/vendor/rbxutil/trove/wally.toml +8 -0
  227. package/vendor/rbxutil/typed-remote/init.luau +196 -0
  228. package/vendor/rbxutil/typed-remote/wally.toml +8 -0
  229. package/vendor/rbxutil/wait-for/index.d.ts +17 -0
  230. package/vendor/rbxutil/wait-for/init.luau +257 -0
  231. package/vendor/rbxutil/wait-for/init.test.luau +182 -0
  232. package/vendor/rbxutil/wait-for/wally.toml +11 -0
  233. package/vendor/t/t.lua +1350 -0
  234. package/vendor/testez/Context.lua +26 -0
  235. package/vendor/testez/Expectation.lua +311 -0
  236. package/vendor/testez/ExpectationContext.lua +38 -0
  237. package/vendor/testez/LifecycleHooks.lua +89 -0
  238. package/vendor/testez/Reporters/TeamCityReporter.lua +102 -0
  239. package/vendor/testez/Reporters/TextReporter.lua +106 -0
  240. package/vendor/testez/Reporters/TextReporterQuiet.lua +97 -0
  241. package/vendor/testez/TestBootstrap.lua +147 -0
  242. package/vendor/testez/TestEnum.lua +28 -0
  243. package/vendor/testez/TestPlan.lua +304 -0
  244. package/vendor/testez/TestPlanner.lua +40 -0
  245. package/vendor/testez/TestResults.lua +112 -0
  246. package/vendor/testez/TestRunner.lua +188 -0
  247. package/vendor/testez/TestSession.lua +243 -0
  248. package/vendor/testez/init.lua +40 -0
@@ -0,0 +1,202 @@
1
+ --!strict
2
+
3
+ -- Streamable
4
+ -- Stephen Leitnick
5
+ -- March 03, 2021
6
+
7
+ type StreamableWithInstance = {
8
+ Instance: Instance?,
9
+ [any]: any,
10
+ }
11
+
12
+ local Trove = require(script.Parent.Parent.Trove)
13
+ local Signal = require(script.Parent.Parent.Signal)
14
+
15
+ --[=[
16
+ @within Streamable
17
+ @prop Instance Instance
18
+ The current instance represented by the Streamable. If this
19
+ is being observed, it will always exist. If not currently
20
+ being observed, this will be `nil`.
21
+ ]=]
22
+
23
+ --[=[
24
+ @class Streamable
25
+ @client
26
+ Because parts in StreamingEnabled games can stream in and out of existence at
27
+ any point in time, it is hard to write code to interact with them. This is
28
+ where Streamables come into play. Streamables will observe the existence of
29
+ a given instance, and will signal when the instance exists and does not
30
+ exist.
31
+
32
+ The API is very simple. Create a Streamable that points to a certain parent
33
+ and looks for a specific child instance (typically a BasePart). Then, call
34
+ the `Observe` method to observe when the instance streams in and out.
35
+
36
+ ```lua
37
+ local Streamable = require(packages.Streamable).Streamable
38
+
39
+ -- Models might take a bit to load, but the model instance
40
+ -- is never removed, thus we can use WaitForChild.
41
+ local model = workspace:WaitForChild("MyModel")
42
+
43
+ -- Watch for a specific part in the model:
44
+ local partStreamable = Streamable.new(model, "SomePart")
45
+
46
+ partStreamable:Observe(function(part, trove)
47
+ print(part:GetFullName() .. " added")
48
+ -- Run code on the part here.
49
+ -- Use the trove to manage cleanup when the part goes away.
50
+ trove:Add(function()
51
+ -- General cleanup stuff
52
+ print(part.Name .. " removed")
53
+ end)
54
+ end)
55
+
56
+ -- Watch for the PrimaryPart of a model to exist:
57
+ local primaryStreamable = Streamable.primary(model)
58
+ primaryStreamable:Observe(function(primary, trove)
59
+ print("Model now has a PrimaryPart:", primary.Name)
60
+ trove:Add(function()
61
+ print("Model's PrimaryPart has been removed")
62
+ end)
63
+ end)
64
+
65
+ -- At any given point, accessing the Instance field will
66
+ -- reference the observed part, if it exists:
67
+ if partStreamable.Instance then
68
+ print("Streamable has its instance:", partStreamable.Instance)
69
+ end
70
+
71
+ -- When/if done, call Destroy on the streamable, which will
72
+ -- also clean up any observers:
73
+ partStreamable:Destroy()
74
+ primaryStreamable:Destroy()
75
+ ```
76
+
77
+ For more information on the mechanics of how StreamingEnabled works
78
+ and what sort of behavior to expect, see the
79
+ [Content Streaming](https://developer.roblox.com/en-us/articles/content-streaming#technical-behavior)
80
+ page. It is important to understand that only BaseParts and their descendants are streamed in/out,
81
+ whereas other instances are loaded during the initial client load. It is also important to understand
82
+ that streaming only occurs on the client. The server has immediate access to everything right away.
83
+ ]=]
84
+ local Streamable = {}
85
+ Streamable.__index = Streamable
86
+
87
+ --[=[
88
+ @return Streamable
89
+ @param parent Instance
90
+ @param childName string
91
+
92
+ Constructs a Streamable that watches for a direct child of name `childName`
93
+ within the `parent` Instance. Call `Observe` to observe the existence of
94
+ the child within the parent.
95
+ ]=]
96
+ function Streamable.new(parent: Instance, childName: string)
97
+ local self: StreamableWithInstance = {}
98
+ setmetatable(self, Streamable)
99
+
100
+ self._trove = Trove.new()
101
+ self._shown = self._trove:Construct(Signal)
102
+ self._shownTrove = Trove.new()
103
+ self._trove:Add(self._shownTrove)
104
+
105
+ self.Instance = parent:FindFirstChild(childName)
106
+
107
+ local function OnInstanceSet()
108
+ local instance = self.Instance
109
+ if typeof(instance) == "Instance" then
110
+ self._shown:Fire(instance, self._shownTrove)
111
+ self._shownTrove:Connect(instance:GetPropertyChangedSignal("Parent"), function()
112
+ if not instance.Parent then
113
+ self._shownTrove:Clean()
114
+ end
115
+ end)
116
+ self._shownTrove:Add(function()
117
+ if self.Instance == instance then
118
+ self.Instance = nil
119
+ end
120
+ end)
121
+ end
122
+ end
123
+
124
+ local function OnChildAdded(child: Instance)
125
+ if child.Name == childName and not self.Instance then
126
+ self.Instance = child
127
+ OnInstanceSet()
128
+ end
129
+ end
130
+
131
+ self._trove:Connect(parent.ChildAdded, OnChildAdded)
132
+ if self.Instance then
133
+ OnInstanceSet()
134
+ end
135
+
136
+ return self
137
+ end
138
+
139
+ --[=[
140
+ @return Streamable
141
+ @param parent Model
142
+
143
+ Constructs a streamable that watches for the PrimaryPart of the
144
+ given `parent` Model.
145
+ ]=]
146
+ function Streamable.primary(parent: Model)
147
+ local self: StreamableWithInstance = {}
148
+ setmetatable(self, Streamable)
149
+
150
+ self._trove = Trove.new()
151
+ self._shown = self._trove:Construct(Signal)
152
+ self._shownTrove = Trove.new()
153
+ self._trove:Add(self._shownTrove)
154
+
155
+ self.Instance = parent.PrimaryPart
156
+
157
+ local function OnPrimaryPartChanged()
158
+ local primaryPart = parent.PrimaryPart
159
+ self._shownTrove:Clean()
160
+ self.Instance = primaryPart
161
+ if primaryPart then
162
+ self._shown:Fire(primaryPart, self._shownTrove)
163
+ end
164
+ end
165
+
166
+ self._trove:Connect(parent:GetPropertyChangedSignal("PrimaryPart"), OnPrimaryPartChanged)
167
+ if self.Instance then
168
+ OnPrimaryPartChanged()
169
+ end
170
+
171
+ return self
172
+ end
173
+
174
+ --[=[
175
+ @param handler (instance: Instance, trove: Trove) -> nil
176
+ @return Connection
177
+
178
+ Observes the instance. The handler is called anytime the
179
+ instance comes into existence, and the trove given is
180
+ cleaned up when the instance goes away.
181
+
182
+ To stop observing, disconnect the returned connection.
183
+ ]=]
184
+ function Streamable:Observe(handler)
185
+ if self.Instance then
186
+ task.spawn(handler, self.Instance, self._shownTrove)
187
+ end
188
+ return self._shown:Connect(handler)
189
+ end
190
+
191
+ --[=[
192
+ Destroys the Streamable. Any observers will be disconnected,
193
+ which also means that troves within observers will be cleaned
194
+ up. This should be called when a streamable is no longer needed.
195
+ ]=]
196
+ function Streamable:Destroy()
197
+ self._trove:Destroy()
198
+ end
199
+
200
+ export type Streamable = typeof(Streamable.new(workspace, "X"))
201
+
202
+ return Streamable
@@ -0,0 +1,80 @@
1
+ --!strict
2
+
3
+ -- StreamableUtil
4
+ -- Stephen Leitnick
5
+ -- March 03, 2021
6
+
7
+ local Trove = require(script.Parent.Parent.Trove)
8
+ local _Streamable = require(script.Parent.Streamable)
9
+
10
+ type Streamables = { _Streamable.Streamable }
11
+ type CompoundHandler = (Streamables, any) -> nil
12
+
13
+ --[=[
14
+ @class StreamableUtil
15
+ @client
16
+ A utility library for the Streamable class.
17
+
18
+ ```lua
19
+ local StreamableUtil = require(packages.Streamable).StreamableUtil
20
+ ```
21
+ ]=]
22
+ local StreamableUtil = {}
23
+
24
+ --[=[
25
+ @param streamables {Streamable}
26
+ @param handler ({[child: string]: Instance}, trove: Trove) -> nil
27
+ @return Trove
28
+
29
+ Creates a compound streamable around all the given streamables. The compound
30
+ streamable's observer handler will be fired once _all_ the given streamables
31
+ are in existence, and will be cleaned up when _any_ of the streamables
32
+ disappear.
33
+
34
+ ```lua
35
+ local s1 = Streamable.new(workspace, "Part1")
36
+ local s2 = Streamable.new(workspace, "Part2")
37
+
38
+ local compoundTrove = StreamableUtil.Compound({S1 = s1, S2 = s2}, function(streamables, trove)
39
+ local part1 = streamables.S1.Instance
40
+ local part2 = streamables.S2.Instance
41
+ trove:Add(function()
42
+ print("Cleanup")
43
+ end)
44
+ end)
45
+ ```
46
+ ]=]
47
+ function StreamableUtil.Compound(streamables: Streamables, handler: CompoundHandler)
48
+ local compoundTrove = Trove.new()
49
+ local observeAllTrove = Trove.new()
50
+ local allAvailable = false
51
+ local function Check()
52
+ if allAvailable then
53
+ return
54
+ end
55
+ for _, streamable in pairs(streamables) do
56
+ if not streamable.Instance then
57
+ return
58
+ end
59
+ end
60
+ allAvailable = true
61
+ handler(streamables, observeAllTrove)
62
+ end
63
+ local function Cleanup()
64
+ if not allAvailable then
65
+ return
66
+ end
67
+ allAvailable = false
68
+ observeAllTrove:Clean()
69
+ end
70
+ for _, streamable in pairs(streamables) do
71
+ compoundTrove:Add(streamable:Observe(function(_child, trove)
72
+ Check()
73
+ trove:Add(Cleanup)
74
+ end))
75
+ end
76
+ compoundTrove:Add(Cleanup)
77
+ return compoundTrove
78
+ end
79
+
80
+ return StreamableUtil
@@ -0,0 +1,8 @@
1
+ -- Streamable
2
+ -- Stephen Leitnick
3
+ -- November 08, 2021
4
+
5
+ return {
6
+ Streamable = require(script.Streamable),
7
+ StreamableUtil = require(script.StreamableUtil),
8
+ }
@@ -0,0 +1,12 @@
1
+ [package]
2
+ name = "sleitnick/streamable"
3
+ description = "Streamable class and StreamableUtil"
4
+ version = "1.2.4"
5
+ license = "MIT"
6
+ authors = ["Stephen Leitnick"]
7
+ registry = "https://github.com/UpliftGames/wally-index"
8
+ realm = "shared"
9
+
10
+ [dependencies]
11
+ Trove = "sleitnick/trove@^0.4"
12
+ Signal = "sleitnick/signal@^1"
@@ -0,0 +1,56 @@
1
+ -- Symbol
2
+ -- Stephen Leitnick
3
+ -- January 04, 2022
4
+
5
+ --[=[
6
+ @class Symbol
7
+
8
+ Represents a unique object.
9
+
10
+ Symbols are often used as unique keys in tables. This is useful to avoid possible collisions
11
+ with a key in a table, since the symbol will always be unique and cannot be reconstructed.
12
+
13
+
14
+ :::note All Unique
15
+ Every creation of a symbol is unique, even if the
16
+ given names are the same.
17
+ :::
18
+
19
+ ```lua
20
+ local Symbol = require(packages.Symbol)
21
+
22
+ -- Create a symbol:
23
+ local symbol = Symbol("MySymbol")
24
+
25
+ -- The name is optional:
26
+ local anotherSymbol = Symbol()
27
+
28
+ -- Comparison:
29
+ print(symbol == symbol) --> true
30
+
31
+ -- All symbol constructions are unique, regardless of the name:
32
+ print(Symbol("Hello") == Symbol("Hello")) --> false
33
+
34
+ -- Commonly used as unique keys in a table:
35
+ local DATA_KEY = Symbol("Data")
36
+ local t = {
37
+ -- Can only be accessed using the DATA_KEY symbol:
38
+ [DATA_KEY] = {}
39
+ }
40
+
41
+ print(t[DATA_KEY]) --> {}
42
+ ```
43
+ ]=]
44
+
45
+ local function Symbol(name: string?)
46
+ local symbol = newproxy(true)
47
+ if not name then
48
+ name = ""
49
+ end
50
+ getmetatable(symbol).__tostring = function()
51
+ return "Symbol(" .. name .. ")"
52
+ end
53
+ return symbol
54
+ end
55
+
56
+ return Symbol
@@ -0,0 +1,37 @@
1
+ local ServerScriptService = game:GetService("ServerScriptService")
2
+
3
+ local Test = require(ServerScriptService.TestRunner.Test)
4
+
5
+ return function(ctx: Test.TestContext)
6
+ local Symbol = require(script.Parent)
7
+
8
+ ctx:Describe("Constructor", function()
9
+ ctx:Test("should create a new symbol", function()
10
+ local symbol = Symbol("Test")
11
+ ctx:Expect(symbol):ToBeA("userdata")
12
+ ctx:Expect(symbol == symbol):ToBe(true)
13
+ ctx:Expect(tostring(symbol)):ToBe("Symbol(Test)")
14
+ end)
15
+
16
+ ctx:Test("should create a new symbol with no name", function()
17
+ local symbol = Symbol()
18
+ ctx:Expect(symbol):ToBeA("userdata")
19
+ ctx:Expect(symbol == symbol):ToBe(true)
20
+ ctx:Expect(tostring(symbol)):ToBe("Symbol()")
21
+ end)
22
+
23
+ ctx:Test("should be unique regardless of the name", function()
24
+ ctx:Expect(Symbol("Test") == Symbol("Test")):ToBe(false)
25
+ ctx:Expect(Symbol() == Symbol()):ToBe(false)
26
+ ctx:Expect(Symbol("Test") == Symbol()):ToBe(false)
27
+ ctx:Expect(Symbol("Test1") == Symbol("Test2")):ToBe(false)
28
+ end)
29
+
30
+ ctx:Test("should be useable as a table key", function()
31
+ local symbol = Symbol()
32
+ local t = {}
33
+ t[symbol] = 100
34
+ ctx:Expect(t[symbol]):ToBe(100)
35
+ end)
36
+ end)
37
+ end
@@ -0,0 +1,8 @@
1
+ [package]
2
+ name = "sleitnick/symbol"
3
+ description = "Symbol"
4
+ version = "2.0.1"
5
+ license = "MIT"
6
+ authors = ["Stephen Leitnick"]
7
+ registry = "https://github.com/UpliftGames/wally-index"
8
+ realm = "shared"