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.
Files changed (246) hide show
  1. package/README.md +112 -122
  2. package/commands/setup-game.md +108 -108
  3. package/commands/sync-check.md +53 -53
  4. package/core/roblox-core.md +93 -93
  5. package/dist/server.js +189 -167
  6. package/package.json +35 -35
  7. package/skills/roblox-analytics/SKILL.md +277 -277
  8. package/skills/roblox-analytics/references/event-batcher.luau +75 -75
  9. package/skills/roblox-animation-vfx/SKILL.md +1325 -1325
  10. package/skills/roblox-architecture/SKILL.md +877 -863
  11. package/skills/roblox-architecture/references/combat-systems.md +1381 -1381
  12. package/skills/roblox-code-review/SKILL.md +686 -686
  13. package/skills/roblox-data/SKILL.md +889 -889
  14. package/skills/roblox-data/references/inventory-systems.md +1729 -1729
  15. package/skills/roblox-debug/SKILL.md +98 -98
  16. package/skills/roblox-gui/SKILL.md +1103 -1103
  17. package/skills/roblox-gui-fusion/SKILL.md +150 -150
  18. package/skills/roblox-gui-fusion/references/inventory.luau +427 -427
  19. package/skills/roblox-gui-fusion/references/settings-menu.luau +579 -579
  20. package/skills/roblox-gui-fusion/references/shop.luau +411 -411
  21. package/skills/roblox-luau-mastery/SKILL.md +1618 -1519
  22. package/skills/roblox-monetization/SKILL.md +1084 -1084
  23. package/skills/roblox-monetization/references/process-receipt.luau +131 -131
  24. package/skills/roblox-networking/SKILL.md +669 -669
  25. package/skills/roblox-networking/references/remote-validator.luau +193 -193
  26. package/skills/roblox-publish-checklist/SKILL.md +127 -127
  27. package/skills/roblox-runtime/SKILL.md +753 -753
  28. package/skills/roblox-sharp-edges/SKILL.md +294 -294
  29. package/skills/roblox-sync/SKILL.md +126 -126
  30. package/skills/roblox-testing/SKILL.md +943 -943
  31. package/skills/roblox-tooling/SKILL.md +149 -149
  32. package/vendor/LICENSES/ProfileStore-LICENSE +201 -201
  33. package/vendor/LICENSES/RbxUtil-LICENSE +7 -7
  34. package/vendor/LICENSES/promise-LICENSE +20 -20
  35. package/vendor/LICENSES/t-LICENSE +21 -21
  36. package/vendor/LICENSES/testez-LICENSE +200 -200
  37. package/vendor/README.md +83 -83
  38. package/vendor/fusion/Animation/ExternalTime.luau +83 -83
  39. package/vendor/fusion/Animation/Spring.luau +321 -321
  40. package/vendor/fusion/Animation/Stopwatch.luau +127 -127
  41. package/vendor/fusion/Animation/Tween.luau +187 -187
  42. package/vendor/fusion/Animation/getTweenDuration.luau +27 -27
  43. package/vendor/fusion/Animation/getTweenRatio.luau +47 -47
  44. package/vendor/fusion/Animation/lerpType.luau +163 -163
  45. package/vendor/fusion/Animation/packType.luau +99 -99
  46. package/vendor/fusion/Animation/springCoefficients.luau +80 -80
  47. package/vendor/fusion/Animation/unpackType.luau +102 -102
  48. package/vendor/fusion/Colour/Oklab.luau +70 -70
  49. package/vendor/fusion/Colour/sRGB.luau +54 -54
  50. package/vendor/fusion/External.luau +167 -167
  51. package/vendor/fusion/ExternalDebug.luau +69 -69
  52. package/vendor/fusion/Graph/Observer.luau +113 -113
  53. package/vendor/fusion/Graph/castToGraph.luau +28 -28
  54. package/vendor/fusion/Graph/change.luau +80 -80
  55. package/vendor/fusion/Graph/depend.luau +32 -32
  56. package/vendor/fusion/Graph/evaluate.luau +55 -55
  57. package/vendor/fusion/Instances/Attribute.luau +57 -57
  58. package/vendor/fusion/Instances/AttributeChange.luau +46 -46
  59. package/vendor/fusion/Instances/AttributeOut.luau +63 -63
  60. package/vendor/fusion/Instances/Child.luau +21 -21
  61. package/vendor/fusion/Instances/Children.luau +147 -147
  62. package/vendor/fusion/Instances/Hydrate.luau +32 -32
  63. package/vendor/fusion/Instances/New.luau +52 -52
  64. package/vendor/fusion/Instances/OnChange.luau +49 -49
  65. package/vendor/fusion/Instances/OnEvent.luau +53 -53
  66. package/vendor/fusion/Instances/Out.luau +69 -69
  67. package/vendor/fusion/Instances/applyInstanceProps.luau +148 -148
  68. package/vendor/fusion/Instances/defaultProps.luau +194 -194
  69. package/vendor/fusion/LICENSE +21 -21
  70. package/vendor/fusion/Logging/formatError.luau +48 -48
  71. package/vendor/fusion/Logging/messages.luau +51 -51
  72. package/vendor/fusion/Logging/parseError.luau +24 -24
  73. package/vendor/fusion/Memory/checkLifetime.luau +133 -133
  74. package/vendor/fusion/Memory/deriveScope.luau +23 -23
  75. package/vendor/fusion/Memory/deriveScopeImpl.luau +44 -44
  76. package/vendor/fusion/Memory/doCleanup.luau +78 -78
  77. package/vendor/fusion/Memory/innerScope.luau +33 -33
  78. package/vendor/fusion/Memory/legacyCleanup.luau +17 -17
  79. package/vendor/fusion/Memory/needsDestruction.luau +16 -16
  80. package/vendor/fusion/Memory/poisonScope.luau +33 -33
  81. package/vendor/fusion/Memory/scopePool.luau +54 -54
  82. package/vendor/fusion/Memory/scoped.luau +26 -26
  83. package/vendor/fusion/Memory/whichLivesLonger.luau +74 -74
  84. package/vendor/fusion/RobloxExternal.luau +97 -97
  85. package/vendor/fusion/State/Computed.luau +138 -138
  86. package/vendor/fusion/State/For/Disassembly.luau +210 -210
  87. package/vendor/fusion/State/For/ForTypes.luau +30 -30
  88. package/vendor/fusion/State/For/init.luau +109 -109
  89. package/vendor/fusion/State/ForKeys.luau +93 -93
  90. package/vendor/fusion/State/ForPairs.luau +96 -96
  91. package/vendor/fusion/State/ForValues.luau +93 -93
  92. package/vendor/fusion/State/Value.luau +87 -87
  93. package/vendor/fusion/State/castToState.luau +25 -25
  94. package/vendor/fusion/State/peek.luau +30 -30
  95. package/vendor/fusion/Types.luau +314 -314
  96. package/vendor/fusion/Utility/Contextual.luau +90 -90
  97. package/vendor/fusion/Utility/Safe.luau +22 -22
  98. package/vendor/fusion/Utility/isSimilar.luau +29 -29
  99. package/vendor/fusion/Utility/merge.luau +35 -35
  100. package/vendor/fusion/Utility/nameOf.luau +34 -34
  101. package/vendor/fusion/Utility/never.luau +13 -13
  102. package/vendor/fusion/Utility/nicknames.luau +10 -10
  103. package/vendor/fusion/Utility/xtypeof.luau +26 -26
  104. package/vendor/fusion/init.luau +82 -82
  105. package/vendor/profilestore/init.luau +2242 -2242
  106. package/vendor/promise/init.luau +1982 -1982
  107. package/vendor/rbxutil/buffer-util/Buffer.test.luau +25 -25
  108. package/vendor/rbxutil/buffer-util/BufferReader.luau +228 -228
  109. package/vendor/rbxutil/buffer-util/BufferWriter.luau +269 -269
  110. package/vendor/rbxutil/buffer-util/DataTypeBuffer.luau +223 -223
  111. package/vendor/rbxutil/buffer-util/Types.luau +60 -60
  112. package/vendor/rbxutil/buffer-util/index.d.ts +153 -153
  113. package/vendor/rbxutil/buffer-util/init.luau +41 -41
  114. package/vendor/rbxutil/buffer-util/package.json +16 -16
  115. package/vendor/rbxutil/buffer-util/wally.toml +9 -9
  116. package/vendor/rbxutil/comm/Client/ClientComm.luau +232 -232
  117. package/vendor/rbxutil/comm/Client/ClientRemoteProperty.luau +156 -156
  118. package/vendor/rbxutil/comm/Client/ClientRemoteSignal.luau +109 -109
  119. package/vendor/rbxutil/comm/Client/init.luau +135 -135
  120. package/vendor/rbxutil/comm/Server/RemoteProperty.luau +295 -295
  121. package/vendor/rbxutil/comm/Server/RemoteSignal.luau +211 -211
  122. package/vendor/rbxutil/comm/Server/ServerComm.luau +211 -211
  123. package/vendor/rbxutil/comm/Server/init.luau +140 -140
  124. package/vendor/rbxutil/comm/Types.luau +18 -18
  125. package/vendor/rbxutil/comm/Util.luau +27 -27
  126. package/vendor/rbxutil/comm/init.luau +35 -35
  127. package/vendor/rbxutil/comm/wally.toml +13 -13
  128. package/vendor/rbxutil/component/init.luau +759 -759
  129. package/vendor/rbxutil/component/init.test.luau +311 -311
  130. package/vendor/rbxutil/component/wally.toml +14 -14
  131. package/vendor/rbxutil/concur/init.luau +542 -542
  132. package/vendor/rbxutil/concur/init.test.luau +364 -364
  133. package/vendor/rbxutil/concur/wally.toml +8 -8
  134. package/vendor/rbxutil/enum-list/init.luau +101 -101
  135. package/vendor/rbxutil/enum-list/init.test.luau +91 -91
  136. package/vendor/rbxutil/enum-list/wally.toml +8 -8
  137. package/vendor/rbxutil/find/index.d.ts +20 -20
  138. package/vendor/rbxutil/find/init.luau +44 -44
  139. package/vendor/rbxutil/find/package.json +17 -17
  140. package/vendor/rbxutil/find/wally.toml +8 -8
  141. package/vendor/rbxutil/input/Gamepad.luau +559 -559
  142. package/vendor/rbxutil/input/Keyboard.luau +124 -124
  143. package/vendor/rbxutil/input/Mouse.luau +278 -278
  144. package/vendor/rbxutil/input/PreferredInput.luau +91 -91
  145. package/vendor/rbxutil/input/Touch.luau +120 -120
  146. package/vendor/rbxutil/input/init.luau +33 -33
  147. package/vendor/rbxutil/input/wally.toml +12 -12
  148. package/vendor/rbxutil/loader/index.d.ts +15 -15
  149. package/vendor/rbxutil/loader/init.luau +137 -137
  150. package/vendor/rbxutil/loader/wally.toml +8 -8
  151. package/vendor/rbxutil/log/index.d.ts +38 -38
  152. package/vendor/rbxutil/log/init.luau +746 -746
  153. package/vendor/rbxutil/log/wally.toml +8 -8
  154. package/vendor/rbxutil/net/init.luau +190 -190
  155. package/vendor/rbxutil/net/wally.toml +8 -8
  156. package/vendor/rbxutil/option/index.d.ts +44 -44
  157. package/vendor/rbxutil/option/init.luau +489 -489
  158. package/vendor/rbxutil/option/init.test.luau +342 -342
  159. package/vendor/rbxutil/option/wally.toml +8 -8
  160. package/vendor/rbxutil/pid/index.d.ts +53 -53
  161. package/vendor/rbxutil/pid/init.luau +195 -195
  162. package/vendor/rbxutil/pid/package.json +16 -16
  163. package/vendor/rbxutil/pid/wally.toml +9 -9
  164. package/vendor/rbxutil/quaternion/index.d.ts +117 -117
  165. package/vendor/rbxutil/quaternion/init.luau +570 -570
  166. package/vendor/rbxutil/quaternion/package.json +16 -16
  167. package/vendor/rbxutil/quaternion/wally.toml +9 -9
  168. package/vendor/rbxutil/query/index.d.ts +43 -43
  169. package/vendor/rbxutil/query/init.luau +117 -117
  170. package/vendor/rbxutil/query/package.json +18 -18
  171. package/vendor/rbxutil/query/wally.toml +9 -9
  172. package/vendor/rbxutil/sequent/index.d.ts +28 -28
  173. package/vendor/rbxutil/sequent/init.luau +340 -340
  174. package/vendor/rbxutil/sequent/package.json +16 -16
  175. package/vendor/rbxutil/sequent/wally.toml +9 -9
  176. package/vendor/rbxutil/ser/init.luau +175 -175
  177. package/vendor/rbxutil/ser/init.test.luau +50 -50
  178. package/vendor/rbxutil/ser/wally.toml +11 -11
  179. package/vendor/rbxutil/shake/index.d.ts +36 -36
  180. package/vendor/rbxutil/shake/init.luau +532 -532
  181. package/vendor/rbxutil/shake/init.test.luau +267 -267
  182. package/vendor/rbxutil/shake/package.json +16 -16
  183. package/vendor/rbxutil/shake/wally.toml +9 -9
  184. package/vendor/rbxutil/signal/index.d.ts +100 -100
  185. package/vendor/rbxutil/signal/init.luau +432 -432
  186. package/vendor/rbxutil/signal/init.test.luau +190 -190
  187. package/vendor/rbxutil/signal/package.json +17 -17
  188. package/vendor/rbxutil/signal/wally.toml +9 -9
  189. package/vendor/rbxutil/silo/TableWatcher.luau +65 -65
  190. package/vendor/rbxutil/silo/Util.luau +55 -55
  191. package/vendor/rbxutil/silo/init.luau +338 -338
  192. package/vendor/rbxutil/silo/init.test.luau +215 -215
  193. package/vendor/rbxutil/silo/wally.toml +8 -8
  194. package/vendor/rbxutil/spring/index.d.ts +40 -40
  195. package/vendor/rbxutil/spring/init.luau +97 -97
  196. package/vendor/rbxutil/spring/package.json +17 -17
  197. package/vendor/rbxutil/spring/wally.toml +8 -8
  198. package/vendor/rbxutil/stream/index.d.ts +88 -88
  199. package/vendor/rbxutil/stream/init.luau +597 -597
  200. package/vendor/rbxutil/stream/package.json +18 -18
  201. package/vendor/rbxutil/stream/wally.toml +9 -9
  202. package/vendor/rbxutil/streamable/Streamable.luau +202 -202
  203. package/vendor/rbxutil/streamable/StreamableUtil.luau +80 -80
  204. package/vendor/rbxutil/streamable/init.luau +8 -8
  205. package/vendor/rbxutil/streamable/wally.toml +12 -12
  206. package/vendor/rbxutil/symbol/init.luau +56 -56
  207. package/vendor/rbxutil/symbol/init.test.luau +37 -37
  208. package/vendor/rbxutil/symbol/wally.toml +8 -8
  209. package/vendor/rbxutil/table-util/init.luau +938 -938
  210. package/vendor/rbxutil/table-util/init.test.luau +439 -439
  211. package/vendor/rbxutil/task-queue/index.d.ts +27 -27
  212. package/vendor/rbxutil/task-queue/init.luau +97 -97
  213. package/vendor/rbxutil/task-queue/wally.toml +8 -8
  214. package/vendor/rbxutil/timer/index.d.ts +81 -81
  215. package/vendor/rbxutil/timer/init.luau +249 -249
  216. package/vendor/rbxutil/timer/init.test.luau +73 -73
  217. package/vendor/rbxutil/timer/wally.toml +11 -11
  218. package/vendor/rbxutil/tree/index.d.ts +15 -15
  219. package/vendor/rbxutil/tree/init.luau +137 -137
  220. package/vendor/rbxutil/tree/wally.toml +8 -8
  221. package/vendor/rbxutil/trove/index.d.ts +46 -46
  222. package/vendor/rbxutil/trove/init.luau +787 -787
  223. package/vendor/rbxutil/trove/init.test.luau +203 -203
  224. package/vendor/rbxutil/trove/wally.toml +8 -8
  225. package/vendor/rbxutil/typed-remote/init.luau +196 -196
  226. package/vendor/rbxutil/typed-remote/wally.toml +8 -8
  227. package/vendor/rbxutil/wait-for/index.d.ts +17 -17
  228. package/vendor/rbxutil/wait-for/init.luau +257 -257
  229. package/vendor/rbxutil/wait-for/init.test.luau +182 -182
  230. package/vendor/rbxutil/wait-for/wally.toml +11 -11
  231. package/vendor/t/t.lua +1350 -1350
  232. package/vendor/testez/Context.lua +26 -26
  233. package/vendor/testez/Expectation.lua +311 -311
  234. package/vendor/testez/ExpectationContext.lua +38 -38
  235. package/vendor/testez/LifecycleHooks.lua +89 -89
  236. package/vendor/testez/Reporters/TeamCityReporter.lua +101 -101
  237. package/vendor/testez/Reporters/TextReporter.lua +105 -105
  238. package/vendor/testez/Reporters/TextReporterQuiet.lua +96 -96
  239. package/vendor/testez/TestBootstrap.lua +146 -146
  240. package/vendor/testez/TestEnum.lua +27 -27
  241. package/vendor/testez/TestPlan.lua +304 -304
  242. package/vendor/testez/TestPlanner.lua +39 -39
  243. package/vendor/testez/TestResults.lua +111 -111
  244. package/vendor/testez/TestRunner.lua +188 -188
  245. package/vendor/testez/TestSession.lua +243 -243
  246. package/vendor/testez/init.lua +39 -39
