moonscratch 0.1.0 → 0.1.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 (150) hide show
  1. package/dist/chunk-DQk6qfdC.mjs +18 -0
  2. package/dist/index.d.mts +1173 -0
  3. package/dist/index.mjs +27135 -0
  4. package/package.json +6 -1
  5. package/.agents/skills/moonbit-agent-guide/LICENSE +0 -202
  6. package/.agents/skills/moonbit-agent-guide/SKILL.mbt.md +0 -1126
  7. package/.agents/skills/moonbit-agent-guide/SKILL.md +0 -1126
  8. package/.agents/skills/moonbit-agent-guide/ide.md +0 -116
  9. package/.agents/skills/moonbit-agent-guide/references/advanced-moonbit-build.md +0 -106
  10. package/.agents/skills/moonbit-agent-guide/references/moonbit-language-fundamentals.mbt.md +0 -422
  11. package/.agents/skills/moonbit-agent-guide/references/moonbit-language-fundamentals.md +0 -422
  12. package/.agents/skills/moonbit-practice/SKILL.md +0 -258
  13. package/.agents/skills/moonbit-practice/assets/ci.yaml +0 -25
  14. package/.agents/skills/moonbit-practice/reference/agents.md +0 -1469
  15. package/.agents/skills/moonbit-practice/reference/configuration.md +0 -228
  16. package/.agents/skills/moonbit-practice/reference/ffi.md +0 -229
  17. package/.agents/skills/moonbit-practice/reference/ide.md +0 -189
  18. package/.agents/skills/moonbit-practice/reference/performance.md +0 -217
  19. package/.agents/skills/moonbit-practice/reference/refactor.md +0 -154
  20. package/.agents/skills/moonbit-practice/reference/stdlib.md +0 -351
  21. package/.agents/skills/moonbit-practice/reference/testing.md +0 -228
  22. package/.agents/skills/moonbit-refactoring/LICENSE +0 -21
  23. package/.agents/skills/moonbit-refactoring/SKILL.md +0 -323
  24. package/.githooks/README.md +0 -23
  25. package/.githooks/pre-commit +0 -3
  26. package/.github/workflows/copilot-setup-steps.yml +0 -40
  27. package/.turbo/turbo-typecheck.log +0 -2
  28. package/AGENTS.md +0 -91
  29. package/PLAN.md +0 -64
  30. package/TODO.md +0 -120
  31. package/benchmarks/calc.bench.ts +0 -144
  32. package/benchmarks/draw.bench.ts +0 -215
  33. package/benchmarks/load.bench.ts +0 -28
  34. package/benchmarks/render.bench.ts +0 -53
  35. package/benchmarks/run.bench.ts +0 -8
  36. package/benchmarks/types.d.ts +0 -15
  37. package/docs/scratch-vm-specs/eventloop.md +0 -103
  38. package/docs/scratch-vm-specs/moonscratch-time-separation.md +0 -50
  39. package/index.html +0 -91
  40. package/js/AGENTS.md +0 -5
  41. package/js/a.ts +0 -52
  42. package/js/assets/AGENTS.md +0 -5
  43. package/js/assets/base64.test.ts +0 -14
  44. package/js/assets/base64.ts +0 -21
  45. package/js/assets/build-asset.test.ts +0 -26
  46. package/js/assets/build-asset.ts +0 -28
  47. package/js/assets/create.test.ts +0 -142
  48. package/js/assets/create.ts +0 -122
  49. package/js/assets/index.test.ts +0 -15
  50. package/js/assets/index.ts +0 -2
  51. package/js/assets/types.ts +0 -26
  52. package/js/assets/validation.test.ts +0 -34
  53. package/js/assets/validation.ts +0 -25
  54. package/js/assets.test.ts +0 -14
  55. package/js/assets.ts +0 -1
  56. package/js/index.test.ts +0 -26
  57. package/js/index.ts +0 -3
  58. package/js/render/index.test.ts +0 -65
  59. package/js/render/index.ts +0 -13
  60. package/js/render/sharp.ts +0 -87
  61. package/js/render/svg.ts +0 -68
  62. package/js/render/types.ts +0 -35
  63. package/js/render/utils.ts +0 -108
  64. package/js/render/webgl.ts +0 -274
  65. package/js/sharp-optional.d.ts +0 -16
  66. package/js/test/helpers.ts +0 -116
  67. package/js/test/hikkaku-sample.test.ts +0 -37
  68. package/js/test/rubik-components.input-motion.test.ts +0 -60
  69. package/js/test/rubik-components.lists.test.ts +0 -49
  70. package/js/test/rubik-components.operators.test.ts +0 -104
  71. package/js/test/rubik-components.pen.test.ts +0 -112
  72. package/js/test/rubik-components.procedures-loops.test.ts +0 -72
  73. package/js/test/rubik-components.variables-branches.test.ts +0 -57
  74. package/js/test/rubik-components.visibility-entry.test.ts +0 -31
  75. package/js/test/test-projects.ts +0 -598
  76. package/js/test/variable.ts +0 -200
  77. package/js/test/warp.test.ts +0 -59
  78. package/js/vm/AGENTS.md +0 -6
  79. package/js/vm/README.md +0 -183
  80. package/js/vm/bindings.test.ts +0 -13
  81. package/js/vm/bindings.ts +0 -5
  82. package/js/vm/compare-operators.test.ts +0 -145
  83. package/js/vm/constants.test.ts +0 -11
  84. package/js/vm/constants.ts +0 -4
  85. package/js/vm/effect-guards.test.ts +0 -68
  86. package/js/vm/effect-guards.ts +0 -44
  87. package/js/vm/factory.test.ts +0 -486
  88. package/js/vm/factory.ts +0 -615
  89. package/js/vm/headless-vm.test.ts +0 -131
  90. package/js/vm/headless-vm.ts +0 -342
  91. package/js/vm/index.test.ts +0 -28
  92. package/js/vm/index.ts +0 -5
  93. package/js/vm/internal-types.ts +0 -32
  94. package/js/vm/json.test.ts +0 -40
  95. package/js/vm/json.ts +0 -273
  96. package/js/vm/normalize.test.ts +0 -48
  97. package/js/vm/normalize.ts +0 -65
  98. package/js/vm/options.test.ts +0 -30
  99. package/js/vm/options.ts +0 -55
  100. package/js/vm/pen-transparency.test.ts +0 -115
  101. package/js/vm/program-wasm.ts +0 -322
  102. package/js/vm/scheduler-render.test.ts +0 -401
  103. package/js/vm/scratch-assets.test.ts +0 -136
  104. package/js/vm/scratch-assets.ts +0 -202
  105. package/js/vm/types.ts +0 -358
  106. package/js/vm/value-guards.test.ts +0 -25
  107. package/js/vm/value-guards.ts +0 -18
  108. package/moon.mod.json +0 -10
  109. package/scripts/preinstall.ts +0 -4
  110. package/src/AGENTS.md +0 -6
  111. package/src/api.mbt +0 -161
  112. package/src/api_aot_commands.mbt +0 -184
  113. package/src/api_effects_json.mbt +0 -72
  114. package/src/api_options.mbt +0 -60
  115. package/src/api_program_wasm.mbt +0 -1647
  116. package/src/api_program_wat.mbt +0 -2206
  117. package/src/api_snapshot_json.mbt +0 -44
  118. package/src/cmd/AGENTS.md +0 -5
  119. package/src/cmd/main/AGENTS.md +0 -5
  120. package/src/cmd/main/main.mbt +0 -29
  121. package/src/cmd/main/moon.pkg +0 -7
  122. package/src/cmd/main/pkg.generated.mbti +0 -13
  123. package/src/json_helpers.mbt +0 -176
  124. package/src/moon.pkg +0 -65
  125. package/src/moonscratch.mbt +0 -3
  126. package/src/moonscratch_wbtest.mbt +0 -40
  127. package/src/parser_sb3.mbt +0 -890
  128. package/src/pkg.generated.mbti +0 -479
  129. package/src/runtime_eval.mbt +0 -2844
  130. package/src/runtime_exec.mbt +0 -3850
  131. package/src/runtime_render.mbt +0 -2550
  132. package/src/runtime_state.mbt +0 -870
  133. package/src/test/AGENTS.md +0 -3
  134. package/src/test/projects/AGENTS.md +0 -6
  135. package/src/test/projects/moon.pkg +0 -4
  136. package/src/test/projects/moonscratch_compat_test.mbt +0 -642
  137. package/src/test/projects/moonscratch_core_test.mbt +0 -1332
  138. package/src/test/projects/moonscratch_runtime_test.mbt +0 -1087
  139. package/src/test/projects/pkg.generated.mbti +0 -13
  140. package/src/test/projects/test_support.mbt +0 -35
  141. package/src/types_effects.mbt +0 -20
  142. package/src/types_error.mbt +0 -4
  143. package/src/types_options.mbt +0 -31
  144. package/src/types_runtime_structs.mbt +0 -254
  145. package/src/types_vm.mbt +0 -109
  146. package/tsconfig.json +0 -29
  147. package/viewer/index.ts +0 -399
  148. package/viewer/vite.d.ts +0 -1
  149. package/viewer/worker.ts +0 -161
  150. package/vite.config.ts +0 -11
