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,249 +1,249 @@
1
- --!strict
2
-
3
- local RunService = game:GetService("RunService")
4
-
5
- local Signal = require(script.Parent.Signal)
6
-
7
- --[=[
8
- @within Timer
9
- @type CallbackFn () -> ()
10
- Callback function.
11
- ]=]
12
- type CallbackFn = () -> nil
13
-
14
- --[=[
15
- @within Timer
16
- @type TimeFn () -> number
17
- Time function.
18
- ]=]
19
- type TimeFn = () -> number
20
-
21
- --[=[
22
- @class Timer
23
-
24
- The Timer class allows for code to run periodically at specified intervals.
25
-
26
- ```lua
27
- local timer = Timer.new(2)
28
- timer.Tick:Connect(function()
29
- print("Tock")
30
- end)
31
- timer:Start()
32
- ```
33
- ]=]
34
- local Timer = {}
35
- Timer.__index = Timer
36
-
37
- export type Timer = typeof(setmetatable(
38
- {} :: {
39
- Interval: number,
40
- UpdateSignal: RBXScriptSignal,
41
- TimeFunction: () -> number,
42
- AllowDrift: boolean,
43
- Tick: Signal.Signal<>,
44
-
45
- _runHandle: RBXScriptConnection?,
46
- },
47
- Timer
48
- ))
49
-
50
- --[=[
51
- @within Timer
52
- @prop Interval number
53
- Interval at which the `Tick` event fires.
54
- ]=]
55
- --[=[
56
- @within Timer
57
- @prop UpdateSignal RBXScriptSignal | Signal
58
- The signal which updates the timer internally.
59
- ]=]
60
- --[=[
61
- @within Timer
62
- @prop TimeFunction TimeFn
63
- The function which gets the current time.
64
- ]=]
65
- --[=[
66
- @within Timer
67
- @prop AllowDrift boolean
68
- Flag which indicates if the timer is allowed to drift. This
69
- is set to `true` by default. This flag must be set before
70
- calling `Start` or `StartNow`. This flag should only be set
71
- to `false` if it is necessary for drift to be eliminated.
72
- ]=]
73
- --[=[
74
- @within Timer
75
- @prop Tick RBXScriptSignal | Signal
76
- The event which is fired every time the timer hits its interval.
77
- ]=]
78
-
79
- --[=[
80
- @return Timer
81
-
82
- Creates a new timer.
83
- ]=]
84
- function Timer.new(interval: number): Timer
85
- assert(type(interval) == "number", "argument #1 to Timer.new must be a number; got " .. type(interval))
86
- assert(interval >= 0, "argument #1 to Timer.new must be greater or equal to 0; got " .. tostring(interval))
87
-
88
- local self = setmetatable({}, Timer)
89
-
90
- self._runHandle = nil
91
- self.Interval = interval
92
- self.UpdateSignal = RunService.Heartbeat
93
- self.TimeFunction = time
94
- self.AllowDrift = true
95
- self.Tick = Signal.new()
96
-
97
- return self
98
- end
99
-
100
- --[=[
101
- @return RBXScriptConnection
102
-
103
- Creates a simplified timer which just fires off a callback function at the given interval.
104
-
105
- ```lua
106
- -- Basic:
107
- Timer.simple(1, function()
108
- print("Tick")
109
- end)
110
-
111
- -- Using other arguments:
112
- Timer.simple(1, function()
113
- print("Tick")
114
- end, true, RunService.Heartbeat, os.clock)
115
- ```
116
- ]=]
117
- function Timer.simple(
118
- interval: number,
119
- callback: CallbackFn,
120
- startNow: boolean?,
121
- updateSignal: RBXScriptSignal?,
122
- timeFn: TimeFn?
123
- )
124
- local update = updateSignal or RunService.Heartbeat
125
- local t = timeFn or time
126
- local nextTick = t() + interval
127
-
128
- if startNow then
129
- task.defer(callback)
130
- end
131
-
132
- return update:Connect(function()
133
- local now = t()
134
- if now >= nextTick then
135
- nextTick = now + interval
136
- task.defer(callback)
137
- end
138
- end)
139
- end
140
-
141
- --[=[
142
- Returns `true` if the given object is a Timer.
143
- ]=]
144
- function Timer.is(obj: any): boolean
145
- return type(obj) == "table" and getmetatable(obj) == Timer
146
- end
147
-
148
- function Timer._startTimer(self: Timer)
149
- local t = self.TimeFunction
150
- local nextTick = t() + self.Interval
151
-
152
- self._runHandle = self.UpdateSignal:Connect(function()
153
- local now = t()
154
- if now >= nextTick then
155
- nextTick = now + self.Interval
156
- self.Tick:Fire()
157
- end
158
- end)
159
- end
160
-
161
- function Timer._startTimerNoDrift(self: Timer)
162
- assert(self.Interval > 0, "interval must be greater than 0 when AllowDrift is set to false")
163
-
164
- local t = self.TimeFunction
165
- local n = 1
166
- local start = t()
167
- local nextTick = start + self.Interval
168
- self._runHandle = self.UpdateSignal:Connect(function()
169
- local now = t()
170
- while now >= nextTick do
171
- n += 1
172
- nextTick = start + (self.Interval * n)
173
- self.Tick:Fire()
174
- end
175
- end)
176
- end
177
-
178
- --[=[
179
- Starts the timer. Will do nothing if the timer is already running.
180
-
181
- ```lua
182
- timer:Start()
183
- ```
184
- ]=]
185
- function Timer.Start(self: Timer)
186
- if self._runHandle then
187
- return
188
- end
189
- if self.AllowDrift then
190
- self:_startTimer()
191
- else
192
- self:_startTimerNoDrift()
193
- end
194
- end
195
-
196
- --[=[
197
- Starts the timer and fires off the Tick event immediately. Will do
198
- nothing if the timer is already running.
199
-
200
- ```lua
201
- timer:StartNow()
202
- ```
203
- ]=]
204
- function Timer.StartNow(self: Timer)
205
- if self._runHandle then
206
- return
207
- end
208
- self.Tick:Fire()
209
- self:Start()
210
- end
211
-
212
- --[=[
213
- Stops the timer. Will do nothing if the timer is already stopped.
214
-
215
- ```lua
216
- timer:Stop()
217
- ```
218
- ]=]
219
- function Timer.Stop(self: Timer)
220
- if not self._runHandle then
221
- return
222
- end
223
-
224
- self._runHandle:Disconnect()
225
- self._runHandle = nil
226
- end
227
-
228
- --[=[
229
- Returns `true` if the timer is currently running.
230
-
231
- ```lua
232
- if timer:IsRunning() then
233
- -- Do something
234
- end
235
- ```
236
- ]=]
237
- function Timer.IsRunning(self: Timer): boolean
238
- return self._runHandle ~= nil
239
- end
240
-
241
- --[=[
242
- Destroys the timer. This will also stop the timer.
243
- ]=]
244
- function Timer.Destroy(self: Timer)
245
- self.Tick:Destroy()
246
- self:Stop()
247
- end
248
-
249
- return Timer
1
+ --!strict
2
+
3
+ local RunService = game:GetService("RunService")
4
+
5
+ local Signal = require(script.Parent.Signal)
6
+
7
+ --[=[
8
+ @within Timer
9
+ @type CallbackFn () -> ()
10
+ Callback function.
11
+ ]=]
12
+ type CallbackFn = () -> nil
13
+
14
+ --[=[
15
+ @within Timer
16
+ @type TimeFn () -> number
17
+ Time function.
18
+ ]=]
19
+ type TimeFn = () -> number
20
+
21
+ --[=[
22
+ @class Timer
23
+
24
+ The Timer class allows for code to run periodically at specified intervals.
25
+
26
+ ```lua
27
+ local timer = Timer.new(2)
28
+ timer.Tick:Connect(function()
29
+ print("Tock")
30
+ end)
31
+ timer:Start()
32
+ ```
33
+ ]=]
34
+ local Timer = {}
35
+ Timer.__index = Timer
36
+
37
+ export type Timer = typeof(setmetatable(
38
+ {} :: {
39
+ Interval: number,
40
+ UpdateSignal: RBXScriptSignal,
41
+ TimeFunction: () -> number,
42
+ AllowDrift: boolean,
43
+ Tick: Signal.Signal<>,
44
+
45
+ _runHandle: RBXScriptConnection?,
46
+ },
47
+ Timer
48
+ ))
49
+
50
+ --[=[
51
+ @within Timer
52
+ @prop Interval number
53
+ Interval at which the `Tick` event fires.
54
+ ]=]
55
+ --[=[
56
+ @within Timer
57
+ @prop UpdateSignal RBXScriptSignal | Signal
58
+ The signal which updates the timer internally.
59
+ ]=]
60
+ --[=[
61
+ @within Timer
62
+ @prop TimeFunction TimeFn
63
+ The function which gets the current time.
64
+ ]=]
65
+ --[=[
66
+ @within Timer
67
+ @prop AllowDrift boolean
68
+ Flag which indicates if the timer is allowed to drift. This
69
+ is set to `true` by default. This flag must be set before
70
+ calling `Start` or `StartNow`. This flag should only be set
71
+ to `false` if it is necessary for drift to be eliminated.
72
+ ]=]
73
+ --[=[
74
+ @within Timer
75
+ @prop Tick RBXScriptSignal | Signal
76
+ The event which is fired every time the timer hits its interval.
77
+ ]=]
78
+
79
+ --[=[
80
+ @return Timer
81
+
82
+ Creates a new timer.
83
+ ]=]
84
+ function Timer.new(interval: number): Timer
85
+ assert(type(interval) == "number", "argument #1 to Timer.new must be a number; got " .. type(interval))
86
+ assert(interval >= 0, "argument #1 to Timer.new must be greater or equal to 0; got " .. tostring(interval))
87
+
88
+ local self = setmetatable({}, Timer)
89
+
90
+ self._runHandle = nil
91
+ self.Interval = interval
92
+ self.UpdateSignal = RunService.Heartbeat
93
+ self.TimeFunction = time
94
+ self.AllowDrift = true
95
+ self.Tick = Signal.new()
96
+
97
+ return self
98
+ end
99
+
100
+ --[=[
101
+ @return RBXScriptConnection
102
+
103
+ Creates a simplified timer which just fires off a callback function at the given interval.
104
+
105
+ ```lua
106
+ -- Basic:
107
+ Timer.simple(1, function()
108
+ print("Tick")
109
+ end)
110
+
111
+ -- Using other arguments:
112
+ Timer.simple(1, function()
113
+ print("Tick")
114
+ end, true, RunService.Heartbeat, os.clock)
115
+ ```
116
+ ]=]
117
+ function Timer.simple(
118
+ interval: number,
119
+ callback: CallbackFn,
120
+ startNow: boolean?,
121
+ updateSignal: RBXScriptSignal?,
122
+ timeFn: TimeFn?
123
+ )
124
+ local update = updateSignal or RunService.Heartbeat
125
+ local t = timeFn or time
126
+ local nextTick = t() + interval
127
+
128
+ if startNow then
129
+ task.defer(callback)
130
+ end
131
+
132
+ return update:Connect(function()
133
+ local now = t()
134
+ if now >= nextTick then
135
+ nextTick = now + interval
136
+ task.defer(callback)
137
+ end
138
+ end)
139
+ end
140
+
141
+ --[=[
142
+ Returns `true` if the given object is a Timer.
143
+ ]=]
144
+ function Timer.is(obj: any): boolean
145
+ return type(obj) == "table" and getmetatable(obj) == Timer
146
+ end
147
+
148
+ function Timer._startTimer(self: Timer)
149
+ local t = self.TimeFunction
150
+ local nextTick = t() + self.Interval
151
+
152
+ self._runHandle = self.UpdateSignal:Connect(function()
153
+ local now = t()
154
+ if now >= nextTick then
155
+ nextTick = now + self.Interval
156
+ self.Tick:Fire()
157
+ end
158
+ end)
159
+ end
160
+
161
+ function Timer._startTimerNoDrift(self: Timer)
162
+ assert(self.Interval > 0, "interval must be greater than 0 when AllowDrift is set to false")
163
+
164
+ local t = self.TimeFunction
165
+ local n = 1
166
+ local start = t()
167
+ local nextTick = start + self.Interval
168
+ self._runHandle = self.UpdateSignal:Connect(function()
169
+ local now = t()
170
+ while now >= nextTick do
171
+ n += 1
172
+ nextTick = start + (self.Interval * n)
173
+ self.Tick:Fire()
174
+ end
175
+ end)
176
+ end
177
+
178
+ --[=[
179
+ Starts the timer. Will do nothing if the timer is already running.
180
+
181
+ ```lua
182
+ timer:Start()
183
+ ```
184
+ ]=]
185
+ function Timer.Start(self: Timer)
186
+ if self._runHandle then
187
+ return
188
+ end
189
+ if self.AllowDrift then
190
+ self:_startTimer()
191
+ else
192
+ self:_startTimerNoDrift()
193
+ end
194
+ end
195
+
196
+ --[=[
197
+ Starts the timer and fires off the Tick event immediately. Will do
198
+ nothing if the timer is already running.
199
+
200
+ ```lua
201
+ timer:StartNow()
202
+ ```
203
+ ]=]
204
+ function Timer.StartNow(self: Timer)
205
+ if self._runHandle then
206
+ return
207
+ end
208
+ self.Tick:Fire()
209
+ self:Start()
210
+ end
211
+
212
+ --[=[
213
+ Stops the timer. Will do nothing if the timer is already stopped.
214
+
215
+ ```lua
216
+ timer:Stop()
217
+ ```
218
+ ]=]
219
+ function Timer.Stop(self: Timer)
220
+ if not self._runHandle then
221
+ return
222
+ end
223
+
224
+ self._runHandle:Disconnect()
225
+ self._runHandle = nil
226
+ end
227
+
228
+ --[=[
229
+ Returns `true` if the timer is currently running.
230
+
231
+ ```lua
232
+ if timer:IsRunning() then
233
+ -- Do something
234
+ end
235
+ ```
236
+ ]=]
237
+ function Timer.IsRunning(self: Timer): boolean
238
+ return self._runHandle ~= nil
239
+ end
240
+
241
+ --[=[
242
+ Destroys the timer. This will also stop the timer.
243
+ ]=]
244
+ function Timer.Destroy(self: Timer)
245
+ self.Tick:Destroy()
246
+ self:Stop()
247
+ end
248
+
249
+ return Timer
@@ -1,73 +1,73 @@
1
- local ServerScriptService = game:GetService("ServerScriptService")
2
-
3
- local Test = require(ServerScriptService.TestRunner.Test)
4
-
5
- return function(ctx: Test.TestContext)
6
- local Timer = require(script.Parent)
7
-
8
- ctx:Describe("Timer", function()
9
- local timer
10
-
11
- ctx:BeforeEach(function()
12
- timer = Timer.new(0.1)
13
- timer.TimeFunction = os.clock
14
- end)
15
-
16
- ctx:AfterEach(function()
17
- if timer then
18
- timer:Destroy()
19
- timer = nil
20
- end
21
- end)
22
-
23
- ctx:Test("should create a new timer", function()
24
- ctx:Expect(Timer.is(timer)):ToBe(true)
25
- end)
26
-
27
- ctx:Test("should tick appropriately", function()
28
- local start = os.clock()
29
- timer:Start()
30
- timer.Tick:Wait()
31
- local duration = (os.clock() - start)
32
- ctx:Expect(duration):ToBeNear(duration, 0.02)
33
- end)
34
-
35
- ctx:Test("should start immediately", function()
36
- local start = os.clock()
37
- local stop = nil
38
- timer.Tick:Connect(function()
39
- if not stop then
40
- stop = os.clock()
41
- end
42
- end)
43
- timer:StartNow()
44
- timer.Tick:Wait()
45
- ctx:Expect(stop):ToBeA("number")
46
- local duration = (stop - start)
47
- ctx:Expect(duration):ToBeNear(0, 0.02)
48
- end)
49
-
50
- ctx:Test("should stop", function()
51
- local ticks = 0
52
- timer.Tick:Connect(function()
53
- ticks += 1
54
- end)
55
- timer:StartNow()
56
- timer:Stop()
57
- task.wait(1)
58
- ctx:Expect(ticks):ToBe(1)
59
- end)
60
-
61
- ctx:Test("should detect if running", function()
62
- ctx:Expect(timer:IsRunning()):ToBe(false)
63
- timer:Start()
64
- ctx:Expect(timer:IsRunning()):ToBe(true)
65
- timer:Stop()
66
- ctx:Expect(timer:IsRunning()):ToBe(false)
67
- timer:StartNow()
68
- ctx:Expect(timer:IsRunning()):ToBe(true)
69
- timer:Stop()
70
- ctx:Expect(timer:IsRunning()):ToBe(false)
71
- end)
72
- end)
73
- end
1
+ local ServerScriptService = game:GetService("ServerScriptService")
2
+
3
+ local Test = require(ServerScriptService.TestRunner.Test)
4
+
5
+ return function(ctx: Test.TestContext)
6
+ local Timer = require(script.Parent)
7
+
8
+ ctx:Describe("Timer", function()
9
+ local timer
10
+
11
+ ctx:BeforeEach(function()
12
+ timer = Timer.new(0.1)
13
+ timer.TimeFunction = os.clock
14
+ end)
15
+
16
+ ctx:AfterEach(function()
17
+ if timer then
18
+ timer:Destroy()
19
+ timer = nil
20
+ end
21
+ end)
22
+
23
+ ctx:Test("should create a new timer", function()
24
+ ctx:Expect(Timer.is(timer)):ToBe(true)
25
+ end)
26
+
27
+ ctx:Test("should tick appropriately", function()
28
+ local start = os.clock()
29
+ timer:Start()
30
+ timer.Tick:Wait()
31
+ local duration = (os.clock() - start)
32
+ ctx:Expect(duration):ToBeNear(duration, 0.02)
33
+ end)
34
+
35
+ ctx:Test("should start immediately", function()
36
+ local start = os.clock()
37
+ local stop = nil
38
+ timer.Tick:Connect(function()
39
+ if not stop then
40
+ stop = os.clock()
41
+ end
42
+ end)
43
+ timer:StartNow()
44
+ timer.Tick:Wait()
45
+ ctx:Expect(stop):ToBeA("number")
46
+ local duration = (stop - start)
47
+ ctx:Expect(duration):ToBeNear(0, 0.02)
48
+ end)
49
+
50
+ ctx:Test("should stop", function()
51
+ local ticks = 0
52
+ timer.Tick:Connect(function()
53
+ ticks += 1
54
+ end)
55
+ timer:StartNow()
56
+ timer:Stop()
57
+ task.wait(1)
58
+ ctx:Expect(ticks):ToBe(1)
59
+ end)
60
+
61
+ ctx:Test("should detect if running", function()
62
+ ctx:Expect(timer:IsRunning()):ToBe(false)
63
+ timer:Start()
64
+ ctx:Expect(timer:IsRunning()):ToBe(true)
65
+ timer:Stop()
66
+ ctx:Expect(timer:IsRunning()):ToBe(false)
67
+ timer:StartNow()
68
+ ctx:Expect(timer:IsRunning()):ToBe(true)
69
+ timer:Stop()
70
+ ctx:Expect(timer:IsRunning()):ToBe(false)
71
+ end)
72
+ end)
73
+ end
@@ -1,11 +1,11 @@
1
- [package]
2
- name = "sleitnick/timer"
3
- description = "Timer class"
4
- version = "2.0.0"
5
- license = "MIT"
6
- authors = ["Stephen Leitnick"]
7
- registry = "https://github.com/UpliftGames/wally-index"
8
- realm = "shared"
9
-
10
- [dependencies]
11
- Signal = "sleitnick/signal@^2"
1
+ [package]
2
+ name = "sleitnick/timer"
3
+ description = "Timer class"
4
+ version = "2.0.0"
5
+ license = "MIT"
6
+ authors = ["Stephen Leitnick"]
7
+ registry = "https://github.com/UpliftGames/wally-index"
8
+ realm = "shared"
9
+
10
+ [dependencies]
11
+ Signal = "sleitnick/signal@^2"