@@ -1,18 +1,18 @@
1
- {
2
- "name": "@rbxutil/stream",
3
- "version": "0.1.1",
4
- "main": "init.luau",
5
- "repository": {
6
- "url": "git+https://github.com/Sleitnick/RbxUtil.git"
7
- },
8
- "license": "MIT",
9
- "types": "index.d.ts",
10
- "files": [
11
- "./*",
12
- "!*.toml",
13
- "!*.json"
14
- ],
15
- "publishConfig": {
16
- "access": "public"
17
- }
18
- }
1
+ {
2
+ "name": "@rbxutil/stream",
3
+ "version": "0.1.1",
4
+ "main": "init.luau",
5
+ "repository": {
6
+ "url": "git+https://github.com/Sleitnick/RbxUtil.git"
7
+ },
8
+ "license": "MIT",
9
+ "types": "index.d.ts",
10
+ "files": [
11
+ "./*",
12
+ "!*.toml",
13
+ "!*.json"
14
+ ],
15
+ "publishConfig": {
16
+ "access": "public"
17
+ }
18
+ }
@@ -1,9 +1,9 @@
1
- [package]
2
- name = "sleitnick/stream"
3
- description = "Stream abstraction wrapper around buffers"
4
- version = "0.1.1"
5
- license = "MIT"
6
- authors = ["Stephen Leitnick"]
7
- registry = "https://github.com/UpliftGames/wally-index"
8
- realm = "shared"
9
- exclude = ["node_modules", "package.json", "**/*.ts"]
1
+ [package]
2
+ name = "sleitnick/stream"
3
+ description = "Stream abstraction wrapper around buffers"
4
+ version = "0.1.1"
5
+ license = "MIT"
6
+ authors = ["Stephen Leitnick"]
7
+ registry = "https://github.com/UpliftGames/wally-index"
8
+ realm = "shared"
9
+ exclude = ["node_modules", "package.json", "**/*.ts"]
@@ -1,202 +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
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
@@ -1,80 +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
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
@@ -1,8 +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
- }
1
+ -- Streamable
2
+ -- Stephen Leitnick
3
+ -- November 08, 2021
4
+
5
+ return {
6
+ Streamable = require(script.Streamable),
7
+ StreamableUtil = require(script.StreamableUtil),
8
+ }
@@ -1,12 +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"
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"