@@ -1,1332 +0,0 @@
1
- ///|
2
- let broadcast_project =
3
- #|{
4
- #| "targets": [
5
- #| {
6
- #| "isStage": true,
7
- #| "name": "Stage",
8
- #| "variables": {
9
- #| "var_score": ["score", 0]
10
- #| },
11
- #| "lists": {},
12
- #| "blocks": {}
13
- #| },
14
- #| {
15
- #| "isStage": false,
16
- #| "name": "Sprite1",
17
- #| "variables": {},
18
- #| "lists": {},
19
- #| "blocks": {
20
- #| "hat_flag": {
21
- #| "opcode": "event_whenflagclicked",
22
- #| "next": "set_score",
23
- #| "parent": null,
24
- #| "inputs": {},
25
- #| "fields": {},
26
- #| "topLevel": true
27
- #| },
28
- #| "set_score": {
29
- #| "opcode": "data_setvariableto",
30
- #| "next": "broadcast_go",
31
- #| "parent": "hat_flag",
32
- #| "inputs": {
33
- #| "VALUE": [1, [4, 1]]
34
- #| },
35
- #| "fields": {
36
- #| "VARIABLE": ["score", "var_score"]
37
- #| },
38
- #| "topLevel": false
39
- #| },
40
- #| "broadcast_go": {
41
- #| "opcode": "event_broadcast",
42
- #| "next": null,
43
- #| "parent": "set_score",
44
- #| "inputs": {
45
- #| "BROADCAST_INPUT": [1, "broadcast_menu"]
46
- #| },
47
- #| "fields": {},
48
- #| "topLevel": false
49
- #| },
50
- #| "broadcast_menu": {
51
- #| "opcode": "event_broadcast_menu",
52
- #| "next": null,
53
- #| "parent": "broadcast_go",
54
- #| "inputs": {},
55
- #| "fields": {
56
- #| "BROADCAST_OPTION": ["go", "broadcast_go_id"]
57
- #| },
58
- #| "topLevel": false,
59
- #| "shadow": true
60
- #| },
61
- #| "hat_broadcast": {
62
- #| "opcode": "event_whenbroadcastreceived",
63
- #| "next": "change_score",
64
- #| "parent": null,
65
- #| "inputs": {},
66
- #| "fields": {
67
- #| "BROADCAST_OPTION": ["go", "broadcast_go_id"]
68
- #| },
69
- #| "topLevel": true
70
- #| },
71
- #| "change_score": {
72
- #| "opcode": "data_changevariableby",
73
- #| "next": null,
74
- #| "parent": "hat_broadcast",
75
- #| "inputs": {
76
- #| "VALUE": [1, [4, 5]]
77
- #| },
78
- #| "fields": {
79
- #| "VARIABLE": ["score", "var_score"]
80
- #| },
81
- #| "topLevel": false
82
- #| }
83
- #| }
84
- #| }
85
- #| ]
86
- #|}
87
-
88
- ///|
89
- let ask_project =
90
- #|{
91
- #| "targets": [
92
- #| {
93
- #| "isStage": true,
94
- #| "name": "Stage",
95
- #| "variables": {
96
- #| "var_answer": ["answerVar", ""]
97
- #| },
98
- #| "lists": {},
99
- #| "blocks": {}
100
- #| },
101
- #| {
102
- #| "isStage": false,
103
- #| "name": "Sprite1",
104
- #| "variables": {},
105
- #| "lists": {},
106
- #| "blocks": {
107
- #| "hat_flag": {
108
- #| "opcode": "event_whenflagclicked",
109
- #| "next": "ask_name",
110
- #| "parent": null,
111
- #| "inputs": {},
112
- #| "fields": {},
113
- #| "topLevel": true
114
- #| },
115
- #| "ask_name": {
116
- #| "opcode": "sensing_askandwait",
117
- #| "next": "set_answer",
118
- #| "parent": "hat_flag",
119
- #| "inputs": {
120
- #| "QUESTION": [1, [10, "your name?"]]
121
- #| },
122
- #| "fields": {},
123
- #| "topLevel": false
124
- #| },
125
- #| "set_answer": {
126
- #| "opcode": "data_setvariableto",
127
- #| "next": null,
128
- #| "parent": "ask_name",
129
- #| "inputs": {
130
- #| "VALUE": [1, "answer_reporter"]
131
- #| },
132
- #| "fields": {
133
- #| "VARIABLE": ["answerVar", "var_answer"]
134
- #| },
135
- #| "topLevel": false
136
- #| },
137
- #| "answer_reporter": {
138
- #| "opcode": "sensing_answer",
139
- #| "next": null,
140
- #| "parent": "set_answer",
141
- #| "inputs": {},
142
- #| "fields": {},
143
- #| "topLevel": false
144
- #| }
145
- #| }
146
- #| }
147
- #| ]
148
- #|}
149
-
150
- ///|
151
- fn[T, E] unwrap_result(result : Result[T, E], message : String) -> T raise {
152
- match result {
153
- Ok(value) => value
154
- Err(_) => fail(message)
155
- }
156
- }
157
-
158
- ///|
159
- fn vm_new_precompiled_from_json(
160
- project_json : String,
161
- assets_json? : String,
162
- options_json? : String,
163
- ) -> @moonscratch.Vm raise @moonscratch.VmError {
164
- let precompiled = match assets_json {
165
- Some(assets_json) =>
166
- @moonscratch.vm_compile_from_json(project_json, assets_json~)
167
- None => @moonscratch.vm_compile_from_json(project_json)
168
- }
169
- match options_json {
170
- Some(options_json) =>
171
- @moonscratch.vm_new_from_compiled(precompiled, options_json~)
172
- None => @moonscratch.vm_new_from_compiled(precompiled)
173
- }
174
- }
175
-
176
- ///|
177
- test "green flag + broadcast updates variable" {
178
- let vm = unwrap_result(
179
- try? vm_new_precompiled_from_json(broadcast_project),
180
- "vm init failed",
181
- )
182
- @moonscratch.vm_green_flag(vm)
183
- ignore(@moonscratch.vm_step_frame(vm))
184
- ignore(@moonscratch.vm_step_frame(vm))
185
-
186
- let snapshot = @moonscratch.vm_snapshot_json(vm)
187
- let root = unwrap_result(try? @json.parse(snapshot), "snapshot parse failed")
188
- let root_obj = match root {
189
- Object(obj) => obj
190
- _ => fail("snapshot must be object")
191
- }
192
- let targets = match root_obj["targets"] {
193
- Array(items) => items
194
- _ => fail("targets must be array")
195
- }
196
- let stage = match targets[0] {
197
- Object(obj) => obj
198
- _ => fail("stage must be object")
199
- }
200
- let vars = match stage["variables"] {
201
- Object(obj) => obj
202
- _ => fail("variables must be object")
203
- }
204
- assert_eq(vars["var_score"], Json::number(6.0))
205
- }
206
-
207
- ///|
208
- test "ask waits for answer and resumes via post_io" {
209
- let vm = unwrap_result(
210
- try? vm_new_precompiled_from_json(ask_project),
211
- "vm init failed",
212
- )
213
- @moonscratch.vm_green_flag(vm)
214
-
215
- ignore(@moonscratch.vm_step_frame(vm))
216
- let effects_before = unwrap_result(
217
- try? @json.parse(@moonscratch.vm_take_effects_json(vm)),
218
- "effects parse failed",
219
- )
220
- json_inspect(effects_before, content=[
221
- { "type": "ask", "question": "your name?" },
222
- ])
223
-
224
- @moonscratch.vm_post_io_json(vm, "answer", "\"moonscratch\"")
225
- ignore(@moonscratch.vm_step_frame(vm))
226
-
227
- let snapshot = unwrap_result(
228
- try? @json.parse(@moonscratch.vm_snapshot_json(vm)),
229
- "snapshot parse failed",
230
- )
231
- let root_obj = match snapshot {
232
- Object(obj) => obj
233
- _ => fail("snapshot must be object")
234
- }
235
- let targets = match root_obj["targets"] {
236
- Array(items) => items
237
- _ => fail("targets must be array")
238
- }
239
- let stage = match targets[0] {
240
- Object(obj) => obj
241
- _ => fail("stage must be object")
242
- }
243
- let vars = match stage["variables"] {
244
- Object(obj) => obj
245
- _ => fail("variables must be object")
246
- }
247
- assert_eq(vars["var_answer"], Json::string("moonscratch"))
248
- }
249
-
250
- ///|
251
- let control_project =
252
- #|{
253
- #| "targets": [
254
- #| {
255
- #| "isStage": true,
256
- #| "name": "Stage",
257
- #| "variables": {
258
- #| "var_sum": ["sum", 0],
259
- #| "var_i": ["i", 0],
260
- #| "var_counter": ["counter_result", 0]
261
- #| },
262
- #| "lists": {},
263
- #| "blocks": {}
264
- #| },
265
- #| {
266
- #| "isStage": false,
267
- #| "name": "Sprite1",
268
- #| "variables": {},
269
- #| "lists": {},
270
- #| "blocks": {
271
- #| "hat_flag": {
272
- #| "opcode": "event_whenflagclicked",
273
- #| "next": "clear_counter",
274
- #| "parent": null,
275
- #| "inputs": {},
276
- #| "fields": {},
277
- #| "topLevel": true
278
- #| },
279
- #| "clear_counter": {
280
- #| "opcode": "control_clear_counter",
281
- #| "next": "repeat_until",
282
- #| "parent": "hat_flag",
283
- #| "inputs": {},
284
- #| "fields": {},
285
- #| "topLevel": false
286
- #| },
287
- #| "repeat_until": {
288
- #| "opcode": "control_repeat_until",
289
- #| "next": "set_counter_result",
290
- #| "parent": "clear_counter",
291
- #| "inputs": {
292
- #| "CONDITION": [2, "counter_gt_2"],
293
- #| "SUBSTACK": [2, "incr_counter"]
294
- #| },
295
- #| "fields": {},
296
- #| "topLevel": false
297
- #| },
298
- #| "counter_gt_2": {
299
- #| "opcode": "operator_gt",
300
- #| "next": null,
301
- #| "parent": "repeat_until",
302
- #| "inputs": {
303
- #| "OPERAND1": [2, "counter_reporter"],
304
- #| "OPERAND2": [1, [4, 2]]
305
- #| },
306
- #| "fields": {},
307
- #| "topLevel": false
308
- #| },
309
- #| "counter_reporter": {
310
- #| "opcode": "control_get_counter",
311
- #| "next": null,
312
- #| "parent": "counter_gt_2",
313
- #| "inputs": {},
314
- #| "fields": {},
315
- #| "topLevel": false
316
- #| },
317
- #| "incr_counter": {
318
- #| "opcode": "control_incr_counter",
319
- #| "next": null,
320
- #| "parent": "repeat_until",
321
- #| "inputs": {},
322
- #| "fields": {},
323
- #| "topLevel": false
324
- #| },
325
- #| "set_counter_result": {
326
- #| "opcode": "data_setvariableto",
327
- #| "next": "for_each",
328
- #| "parent": "repeat_until",
329
- #| "inputs": {
330
- #| "VALUE": [2, "counter_reporter_after"]
331
- #| },
332
- #| "fields": {
333
- #| "VARIABLE": ["counter_result", "var_counter"]
334
- #| },
335
- #| "topLevel": false
336
- #| },
337
- #| "counter_reporter_after": {
338
- #| "opcode": "control_get_counter",
339
- #| "next": null,
340
- #| "parent": "set_counter_result",
341
- #| "inputs": {},
342
- #| "fields": {},
343
- #| "topLevel": false
344
- #| },
345
- #| "for_each": {
346
- #| "opcode": "control_for_each",
347
- #| "next": null,
348
- #| "parent": "set_counter_result",
349
- #| "inputs": {
350
- #| "VALUE": [1, [4, 3]],
351
- #| "SUBSTACK": [2, "change_sum"]
352
- #| },
353
- #| "fields": {
354
- #| "VARIABLE": ["i", "var_i"]
355
- #| },
356
- #| "topLevel": false
357
- #| },
358
- #| "change_sum": {
359
- #| "opcode": "data_changevariableby",
360
- #| "next": null,
361
- #| "parent": "for_each",
362
- #| "inputs": {
363
- #| "VALUE": [2, "i_reporter"]
364
- #| },
365
- #| "fields": {
366
- #| "VARIABLE": ["sum", "var_sum"]
367
- #| },
368
- #| "topLevel": false
369
- #| },
370
- #| "i_reporter": {
371
- #| "opcode": "data_variable",
372
- #| "next": null,
373
- #| "parent": "change_sum",
374
- #| "inputs": {},
375
- #| "fields": {
376
- #| "VARIABLE": ["i", "var_i"]
377
- #| },
378
- #| "topLevel": false
379
- #| }
380
- #| }
381
- #| }
382
- #| ]
383
- #|}
384
-
385
- ///|
386
- let clone_project =
387
- #|{
388
- #| "targets": [
389
- #| {
390
- #| "isStage": true,
391
- #| "name": "Stage",
392
- #| "variables": {
393
- #| "var_clones": ["clones", 0]
394
- #| },
395
- #| "lists": {},
396
- #| "blocks": {}
397
- #| },
398
- #| {
399
- #| "isStage": false,
400
- #| "name": "Sprite1",
401
- #| "variables": {},
402
- #| "lists": {},
403
- #| "blocks": {
404
- #| "hat_flag": {
405
- #| "opcode": "event_whenflagclicked",
406
- #| "next": "create_clone",
407
- #| "parent": null,
408
- #| "inputs": {},
409
- #| "fields": {},
410
- #| "topLevel": true
411
- #| },
412
- #| "create_clone": {
413
- #| "opcode": "control_create_clone_of",
414
- #| "next": null,
415
- #| "parent": "hat_flag",
416
- #| "inputs": {},
417
- #| "fields": {
418
- #| "CLONE_OPTION": ["_myself_", "_myself_"]
419
- #| },
420
- #| "topLevel": false
421
- #| },
422
- #| "hat_clone": {
423
- #| "opcode": "control_start_as_clone",
424
- #| "next": "inc_clones",
425
- #| "parent": null,
426
- #| "inputs": {},
427
- #| "fields": {},
428
- #| "topLevel": true
429
- #| },
430
- #| "inc_clones": {
431
- #| "opcode": "data_changevariableby",
432
- #| "next": "delete_clone",
433
- #| "parent": "hat_clone",
434
- #| "inputs": {
435
- #| "VALUE": [1, [4, 1]]
436
- #| },
437
- #| "fields": {
438
- #| "VARIABLE": ["clones", "var_clones"]
439
- #| },
440
- #| "topLevel": false
441
- #| },
442
- #| "delete_clone": {
443
- #| "opcode": "control_delete_this_clone",
444
- #| "next": null,
445
- #| "parent": "inc_clones",
446
- #| "inputs": {},
447
- #| "fields": {},
448
- #| "topLevel": false
449
- #| }
450
- #| }
451
- #| }
452
- #| ]
453
- #|}
454
-
455
- ///|
456
- let list_itemnum_project =
457
- #|{
458
- #| "targets": [
459
- #| {
460
- #| "isStage": true,
461
- #| "name": "Stage",
462
- #| "variables": {
463
- #| "var_pos": ["pos", 0]
464
- #| },
465
- #| "lists": {
466
- #| "list_numbers": ["numbers", [4, 7, "123", 9]]
467
- #| },
468
- #| "blocks": {}
469
- #| },
470
- #| {
471
- #| "isStage": false,
472
- #| "name": "Sprite1",
473
- #| "variables": {},
474
- #| "lists": {},
475
- #| "blocks": {
476
- #| "hat_flag": {
477
- #| "opcode": "event_whenflagclicked",
478
- #| "next": "set_pos",
479
- #| "parent": null,
480
- #| "inputs": {},
481
- #| "fields": {},
482
- #| "topLevel": true
483
- #| },
484
- #| "set_pos": {
485
- #| "opcode": "data_setvariableto",
486
- #| "next": null,
487
- #| "parent": "hat_flag",
488
- #| "inputs": {
489
- #| "VALUE": [2, "itemnum_reporter"]
490
- #| },
491
- #| "fields": {
492
- #| "VARIABLE": ["pos", "var_pos"]
493
- #| },
494
- #| "topLevel": false
495
- #| },
496
- #| "itemnum_reporter": {
497
- #| "opcode": "data_itemnumoflist",
498
- #| "next": null,
499
- #| "parent": "set_pos",
500
- #| "inputs": {
501
- #| "ITEM": [1, [4, 123]]
502
- #| },
503
- #| "fields": {
504
- #| "LIST": ["numbers", "list_numbers"]
505
- #| },
506
- #| "topLevel": false
507
- #| }
508
- #| }
509
- #| }
510
- #| ]
511
- #|}
512
-
513
- ///|
514
- let motion_project =
515
- #|{
516
- #| "targets": [
517
- #| {
518
- #| "isStage": true,
519
- #| "name": "Stage",
520
- #| "variables": {
521
- #| "var_dir": ["dir", 0],
522
- #| "var_x": ["xv", 0],
523
- #| "var_y": ["yv", 0]
524
- #| },
525
- #| "lists": {},
526
- #| "blocks": {}
527
- #| },
528
- #| {
529
- #| "isStage": false,
530
- #| "name": "Sprite2",
531
- #| "x": 0,
532
- #| "y": 100,
533
- #| "variables": {},
534
- #| "lists": {},
535
- #| "blocks": {}
536
- #| },
537
- #| {
538
- #| "isStage": false,
539
- #| "name": "Sprite1",
540
- #| "x": 0,
541
- #| "y": 0,
542
- #| "variables": {},
543
- #| "lists": {},
544
- #| "blocks": {
545
- #| "hat_flag": {
546
- #| "opcode": "event_whenflagclicked",
547
- #| "next": "point_towards",
548
- #| "parent": null,
549
- #| "inputs": {},
550
- #| "fields": {},
551
- #| "topLevel": true
552
- #| },
553
- #| "point_towards": {
554
- #| "opcode": "motion_pointtowards",
555
- #| "next": "set_dir",
556
- #| "parent": "hat_flag",
557
- #| "inputs": {
558
- #| "TOWARDS": [1, [10, "Sprite2"]]
559
- #| },
560
- #| "fields": {},
561
- #| "topLevel": false
562
- #| },
563
- #| "set_dir": {
564
- #| "opcode": "data_setvariableto",
565
- #| "next": "glide_xy",
566
- #| "parent": "point_towards",
567
- #| "inputs": {
568
- #| "VALUE": [2, "dir_reporter"]
569
- #| },
570
- #| "fields": {
571
- #| "VARIABLE": ["dir", "var_dir"]
572
- #| },
573
- #| "topLevel": false
574
- #| },
575
- #| "dir_reporter": {
576
- #| "opcode": "motion_direction",
577
- #| "next": null,
578
- #| "parent": "set_dir",
579
- #| "inputs": {},
580
- #| "fields": {},
581
- #| "topLevel": false
582
- #| },
583
- #| "glide_xy": {
584
- #| "opcode": "motion_glidesecstoxy",
585
- #| "next": "set_x",
586
- #| "parent": "set_dir",
587
- #| "inputs": {
588
- #| "SECS": [1, [4, 0]],
589
- #| "X": [1, [4, 50]],
590
- #| "Y": [1, [4, -20]]
591
- #| },
592
- #| "fields": {},
593
- #| "topLevel": false
594
- #| },
595
- #| "set_x": {
596
- #| "opcode": "data_setvariableto",
597
- #| "next": "set_y",
598
- #| "parent": "glide_xy",
599
- #| "inputs": {
600
- #| "VALUE": [2, "x_reporter"]
601
- #| },
602
- #| "fields": {
603
- #| "VARIABLE": ["xv", "var_x"]
604
- #| },
605
- #| "topLevel": false
606
- #| },
607
- #| "x_reporter": {
608
- #| "opcode": "motion_xposition",
609
- #| "next": null,
610
- #| "parent": "set_x",
611
- #| "inputs": {},
612
- #| "fields": {},
613
- #| "topLevel": false
614
- #| },
615
- #| "set_y": {
616
- #| "opcode": "data_setvariableto",
617
- #| "next": null,
618
- #| "parent": "set_x",
619
- #| "inputs": {
620
- #| "VALUE": [2, "y_reporter"]
621
- #| },
622
- #| "fields": {
623
- #| "VARIABLE": ["yv", "var_y"]
624
- #| },
625
- #| "topLevel": false
626
- #| },
627
- #| "y_reporter": {
628
- #| "opcode": "motion_yposition",
629
- #| "next": null,
630
- #| "parent": "set_y",
631
- #| "inputs": {},
632
- #| "fields": {},
633
- #| "topLevel": false
634
- #| }
635
- #| }
636
- #| }
637
- #| ]
638
- #|}
639
-
640
- ///|
641
- let forever_motion_project =
642
- #|{
643
- #| "targets": [
644
- #| {
645
- #| "isStage": true,
646
- #| "name": "Stage",
647
- #| "variables": {},
648
- #| "lists": {},
649
- #| "blocks": {}
650
- #| },
651
- #| {
652
- #| "isStage": false,
653
- #| "name": "Sprite1",
654
- #| "variables": {},
655
- #| "lists": {},
656
- #| "blocks": {
657
- #| "hat_flag": {
658
- #| "opcode": "event_whenflagclicked",
659
- #| "next": "forever_loop",
660
- #| "parent": null,
661
- #| "inputs": {},
662
- #| "fields": {},
663
- #| "topLevel": true
664
- #| },
665
- #| "forever_loop": {
666
- #| "opcode": "control_forever",
667
- #| "next": null,
668
- #| "parent": "hat_flag",
669
- #| "inputs": {
670
- #| "SUBSTACK": [2, "move_steps"]
671
- #| },
672
- #| "fields": {},
673
- #| "topLevel": false
674
- #| },
675
- #| "move_steps": {
676
- #| "opcode": "motion_movesteps",
677
- #| "next": null,
678
- #| "parent": "forever_loop",
679
- #| "inputs": {
680
- #| "STEPS": [1, [4, 1]]
681
- #| },
682
- #| "fields": {},
683
- #| "topLevel": false
684
- #| }
685
- #| }
686
- #| }
687
- #| ]
688
- #|}
689
-
690
- ///|
691
- test "control repeat_until, for_each and counter reporter" {
692
- let vm = unwrap_result(
693
- try? vm_new_precompiled_from_json(control_project),
694
- "vm init failed",
695
- )
696
- @moonscratch.vm_green_flag(vm)
697
-
698
- for _ in 0..<32 {
699
- ignore(@moonscratch.vm_step_frame(vm))
700
- }
701
-
702
- let snapshot = unwrap_result(
703
- try? @json.parse(@moonscratch.vm_snapshot_json(vm)),
704
- "snapshot parse failed",
705
- )
706
- let root_obj = match snapshot {
707
- Object(obj) => obj
708
- _ => fail("snapshot must be object")
709
- }
710
- let targets = match root_obj["targets"] {
711
- Array(items) => items
712
- _ => fail("targets must be array")
713
- }
714
- let stage = match targets[0] {
715
- Object(obj) => obj
716
- _ => fail("stage must be object")
717
- }
718
- let vars = match stage["variables"] {
719
- Object(obj) => obj
720
- _ => fail("variables must be object")
721
- }
722
- assert_eq(vars["var_counter"], Json::number(3.0))
723
- assert_eq(vars["var_sum"], Json::number(6.0))
724
- assert_eq(vars["var_i"], Json::number(3.0))
725
- }
726
-
727
- ///|
728
- test "control forever keeps repeating substack blocks" {
729
- let vm = unwrap_result(
730
- try? vm_new_precompiled_from_json(forever_motion_project),
731
- "vm init failed",
732
- )
733
- @moonscratch.vm_green_flag(vm)
734
-
735
- for _ in 0..<20 {
736
- ignore(@moonscratch.vm_step_frame(vm))
737
- }
738
-
739
- let snapshot = unwrap_result(
740
- try? @json.parse(@moonscratch.vm_snapshot_json(vm)),
741
- "snapshot parse failed",
742
- )
743
- let root_obj = match snapshot {
744
- Object(obj) => obj
745
- _ => fail("snapshot must be object")
746
- }
747
- let targets = match root_obj["targets"] {
748
- Array(items) => items
749
- _ => fail("targets must be array")
750
- }
751
- let sprite = match targets[1] {
752
- Object(obj) => obj
753
- _ => fail("sprite must be object")
754
- }
755
- let x = match sprite["x"] {
756
- Number(value, ..) => value
757
- _ => fail("sprite.x must be number")
758
- }
759
- assert_true(x > 19.0)
760
- }
761
-
762
- ///|
763
- test "control create clone starts control_start_as_clone hats" {
764
- let vm = unwrap_result(
765
- try? vm_new_precompiled_from_json(clone_project),
766
- "vm init failed",
767
- )
768
- @moonscratch.vm_green_flag(vm)
769
-
770
- for _ in 0..<16 {
771
- ignore(@moonscratch.vm_step_frame(vm))
772
- }
773
-
774
- let snapshot = unwrap_result(
775
- try? @json.parse(@moonscratch.vm_snapshot_json(vm)),
776
- "snapshot parse failed",
777
- )
778
- let root_obj = match snapshot {
779
- Object(obj) => obj
780
- _ => fail("snapshot must be object")
781
- }
782
- let targets = match root_obj["targets"] {
783
- Array(items) => items
784
- _ => fail("targets must be array")
785
- }
786
- let stage = match targets[0] {
787
- Object(obj) => obj
788
- _ => fail("stage must be object")
789
- }
790
- let vars = match stage["variables"] {
791
- Object(obj) => obj
792
- _ => fail("variables must be object")
793
- }
794
- assert_eq(vars["var_clones"], Json::number(1.0))
795
- }
796
-
797
- ///|
798
- test "data_itemnumoflist uses scratch-style equality" {
799
- let vm = unwrap_result(
800
- try? vm_new_precompiled_from_json(list_itemnum_project),
801
- "vm init failed",
802
- )
803
- @moonscratch.vm_green_flag(vm)
804
- for _ in 0..<8 {
805
- ignore(@moonscratch.vm_step_frame(vm))
806
- }
807
-
808
- let snapshot = unwrap_result(
809
- try? @json.parse(@moonscratch.vm_snapshot_json(vm)),
810
- "snapshot parse failed",
811
- )
812
- let root_obj = match snapshot {
813
- Object(obj) => obj
814
- _ => fail("snapshot must be object")
815
- }
816
- let targets = match root_obj["targets"] {
817
- Array(items) => items
818
- _ => fail("targets must be array")
819
- }
820
- let stage = match targets[0] {
821
- Object(obj) => obj
822
- _ => fail("stage must be object")
823
- }
824
- let vars = match stage["variables"] {
825
- Object(obj) => obj
826
- _ => fail("variables must be object")
827
- }
828
- assert_eq(vars["var_pos"], Json::number(3.0))
829
- }
830
-
831
- ///|
832
- test "motion reporters and target-based motion commands" {
833
- let vm = unwrap_result(
834
- try? vm_new_precompiled_from_json(motion_project),
835
- "vm init failed",
836
- )
837
- @moonscratch.vm_green_flag(vm)
838
- for _ in 0..<12 {
839
- ignore(@moonscratch.vm_step_frame(vm))
840
- }
841
-
842
- let snapshot = unwrap_result(
843
- try? @json.parse(@moonscratch.vm_snapshot_json(vm)),
844
- "snapshot parse failed",
845
- )
846
- let root_obj = match snapshot {
847
- Object(obj) => obj
848
- _ => fail("snapshot must be object")
849
- }
850
- let targets = match root_obj["targets"] {
851
- Array(items) => items
852
- _ => fail("targets must be array")
853
- }
854
- let stage = match targets[0] {
855
- Object(obj) => obj
856
- _ => fail("stage must be object")
857
- }
858
- let vars = match stage["variables"] {
859
- Object(obj) => obj
860
- _ => fail("variables must be object")
861
- }
862
- assert_eq(vars["var_dir"], Json::number(0.0))
863
- assert_eq(vars["var_x"], Json::number(50.0))
864
- assert_eq(vars["var_y"], Json::number(-20.0))
865
- }
866
-
867
- ///|
868
- let looks_project =
869
- #|{
870
- #| "targets": [
871
- #| {
872
- #| "isStage": true,
873
- #| "name": "Stage",
874
- #| "currentCostume": 0,
875
- #| "costumes": [
876
- #| { "name": "bg1" },
877
- #| { "name": "bg2" },
878
- #| { "name": "bg3" }
879
- #| ],
880
- #| "variables": {
881
- #| "var_cn": ["costume_name", ""],
882
- #| "var_cnum": ["costume_num", 0],
883
- #| "var_bn": ["backdrop_name", ""],
884
- #| "var_bnum": ["backdrop_num", 0],
885
- #| "var_size": ["size_value", 0]
886
- #| },
887
- #| "lists": {},
888
- #| "blocks": {}
889
- #| },
890
- #| {
891
- #| "isStage": false,
892
- #| "name": "Sprite1",
893
- #| "currentCostume": 0,
894
- #| "costumes": [
895
- #| { "name": "a" },
896
- #| { "name": "b" }
897
- #| ],
898
- #| "variables": {},
899
- #| "lists": {},
900
- #| "blocks": {
901
- #| "hat_flag": {
902
- #| "opcode": "event_whenflagclicked",
903
- #| "next": "switch_costume",
904
- #| "parent": null,
905
- #| "inputs": {},
906
- #| "fields": {},
907
- #| "topLevel": true
908
- #| },
909
- #| "switch_costume": {
910
- #| "opcode": "looks_switchcostumeto",
911
- #| "next": "set_costume_name",
912
- #| "parent": "hat_flag",
913
- #| "inputs": {
914
- #| "COSTUME": [1, [10, "b"]]
915
- #| },
916
- #| "fields": {},
917
- #| "topLevel": false
918
- #| },
919
- #| "set_costume_name": {
920
- #| "opcode": "data_setvariableto",
921
- #| "next": "set_costume_num",
922
- #| "parent": "switch_costume",
923
- #| "inputs": {
924
- #| "VALUE": [2, "costume_name_reporter"]
925
- #| },
926
- #| "fields": {
927
- #| "VARIABLE": ["costume_name", "var_cn"]
928
- #| },
929
- #| "topLevel": false
930
- #| },
931
- #| "costume_name_reporter": {
932
- #| "opcode": "looks_costumenumbername",
933
- #| "next": null,
934
- #| "parent": "set_costume_name",
935
- #| "inputs": {},
936
- #| "fields": {
937
- #| "NUMBER_NAME": ["name", null]
938
- #| },
939
- #| "topLevel": false
940
- #| },
941
- #| "set_costume_num": {
942
- #| "opcode": "data_setvariableto",
943
- #| "next": "set_size",
944
- #| "parent": "set_costume_name",
945
- #| "inputs": {
946
- #| "VALUE": [2, "costume_num_reporter"]
947
- #| },
948
- #| "fields": {
949
- #| "VARIABLE": ["costume_num", "var_cnum"]
950
- #| },
951
- #| "topLevel": false
952
- #| },
953
- #| "costume_num_reporter": {
954
- #| "opcode": "looks_costumenumbername",
955
- #| "next": null,
956
- #| "parent": "set_costume_num",
957
- #| "inputs": {},
958
- #| "fields": {
959
- #| "NUMBER_NAME": ["number", null]
960
- #| },
961
- #| "topLevel": false
962
- #| },
963
- #| "set_size": {
964
- #| "opcode": "looks_setsizeto",
965
- #| "next": "set_size_var",
966
- #| "parent": "set_costume_num",
967
- #| "inputs": {
968
- #| "SIZE": [1, [4, 80]]
969
- #| },
970
- #| "fields": {},
971
- #| "topLevel": false
972
- #| },
973
- #| "set_size_var": {
974
- #| "opcode": "data_setvariableto",
975
- #| "next": "switch_backdrop",
976
- #| "parent": "set_size",
977
- #| "inputs": {
978
- #| "VALUE": [2, "size_reporter"]
979
- #| },
980
- #| "fields": {
981
- #| "VARIABLE": ["size_value", "var_size"]
982
- #| },
983
- #| "topLevel": false
984
- #| },
985
- #| "size_reporter": {
986
- #| "opcode": "looks_size",
987
- #| "next": null,
988
- #| "parent": "set_size_var",
989
- #| "inputs": {},
990
- #| "fields": {},
991
- #| "topLevel": false
992
- #| },
993
- #| "switch_backdrop": {
994
- #| "opcode": "looks_switchbackdropto",
995
- #| "next": "next_backdrop",
996
- #| "parent": "set_size_var",
997
- #| "inputs": {},
998
- #| "fields": {
999
- #| "BACKDROP": ["bg2", null]
1000
- #| },
1001
- #| "topLevel": false
1002
- #| },
1003
- #| "next_backdrop": {
1004
- #| "opcode": "looks_nextbackdrop",
1005
- #| "next": "set_backdrop_name",
1006
- #| "parent": "switch_backdrop",
1007
- #| "inputs": {},
1008
- #| "fields": {},
1009
- #| "topLevel": false
1010
- #| },
1011
- #| "set_backdrop_name": {
1012
- #| "opcode": "data_setvariableto",
1013
- #| "next": "set_backdrop_num",
1014
- #| "parent": "next_backdrop",
1015
- #| "inputs": {
1016
- #| "VALUE": [2, "backdrop_name_reporter"]
1017
- #| },
1018
- #| "fields": {
1019
- #| "VARIABLE": ["backdrop_name", "var_bn"]
1020
- #| },
1021
- #| "topLevel": false
1022
- #| },
1023
- #| "backdrop_name_reporter": {
1024
- #| "opcode": "looks_backdropnumbername",
1025
- #| "next": null,
1026
- #| "parent": "set_backdrop_name",
1027
- #| "inputs": {},
1028
- #| "fields": {
1029
- #| "NUMBER_NAME": ["name", null]
1030
- #| },
1031
- #| "topLevel": false
1032
- #| },
1033
- #| "set_backdrop_num": {
1034
- #| "opcode": "data_setvariableto",
1035
- #| "next": "hide_all",
1036
- #| "parent": "set_backdrop_name",
1037
- #| "inputs": {
1038
- #| "VALUE": [2, "backdrop_num_reporter"]
1039
- #| },
1040
- #| "fields": {
1041
- #| "VARIABLE": ["backdrop_num", "var_bnum"]
1042
- #| },
1043
- #| "topLevel": false
1044
- #| },
1045
- #| "backdrop_num_reporter": {
1046
- #| "opcode": "looks_backdropnumbername",
1047
- #| "next": null,
1048
- #| "parent": "set_backdrop_num",
1049
- #| "inputs": {},
1050
- #| "fields": {
1051
- #| "NUMBER_NAME": ["number", null]
1052
- #| },
1053
- #| "topLevel": false
1054
- #| },
1055
- #| "hide_all": {
1056
- #| "opcode": "looks_hideallsprites",
1057
- #| "next": null,
1058
- #| "parent": "set_backdrop_num",
1059
- #| "inputs": {},
1060
- #| "fields": {},
1061
- #| "topLevel": false
1062
- #| }
1063
- #| }
1064
- #| }
1065
- #| ]
1066
- #|}
1067
-
1068
- ///|
1069
- let event_project =
1070
- #|{
1071
- #| "targets": [
1072
- #| {
1073
- #| "isStage": true,
1074
- #| "name": "Stage",
1075
- #| "currentCostume": 0,
1076
- #| "costumes": [
1077
- #| { "name": "bg1" },
1078
- #| { "name": "bg2" }
1079
- #| ],
1080
- #| "variables": {
1081
- #| "var_total": ["total", 0]
1082
- #| },
1083
- #| "lists": {},
1084
- #| "blocks": {
1085
- #| "hat_flag": {
1086
- #| "opcode": "event_whenflagclicked",
1087
- #| "next": "switch_bg2",
1088
- #| "parent": null,
1089
- #| "inputs": {},
1090
- #| "fields": {},
1091
- #| "topLevel": true
1092
- #| },
1093
- #| "switch_bg2": {
1094
- #| "opcode": "looks_switchbackdropto",
1095
- #| "next": null,
1096
- #| "parent": "hat_flag",
1097
- #| "inputs": {},
1098
- #| "fields": {
1099
- #| "BACKDROP": ["bg2", null]
1100
- #| },
1101
- #| "topLevel": false
1102
- #| },
1103
- #| "hat_backdrop": {
1104
- #| "opcode": "event_whenbackdropswitchesto",
1105
- #| "next": "add_1",
1106
- #| "parent": null,
1107
- #| "inputs": {},
1108
- #| "fields": {
1109
- #| "BACKDROP": ["bg2", null]
1110
- #| },
1111
- #| "topLevel": true
1112
- #| },
1113
- #| "add_1": {
1114
- #| "opcode": "data_changevariableby",
1115
- #| "next": null,
1116
- #| "parent": "hat_backdrop",
1117
- #| "inputs": {
1118
- #| "VALUE": [1, [4, 1]]
1119
- #| },
1120
- #| "fields": {
1121
- #| "VARIABLE": ["total", "var_total"]
1122
- #| },
1123
- #| "topLevel": false
1124
- #| },
1125
- #| "hat_stage_click": {
1126
- #| "opcode": "event_whenstageclicked",
1127
- #| "next": "add_10",
1128
- #| "parent": null,
1129
- #| "inputs": {},
1130
- #| "fields": {},
1131
- #| "topLevel": true
1132
- #| },
1133
- #| "add_10": {
1134
- #| "opcode": "data_changevariableby",
1135
- #| "next": null,
1136
- #| "parent": "hat_stage_click",
1137
- #| "inputs": {
1138
- #| "VALUE": [1, [4, 10]]
1139
- #| },
1140
- #| "fields": {
1141
- #| "VARIABLE": ["total", "var_total"]
1142
- #| },
1143
- #| "topLevel": false
1144
- #| }
1145
- #| }
1146
- #| },
1147
- #| {
1148
- #| "isStage": false,
1149
- #| "name": "Sprite1",
1150
- #| "variables": {},
1151
- #| "lists": {},
1152
- #| "blocks": {
1153
- #| "hat_key": {
1154
- #| "opcode": "event_whenkeypressed",
1155
- #| "next": "add_100",
1156
- #| "parent": null,
1157
- #| "inputs": {},
1158
- #| "fields": {
1159
- #| "KEY_OPTION": ["space", "space"]
1160
- #| },
1161
- #| "topLevel": true
1162
- #| },
1163
- #| "add_100": {
1164
- #| "opcode": "data_changevariableby",
1165
- #| "next": null,
1166
- #| "parent": "hat_key",
1167
- #| "inputs": {
1168
- #| "VALUE": [1, [4, 100]]
1169
- #| },
1170
- #| "fields": {
1171
- #| "VARIABLE": ["total", "var_total"]
1172
- #| },
1173
- #| "topLevel": false
1174
- #| },
1175
- #| "hat_sprite_click": {
1176
- #| "opcode": "event_whenthisspriteclicked",
1177
- #| "next": "add_1000",
1178
- #| "parent": null,
1179
- #| "inputs": {},
1180
- #| "fields": {},
1181
- #| "topLevel": true
1182
- #| },
1183
- #| "add_1000": {
1184
- #| "opcode": "data_changevariableby",
1185
- #| "next": null,
1186
- #| "parent": "hat_sprite_click",
1187
- #| "inputs": {
1188
- #| "VALUE": [1, [4, 1000]]
1189
- #| },
1190
- #| "fields": {
1191
- #| "VARIABLE": ["total", "var_total"]
1192
- #| },
1193
- #| "topLevel": false
1194
- #| },
1195
- #| "hat_timer": {
1196
- #| "opcode": "event_whengreaterthan",
1197
- #| "next": "add_10000",
1198
- #| "parent": null,
1199
- #| "inputs": {
1200
- #| "VALUE": [1, [4, 0.05]]
1201
- #| },
1202
- #| "fields": {
1203
- #| "WHENGREATERTHANMENU": ["TIMER", null]
1204
- #| },
1205
- #| "topLevel": true
1206
- #| },
1207
- #| "add_10000": {
1208
- #| "opcode": "data_changevariableby",
1209
- #| "next": null,
1210
- #| "parent": "hat_timer",
1211
- #| "inputs": {
1212
- #| "VALUE": [1, [4, 10000]]
1213
- #| },
1214
- #| "fields": {
1215
- #| "VARIABLE": ["total", "var_total"]
1216
- #| },
1217
- #| "topLevel": false
1218
- #| },
1219
- #| "hat_touch": {
1220
- #| "opcode": "event_whentouchingobject",
1221
- #| "next": "add_100000",
1222
- #| "parent": null,
1223
- #| "inputs": {},
1224
- #| "fields": {
1225
- #| "TOUCHINGOBJECTMENU": ["_mouse_", null]
1226
- #| },
1227
- #| "topLevel": true
1228
- #| },
1229
- #| "add_100000": {
1230
- #| "opcode": "data_changevariableby",
1231
- #| "next": null,
1232
- #| "parent": "hat_touch",
1233
- #| "inputs": {
1234
- #| "VALUE": [1, [4, 100000]]
1235
- #| },
1236
- #| "fields": {
1237
- #| "VARIABLE": ["total", "var_total"]
1238
- #| },
1239
- #| "topLevel": false
1240
- #| }
1241
- #| }
1242
- #| }
1243
- #| ]
1244
- #|}
1245
-
1246
- ///|
1247
- test "looks reporters and backdrop opcodes update state" {
1248
- let vm = unwrap_result(
1249
- try? vm_new_precompiled_from_json(looks_project),
1250
- "vm init failed",
1251
- )
1252
- @moonscratch.vm_green_flag(vm)
1253
- for _ in 0..<20 {
1254
- ignore(@moonscratch.vm_step_frame(vm))
1255
- }
1256
-
1257
- let snapshot = unwrap_result(
1258
- try? @json.parse(@moonscratch.vm_snapshot_json(vm)),
1259
- "snapshot parse failed",
1260
- )
1261
- let root_obj = match snapshot {
1262
- Object(obj) => obj
1263
- _ => fail("snapshot must be object")
1264
- }
1265
- let targets = match root_obj["targets"] {
1266
- Array(items) => items
1267
- _ => fail("targets must be array")
1268
- }
1269
- let stage = match targets[0] {
1270
- Object(obj) => obj
1271
- _ => fail("stage must be object")
1272
- }
1273
- let sprite = match targets[1] {
1274
- Object(obj) => obj
1275
- _ => fail("sprite must be object")
1276
- }
1277
- let vars = match stage["variables"] {
1278
- Object(obj) => obj
1279
- _ => fail("variables must be object")
1280
- }
1281
- assert_eq(vars["var_cn"], Json::string("b"))
1282
- assert_eq(vars["var_cnum"], Json::number(2.0))
1283
- assert_eq(vars["var_bn"], Json::string("bg3"))
1284
- assert_eq(vars["var_bnum"], Json::number(3.0))
1285
- assert_eq(vars["var_size"], Json::number(80.0))
1286
- assert_eq(sprite["visible"], Json::boolean(false))
1287
- }
1288
-
1289
- ///|
1290
- test "event hats for key, click, backdrop, greaterthan and touchingobject" {
1291
- let vm = unwrap_result(
1292
- try? vm_new_precompiled_from_json(event_project),
1293
- "vm init failed",
1294
- )
1295
- @moonscratch.vm_green_flag(vm)
1296
-
1297
- @moonscratch.vm_post_io_json(vm, "keys_down", "[\"space\"]")
1298
- @moonscratch.vm_post_io_json(vm, "mouse", "{\"x\":0,\"y\":0,\"isDown\":true}")
1299
- @moonscratch.vm_post_io_json(
1300
- vm, "mouse_targets", "{\"stage\":true,\"targets\":[\"Sprite1\"]}",
1301
- )
1302
- @moonscratch.vm_post_io_json(vm, "touching", "{\"Sprite1\":[\"_mouse_\"]}")
1303
-
1304
- let mut now_ms = 0
1305
- for _ in 0..<24 {
1306
- now_ms += 16
1307
- @moonscratch.vm_set_time(vm, now_ms)
1308
- ignore(@moonscratch.vm_step_frame(vm))
1309
- }
1310
-
1311
- let snapshot = unwrap_result(
1312
- try? @json.parse(@moonscratch.vm_snapshot_json(vm)),
1313
- "snapshot parse failed",
1314
- )
1315
- let root_obj = match snapshot {
1316
- Object(obj) => obj
1317
- _ => fail("snapshot must be object")
1318
- }
1319
- let targets = match root_obj["targets"] {
1320
- Array(items) => items
1321
- _ => fail("targets must be array")
1322
- }
1323
- let stage = match targets[0] {
1324
- Object(obj) => obj
1325
- _ => fail("stage must be object")
1326
- }
1327
- let vars = match stage["variables"] {
1328
- Object(obj) => obj
1329
- _ => fail("variables must be object")
1330
- }
1331
- assert_eq(vars["var_total"], Json::number(111111.0))
1332
- }