@rbxts/planck 0.2.5 → 0.3.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +40 -51
- package/{out → src}/DependencyGraph.luau +220 -180
- package/src/Phase.d.ts +23 -0
- package/{out → src}/Phase.luau +41 -41
- package/src/Pipeline.d.ts +26 -0
- package/{out → src}/Pipeline.luau +86 -86
- package/src/Scheduler.d.ts +385 -0
- package/{out → src}/Scheduler.luau +207 -44
- package/src/__tests__/InitializerSystems.test.luau +660 -0
- package/src/__tests__/Scheduler.test.luau +313 -0
- package/src/__tests__/conditions.test.luau +147 -0
- package/src/__tests__/hooks.test.luau +54 -0
- package/src/__tests__/systems.test.luau +192 -0
- package/src/conditions.d.ts +69 -0
- package/{out → src}/conditions.luau +189 -151
- package/{out → src}/hooks.luau +163 -145
- package/src/index.d.ts +12 -0
- package/src/init.luau +207 -0
- package/src/utils.d.ts +10 -0
- package/{out → src}/utils.luau +197 -161
- package/out/Phase.d.ts +0 -8
- package/out/Pipeline.d.ts +0 -11
- package/out/Scheduler.d.ts +0 -31
- package/out/conditions.d.ts +0 -14
- package/out/hooks.d.ts +0 -4
- package/out/index.d.ts +0 -18
- package/out/init.luau +0 -143
- package/out/types.d.ts +0 -113
- package/out/utils.d.ts +0 -4
|
@@ -0,0 +1,660 @@
|
|
|
1
|
+
--!nonstrict
|
|
2
|
+
local ReplicatedStorage = game:GetService("ReplicatedStorage")
|
|
3
|
+
|
|
4
|
+
local root = script.Parent.Parent
|
|
5
|
+
|
|
6
|
+
local Phase = require(root.Phase)
|
|
7
|
+
local Scheduler = require(root.Scheduler)
|
|
8
|
+
|
|
9
|
+
local JestGlobals = require(ReplicatedStorage.DevPackages.JestGlobals)
|
|
10
|
+
|
|
11
|
+
local describe = JestGlobals.describe
|
|
12
|
+
local expect = JestGlobals.expect
|
|
13
|
+
local test = JestGlobals.test
|
|
14
|
+
|
|
15
|
+
describe("Initializer Systems", function()
|
|
16
|
+
describe("Basic Initialization", function()
|
|
17
|
+
test("standard system", function()
|
|
18
|
+
expect.assertions(3)
|
|
19
|
+
|
|
20
|
+
local runCount = 0
|
|
21
|
+
|
|
22
|
+
local function standardSystem()
|
|
23
|
+
runCount += 1
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
local myScheduler = Scheduler.new()
|
|
27
|
+
local myPhase = Phase.new("myPhase")
|
|
28
|
+
|
|
29
|
+
myScheduler:insert(myPhase):addSystem(standardSystem, myPhase)
|
|
30
|
+
|
|
31
|
+
myScheduler:runPhase(myPhase)
|
|
32
|
+
expect(runCount).toBe(1)
|
|
33
|
+
expect(myScheduler._systemInfo[standardSystem].initialized).toBe(
|
|
34
|
+
true
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
myScheduler:runPhase(myPhase)
|
|
38
|
+
expect(runCount).toBe(2)
|
|
39
|
+
end)
|
|
40
|
+
|
|
41
|
+
test("initializer system", function()
|
|
42
|
+
expect.assertions(7)
|
|
43
|
+
|
|
44
|
+
local initCount = 0
|
|
45
|
+
local runCount = 0
|
|
46
|
+
|
|
47
|
+
local function initializerSystem()
|
|
48
|
+
initCount += 1
|
|
49
|
+
|
|
50
|
+
return function()
|
|
51
|
+
runCount += 1
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
local myScheduler = Scheduler.new()
|
|
56
|
+
local myPhase = Phase.new("myPhase")
|
|
57
|
+
|
|
58
|
+
myScheduler:insert(myPhase):addSystem(initializerSystem, myPhase)
|
|
59
|
+
|
|
60
|
+
myScheduler:runPhase(myPhase)
|
|
61
|
+
expect(initCount).toBe(1)
|
|
62
|
+
expect(runCount).toBe(1)
|
|
63
|
+
expect(myScheduler._systemInfo[initializerSystem].initialized).toBe(
|
|
64
|
+
true
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
myScheduler:runPhase(myPhase)
|
|
68
|
+
expect(initCount).toBe(1)
|
|
69
|
+
expect(runCount).toBe(2)
|
|
70
|
+
|
|
71
|
+
myScheduler:runPhase(myPhase)
|
|
72
|
+
expect(initCount).toBe(1)
|
|
73
|
+
expect(runCount).toBe(3)
|
|
74
|
+
end)
|
|
75
|
+
|
|
76
|
+
test("initializer with cleanup", function()
|
|
77
|
+
expect.assertions(5)
|
|
78
|
+
|
|
79
|
+
local initCount = 0
|
|
80
|
+
local runCount = 0
|
|
81
|
+
local cleanupCount = 0
|
|
82
|
+
|
|
83
|
+
local function initializerWithCleanup()
|
|
84
|
+
initCount += 1
|
|
85
|
+
|
|
86
|
+
return function()
|
|
87
|
+
runCount += 1
|
|
88
|
+
end, function()
|
|
89
|
+
cleanupCount += 1
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
local myScheduler = Scheduler.new()
|
|
94
|
+
local myPhase = Phase.new("myPhase")
|
|
95
|
+
|
|
96
|
+
myScheduler
|
|
97
|
+
:insert(myPhase)
|
|
98
|
+
:addSystem(initializerWithCleanup, myPhase)
|
|
99
|
+
|
|
100
|
+
myScheduler:runPhase(myPhase)
|
|
101
|
+
expect(initCount).toBe(1)
|
|
102
|
+
expect(runCount).toBe(1)
|
|
103
|
+
expect(myScheduler._systemInfo[initializerWithCleanup].cleanup).toBeTruthy()
|
|
104
|
+
|
|
105
|
+
myScheduler:runPhase(myPhase)
|
|
106
|
+
expect(runCount).toBe(2)
|
|
107
|
+
|
|
108
|
+
myScheduler:removeSystem(initializerWithCleanup)
|
|
109
|
+
expect(cleanupCount).toBe(1)
|
|
110
|
+
end)
|
|
111
|
+
|
|
112
|
+
test("init once", function()
|
|
113
|
+
expect.assertions(2)
|
|
114
|
+
|
|
115
|
+
local initCount = 0
|
|
116
|
+
local runCount = 0
|
|
117
|
+
|
|
118
|
+
local function initOnceSystem()
|
|
119
|
+
initCount += 1
|
|
120
|
+
return function()
|
|
121
|
+
runCount += 1
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
local myScheduler = Scheduler.new()
|
|
126
|
+
local myPhase = Phase.new("myPhase")
|
|
127
|
+
|
|
128
|
+
myScheduler:insert(myPhase):addSystem(initOnceSystem, myPhase)
|
|
129
|
+
|
|
130
|
+
myScheduler:runPhase(myPhase)
|
|
131
|
+
myScheduler:runPhase(myPhase)
|
|
132
|
+
myScheduler:runPhase(myPhase)
|
|
133
|
+
myScheduler:runPhase(myPhase)
|
|
134
|
+
|
|
135
|
+
expect(initCount).toBe(1)
|
|
136
|
+
expect(runCount).toBe(4)
|
|
137
|
+
end)
|
|
138
|
+
end)
|
|
139
|
+
|
|
140
|
+
describe("Error Cases", function()
|
|
141
|
+
test("invalid return type", function()
|
|
142
|
+
expect.assertions(4)
|
|
143
|
+
|
|
144
|
+
local attemptCount = 0
|
|
145
|
+
|
|
146
|
+
local function brokenSystem()
|
|
147
|
+
attemptCount += 1
|
|
148
|
+
return "invalid"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
local myScheduler = Scheduler.new()
|
|
152
|
+
local myPhase = Phase.new("myPhase")
|
|
153
|
+
|
|
154
|
+
myScheduler:insert(myPhase):addSystem(brokenSystem, myPhase)
|
|
155
|
+
|
|
156
|
+
myScheduler:runPhase(myPhase)
|
|
157
|
+
expect(myScheduler._systemInfo[brokenSystem].initialized).toBe(true)
|
|
158
|
+
expect(attemptCount).toBe(1)
|
|
159
|
+
|
|
160
|
+
myScheduler:runPhase(myPhase)
|
|
161
|
+
expect(myScheduler._systemInfo[brokenSystem].initialized).toBe(true)
|
|
162
|
+
expect(attemptCount).toBe(2)
|
|
163
|
+
end)
|
|
164
|
+
|
|
165
|
+
test("init with run condition", function()
|
|
166
|
+
expect.assertions(5)
|
|
167
|
+
|
|
168
|
+
local initCount = 0
|
|
169
|
+
local runCount = 0
|
|
170
|
+
local allowRun = false
|
|
171
|
+
|
|
172
|
+
local function conditionalInit()
|
|
173
|
+
initCount += 1
|
|
174
|
+
return function()
|
|
175
|
+
runCount += 1
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
local myScheduler = Scheduler.new()
|
|
180
|
+
local myPhase = Phase.new("myPhase")
|
|
181
|
+
|
|
182
|
+
myScheduler
|
|
183
|
+
:insert(myPhase)
|
|
184
|
+
:addSystem(conditionalInit, myPhase)
|
|
185
|
+
:addRunCondition(conditionalInit, function()
|
|
186
|
+
return allowRun
|
|
187
|
+
end)
|
|
188
|
+
|
|
189
|
+
myScheduler:runPhase(myPhase)
|
|
190
|
+
expect(initCount).toBe(0)
|
|
191
|
+
expect(runCount).toBe(0)
|
|
192
|
+
|
|
193
|
+
allowRun = true
|
|
194
|
+
|
|
195
|
+
myScheduler:runPhase(myPhase)
|
|
196
|
+
expect(initCount).toBe(1)
|
|
197
|
+
expect(runCount).toBe(1)
|
|
198
|
+
|
|
199
|
+
myScheduler:runPhase(myPhase)
|
|
200
|
+
expect(runCount).toBe(2)
|
|
201
|
+
end)
|
|
202
|
+
|
|
203
|
+
test("nested initializer should not run inner", function()
|
|
204
|
+
expect.assertions(3)
|
|
205
|
+
|
|
206
|
+
local initCount = 0
|
|
207
|
+
local runtimeReturnCount = 0
|
|
208
|
+
local innerRunCount = 0
|
|
209
|
+
|
|
210
|
+
local function nestedInit()
|
|
211
|
+
initCount += 1
|
|
212
|
+
return function()
|
|
213
|
+
runtimeReturnCount += 1
|
|
214
|
+
return function()
|
|
215
|
+
innerRunCount += 1
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
local myScheduler = Scheduler.new()
|
|
221
|
+
local myPhase = Phase.new("myPhase")
|
|
222
|
+
|
|
223
|
+
myScheduler:insert(myPhase):addSystem(nestedInit, myPhase)
|
|
224
|
+
|
|
225
|
+
myScheduler:runPhase(myPhase)
|
|
226
|
+
myScheduler:runPhase(myPhase)
|
|
227
|
+
myScheduler:runPhase(myPhase)
|
|
228
|
+
|
|
229
|
+
expect(initCount).toBe(1)
|
|
230
|
+
expect(runtimeReturnCount).toBe(3)
|
|
231
|
+
expect(innerRunCount).toBe(0)
|
|
232
|
+
end)
|
|
233
|
+
|
|
234
|
+
test("nil with second value", function()
|
|
235
|
+
expect.assertions(1)
|
|
236
|
+
|
|
237
|
+
local function invalidNilSystem()
|
|
238
|
+
return nil, "oops"
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
local myScheduler = Scheduler.new()
|
|
242
|
+
local myPhase = Phase.new("myPhase")
|
|
243
|
+
|
|
244
|
+
myScheduler:insert(myPhase):addSystem(invalidNilSystem, myPhase)
|
|
245
|
+
|
|
246
|
+
myScheduler:runPhase(myPhase)
|
|
247
|
+
expect(myScheduler._systemInfo[invalidNilSystem].initialized).toBe(
|
|
248
|
+
true
|
|
249
|
+
)
|
|
250
|
+
end)
|
|
251
|
+
|
|
252
|
+
test("same system in multiple phases", function()
|
|
253
|
+
expect.assertions(2)
|
|
254
|
+
|
|
255
|
+
local initCount = 0
|
|
256
|
+
|
|
257
|
+
local function sharedSystem()
|
|
258
|
+
initCount += 1
|
|
259
|
+
return function() end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
local myScheduler = Scheduler.new()
|
|
263
|
+
local phase1 = Phase.new("Phase1")
|
|
264
|
+
local phase2 = Phase.new("Phase2")
|
|
265
|
+
|
|
266
|
+
myScheduler
|
|
267
|
+
:insert(phase1)
|
|
268
|
+
:insert(phase2)
|
|
269
|
+
:addSystem(sharedSystem, phase1)
|
|
270
|
+
:addSystem(sharedSystem, phase2)
|
|
271
|
+
|
|
272
|
+
myScheduler:runPhase(phase1)
|
|
273
|
+
expect(initCount).toBe(1)
|
|
274
|
+
|
|
275
|
+
myScheduler:runPhase(phase2)
|
|
276
|
+
expect(initCount).toBe(1)
|
|
277
|
+
end)
|
|
278
|
+
|
|
279
|
+
test("table with 2 functions", function()
|
|
280
|
+
expect.assertions(4)
|
|
281
|
+
|
|
282
|
+
local initCount = 0
|
|
283
|
+
local runCount = 0
|
|
284
|
+
local cleanupCount = 0
|
|
285
|
+
|
|
286
|
+
local function tableStyleInit()
|
|
287
|
+
initCount += 1
|
|
288
|
+
return {
|
|
289
|
+
system = function()
|
|
290
|
+
runCount += 1
|
|
291
|
+
end,
|
|
292
|
+
cleanup = function()
|
|
293
|
+
cleanupCount += 1
|
|
294
|
+
end,
|
|
295
|
+
}
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
local myScheduler = Scheduler.new()
|
|
299
|
+
local myPhase = Phase.new("myPhase")
|
|
300
|
+
|
|
301
|
+
myScheduler:insert(myPhase):addSystem(tableStyleInit, myPhase)
|
|
302
|
+
|
|
303
|
+
myScheduler:runPhase(myPhase)
|
|
304
|
+
expect(initCount).toBe(1)
|
|
305
|
+
expect(runCount).toBe(1)
|
|
306
|
+
|
|
307
|
+
myScheduler:runPhase(myPhase)
|
|
308
|
+
expect(runCount).toBe(2)
|
|
309
|
+
|
|
310
|
+
myScheduler:removeSystem(tableStyleInit)
|
|
311
|
+
expect(cleanupCount).toBe(1)
|
|
312
|
+
end)
|
|
313
|
+
|
|
314
|
+
test("table with 1 function", function()
|
|
315
|
+
expect.assertions(3)
|
|
316
|
+
|
|
317
|
+
local initCount = 0
|
|
318
|
+
local runCount = 0
|
|
319
|
+
|
|
320
|
+
local function singleTableInit()
|
|
321
|
+
initCount += 1
|
|
322
|
+
return {
|
|
323
|
+
system = function()
|
|
324
|
+
runCount += 1
|
|
325
|
+
end,
|
|
326
|
+
}
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
local myScheduler = Scheduler.new()
|
|
330
|
+
local myPhase = Phase.new("myPhase")
|
|
331
|
+
|
|
332
|
+
myScheduler:insert(myPhase):addSystem(singleTableInit, myPhase)
|
|
333
|
+
|
|
334
|
+
myScheduler:runPhase(myPhase)
|
|
335
|
+
expect(initCount).toBe(1)
|
|
336
|
+
expect(runCount).toBe(1)
|
|
337
|
+
|
|
338
|
+
myScheduler:runPhase(myPhase)
|
|
339
|
+
expect(runCount).toBe(2)
|
|
340
|
+
end)
|
|
341
|
+
|
|
342
|
+
test("table with non-functions", function()
|
|
343
|
+
expect.assertions(1)
|
|
344
|
+
|
|
345
|
+
local function invalidTableSystem()
|
|
346
|
+
return { system = "not a function", cleanup = 123 }
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
local myScheduler = Scheduler.new()
|
|
350
|
+
local myPhase = Phase.new("myPhase")
|
|
351
|
+
|
|
352
|
+
myScheduler:insert(myPhase):addSystem(invalidTableSystem, myPhase)
|
|
353
|
+
|
|
354
|
+
myScheduler:runPhase(myPhase)
|
|
355
|
+
expect(myScheduler._systemInfo[invalidTableSystem].initialized).toBe(
|
|
356
|
+
true
|
|
357
|
+
)
|
|
358
|
+
end)
|
|
359
|
+
|
|
360
|
+
test("table with cleanup only (startup system)", function()
|
|
361
|
+
expect.assertions(5)
|
|
362
|
+
|
|
363
|
+
local startupRunCount = 0
|
|
364
|
+
local cleanupRan = false
|
|
365
|
+
|
|
366
|
+
local function startupSystem()
|
|
367
|
+
startupRunCount += 1
|
|
368
|
+
-- Returns cleanup only - no runtime system
|
|
369
|
+
return {
|
|
370
|
+
cleanup = function()
|
|
371
|
+
cleanupRan = true
|
|
372
|
+
end,
|
|
373
|
+
}
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
local myScheduler = Scheduler.new()
|
|
377
|
+
local myPhase = Phase.new("myPhase")
|
|
378
|
+
|
|
379
|
+
myScheduler:insert(myPhase):addSystem(startupSystem, myPhase)
|
|
380
|
+
|
|
381
|
+
-- First run: startup logic executes
|
|
382
|
+
myScheduler:runPhase(myPhase)
|
|
383
|
+
expect(startupRunCount).toBe(1)
|
|
384
|
+
expect(myScheduler._systemInfo[startupSystem].initialized).toBe(
|
|
385
|
+
true
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
-- Second run: original function runs again (startup-only pattern)
|
|
389
|
+
myScheduler:runPhase(myPhase)
|
|
390
|
+
expect(startupRunCount).toBe(2)
|
|
391
|
+
|
|
392
|
+
-- Cleanup on removal
|
|
393
|
+
expect(cleanupRan).toBe(false)
|
|
394
|
+
myScheduler:removeSystem(startupSystem)
|
|
395
|
+
expect(cleanupRan).toBe(true)
|
|
396
|
+
end)
|
|
397
|
+
|
|
398
|
+
test("table with neither system nor cleanup", function()
|
|
399
|
+
expect.assertions(1)
|
|
400
|
+
|
|
401
|
+
local function invalidSystem()
|
|
402
|
+
return { foo = "bar" } -- No system or cleanup fields
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
local myScheduler = Scheduler.new()
|
|
406
|
+
local myPhase = Phase.new("myPhase")
|
|
407
|
+
|
|
408
|
+
myScheduler:insert(myPhase):addSystem(invalidSystem, myPhase)
|
|
409
|
+
|
|
410
|
+
myScheduler:runPhase(myPhase)
|
|
411
|
+
expect(myScheduler._systemInfo[invalidSystem].initialized).toBe(
|
|
412
|
+
true
|
|
413
|
+
)
|
|
414
|
+
end)
|
|
415
|
+
end)
|
|
416
|
+
|
|
417
|
+
describe("Cleanup", function()
|
|
418
|
+
test("cleanup once", function()
|
|
419
|
+
expect.assertions(1)
|
|
420
|
+
|
|
421
|
+
local cleanupCount = 0
|
|
422
|
+
|
|
423
|
+
local function systemWithCleanup()
|
|
424
|
+
return function() end, function()
|
|
425
|
+
cleanupCount += 1
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
local myScheduler = Scheduler.new()
|
|
430
|
+
local myPhase = Phase.new("myPhase")
|
|
431
|
+
|
|
432
|
+
myScheduler:insert(myPhase):addSystem(systemWithCleanup, myPhase)
|
|
433
|
+
|
|
434
|
+
myScheduler:runPhase(myPhase)
|
|
435
|
+
myScheduler:removeSystem(systemWithCleanup)
|
|
436
|
+
|
|
437
|
+
expect(cleanupCount).toBe(1)
|
|
438
|
+
end)
|
|
439
|
+
|
|
440
|
+
test("no cleanup if uninitialized", function()
|
|
441
|
+
expect.assertions(1)
|
|
442
|
+
|
|
443
|
+
local cleanupCount = 0
|
|
444
|
+
local allowRun = false
|
|
445
|
+
|
|
446
|
+
local function conditionalSystem()
|
|
447
|
+
return function() end, function()
|
|
448
|
+
cleanupCount += 1
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
local myScheduler = Scheduler.new()
|
|
453
|
+
local myPhase = Phase.new("myPhase")
|
|
454
|
+
|
|
455
|
+
myScheduler
|
|
456
|
+
:insert(myPhase)
|
|
457
|
+
:addSystem(conditionalSystem, myPhase)
|
|
458
|
+
:addRunCondition(conditionalSystem, function()
|
|
459
|
+
return allowRun
|
|
460
|
+
end)
|
|
461
|
+
|
|
462
|
+
myScheduler:runPhase(myPhase)
|
|
463
|
+
|
|
464
|
+
myScheduler:removeSystem(conditionalSystem)
|
|
465
|
+
expect(cleanupCount).toBe(0)
|
|
466
|
+
end)
|
|
467
|
+
|
|
468
|
+
test("cleanup failure", function()
|
|
469
|
+
expect.assertions(2)
|
|
470
|
+
|
|
471
|
+
local cleanupRan = false
|
|
472
|
+
|
|
473
|
+
local function brokenCleanupSystem()
|
|
474
|
+
return function() end, function()
|
|
475
|
+
cleanupRan = true
|
|
476
|
+
error("Cleanup failed!")
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
local myScheduler = Scheduler.new()
|
|
481
|
+
local myPhase = Phase.new("myPhase")
|
|
482
|
+
|
|
483
|
+
myScheduler:insert(myPhase):addSystem(brokenCleanupSystem, myPhase)
|
|
484
|
+
|
|
485
|
+
myScheduler:runPhase(myPhase)
|
|
486
|
+
|
|
487
|
+
myScheduler:removeSystem(brokenCleanupSystem)
|
|
488
|
+
|
|
489
|
+
expect(cleanupRan).toBe(true)
|
|
490
|
+
expect(myScheduler._systemInfo[brokenCleanupSystem]).toBeNil()
|
|
491
|
+
end)
|
|
492
|
+
|
|
493
|
+
test("cleanup on replaceSystem", function()
|
|
494
|
+
expect.assertions(3)
|
|
495
|
+
|
|
496
|
+
local cleanupCount = 0
|
|
497
|
+
local newSystemRan = false
|
|
498
|
+
|
|
499
|
+
local function oldSystem()
|
|
500
|
+
return function() end, function()
|
|
501
|
+
cleanupCount += 1
|
|
502
|
+
end
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
local function newSystem()
|
|
506
|
+
newSystemRan = true
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
local myScheduler = Scheduler.new()
|
|
510
|
+
local myPhase = Phase.new("myPhase")
|
|
511
|
+
|
|
512
|
+
myScheduler:insert(myPhase):addSystem(oldSystem, myPhase)
|
|
513
|
+
|
|
514
|
+
myScheduler:runPhase(myPhase)
|
|
515
|
+
expect(cleanupCount).toBe(0)
|
|
516
|
+
|
|
517
|
+
myScheduler:replaceSystem(oldSystem, newSystem)
|
|
518
|
+
expect(cleanupCount).toBe(1)
|
|
519
|
+
|
|
520
|
+
myScheduler:runPhase(myPhase)
|
|
521
|
+
expect(newSystemRan).toBe(true)
|
|
522
|
+
end)
|
|
523
|
+
|
|
524
|
+
test("cleanup receives custom args on removeSystem", function()
|
|
525
|
+
expect.assertions(1)
|
|
526
|
+
|
|
527
|
+
local capturedArgs = nil
|
|
528
|
+
|
|
529
|
+
local function systemWithArgsInCleanup()
|
|
530
|
+
return function() end, function(...)
|
|
531
|
+
capturedArgs = { ... }
|
|
532
|
+
end
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
local myScheduler = Scheduler.new(1, 2, 3)
|
|
536
|
+
local myPhase = Phase.new("myPhase")
|
|
537
|
+
|
|
538
|
+
myScheduler
|
|
539
|
+
:insert(myPhase)
|
|
540
|
+
:addSystem(systemWithArgsInCleanup, myPhase)
|
|
541
|
+
|
|
542
|
+
myScheduler:runPhase(myPhase) -- Initialize
|
|
543
|
+
myScheduler:removeSystem(systemWithArgsInCleanup)
|
|
544
|
+
|
|
545
|
+
expect(capturedArgs).toEqual({ 1, 2, 3 })
|
|
546
|
+
end)
|
|
547
|
+
|
|
548
|
+
test("cleanup receives custom args on replaceSystem", function()
|
|
549
|
+
expect.assertions(1)
|
|
550
|
+
|
|
551
|
+
local capturedArgs = nil
|
|
552
|
+
|
|
553
|
+
local function oldSystem()
|
|
554
|
+
return function() end, function(...)
|
|
555
|
+
capturedArgs = { ... }
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
local function newSystem() end
|
|
560
|
+
|
|
561
|
+
local myScheduler = Scheduler.new(1, 2, 3)
|
|
562
|
+
local myPhase = Phase.new("myPhase")
|
|
563
|
+
|
|
564
|
+
myScheduler:insert(myPhase):addSystem(oldSystem, myPhase)
|
|
565
|
+
|
|
566
|
+
myScheduler:runPhase(myPhase) -- Initialize
|
|
567
|
+
myScheduler:replaceSystem(oldSystem, newSystem)
|
|
568
|
+
|
|
569
|
+
expect(capturedArgs).toEqual({ 1, 2, 3 })
|
|
570
|
+
end)
|
|
571
|
+
end)
|
|
572
|
+
|
|
573
|
+
describe("Integration", function()
|
|
574
|
+
test("with ordering", function()
|
|
575
|
+
expect.assertions(6)
|
|
576
|
+
|
|
577
|
+
local order = {}
|
|
578
|
+
|
|
579
|
+
local function systemA()
|
|
580
|
+
table.insert(order, "A-init")
|
|
581
|
+
return function()
|
|
582
|
+
table.insert(order, "A-run")
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
local function systemB()
|
|
587
|
+
table.insert(order, "B-init")
|
|
588
|
+
return function()
|
|
589
|
+
table.insert(order, "B-run")
|
|
590
|
+
end
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
local myScheduler = Scheduler.new()
|
|
594
|
+
local myPhase = Phase.new("myPhase")
|
|
595
|
+
|
|
596
|
+
myScheduler
|
|
597
|
+
:insert(myPhase)
|
|
598
|
+
:addSystem(systemA, myPhase)
|
|
599
|
+
:addSystem(systemB, myPhase)
|
|
600
|
+
|
|
601
|
+
myScheduler:runPhase(myPhase)
|
|
602
|
+
expect(order[1]).toBe("A-init")
|
|
603
|
+
expect(order[2]).toBe("A-run")
|
|
604
|
+
expect(order[3]).toBe("B-init")
|
|
605
|
+
expect(order[4]).toBe("B-run")
|
|
606
|
+
|
|
607
|
+
table.clear(order)
|
|
608
|
+
|
|
609
|
+
myScheduler:runPhase(myPhase)
|
|
610
|
+
expect(order[1]).toBe("A-run")
|
|
611
|
+
expect(order[2]).toBe("B-run")
|
|
612
|
+
end)
|
|
613
|
+
|
|
614
|
+
test("with dependency graph", function()
|
|
615
|
+
expect.assertions(6)
|
|
616
|
+
|
|
617
|
+
local order = {}
|
|
618
|
+
|
|
619
|
+
local function systemA()
|
|
620
|
+
table.insert(order, "A-init")
|
|
621
|
+
return function()
|
|
622
|
+
table.insert(order, "A-run")
|
|
623
|
+
end
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
local function systemB()
|
|
627
|
+
table.insert(order, "B-init")
|
|
628
|
+
return function()
|
|
629
|
+
table.insert(order, "B-run")
|
|
630
|
+
end
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
local myScheduler = Scheduler.new()
|
|
634
|
+
local phaseA = Phase.new("PhaseA")
|
|
635
|
+
local phaseB = Phase.new("PhaseB")
|
|
636
|
+
|
|
637
|
+
myScheduler
|
|
638
|
+
:insert(phaseA)
|
|
639
|
+
:insertAfter(phaseB, phaseA)
|
|
640
|
+
:addSystem(systemA, phaseA)
|
|
641
|
+
:addSystem(systemB, phaseB)
|
|
642
|
+
|
|
643
|
+
myScheduler:runPhase(phaseA)
|
|
644
|
+
myScheduler:runPhase(phaseB)
|
|
645
|
+
|
|
646
|
+
expect(order[1]).toBe("A-init")
|
|
647
|
+
expect(order[2]).toBe("A-run")
|
|
648
|
+
expect(order[3]).toBe("B-init")
|
|
649
|
+
expect(order[4]).toBe("B-run")
|
|
650
|
+
|
|
651
|
+
table.clear(order)
|
|
652
|
+
|
|
653
|
+
myScheduler:runPhase(phaseA)
|
|
654
|
+
myScheduler:runPhase(phaseB)
|
|
655
|
+
|
|
656
|
+
expect(order[1]).toBe("A-run")
|
|
657
|
+
expect(order[2]).toBe("B-run")
|
|
658
|
+
end)
|
|
659
|
+
end)
|
|
660
|
+
end)
|