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,18 +0,0 @@
1
- import type { JsonValue } from './types.ts'
2
-
3
- export const isObjectRecord = (
4
- value: unknown,
5
- ): value is Record<string, JsonValue | unknown> =>
6
- typeof value === 'object' && value !== null && !Array.isArray(value)
7
-
8
- export const hasStringField = (
9
- value: unknown,
10
- key: string,
11
- ): value is { [k: string]: string } =>
12
- isObjectRecord(value) && typeof value[key] === 'string'
13
-
14
- export const hasNumberField = (
15
- value: unknown,
16
- key: string,
17
- ): value is { [k: string]: number } =>
18
- isObjectRecord(value) && typeof value[key] === 'number'
package/moon.mod.json DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "name": "nakasyou/moonscratch",
3
- "version": "0.1.0",
4
- "source": "src",
5
- "readme": "README.mbt.md",
6
- "repository": "",
7
- "license": "Apache-2.0",
8
- "keywords": [],
9
- "description": ""
10
- }
@@ -1,4 +0,0 @@
1
- await Bun.write(
2
- './node_modules/@scratch/scratch-vm/browser/default-stylesheet.css',
3
- '',
4
- )
package/src/AGENTS.md DELETED
@@ -1,6 +0,0 @@
1
- # src
2
-
3
- - This is the core MoonBit implementation package.
4
- - Keep tests in `src/` limited to unit tests.
5
- - Add macro-level behavior checks under `src/test/projects/`.
6
- - When public API changes are involved, always inspect `.mbti` diffs after running `moon info`.
package/src/api.mbt DELETED
@@ -1,161 +0,0 @@
1
- ///|
2
- pub fn vm_compile_from_json(
3
- project_json : String,
4
- assets_json? : String,
5
- ) -> PrecompiledProject raise VmError {
6
- let bundle = parse_bundle(project_json, assets_json)
7
- compile_project(bundle)
8
- }
9
-
10
- ///|
11
- pub fn vm_new_from_compiled(
12
- precompiled : PrecompiledProject,
13
- options_json? : String,
14
- ) -> Vm raise VmError {
15
- let options = parse_options_json(options_json)
16
- vm_new_internal(precompiled, options)
17
- }
18
-
19
- ///|
20
- pub fn vm_start(vm : Vm) -> Unit {
21
- start_vm_runtime(vm)
22
- }
23
-
24
- ///|
25
- pub fn vm_green_flag(vm : Vm) -> Unit {
26
- green_flag_runtime(vm)
27
- }
28
-
29
- ///|
30
- pub fn vm_step_frame(vm : Vm) -> FrameReport {
31
- step_frame_runtime(vm)
32
- }
33
-
34
- ///|
35
- pub fn vm_set_time(vm : Vm, now_ms : Int) -> Unit {
36
- set_time_runtime(vm, now_ms)
37
- }
38
-
39
- ///|
40
- pub fn vm_post_io_json(vm : Vm, device : String, payload_json : String) -> Unit {
41
- post_io_json_runtime(vm, device, payload_json)
42
- }
43
-
44
- ///|
45
- pub fn vm_set_aot_commands_json(
46
- vm : Vm,
47
- commands_json : String,
48
- ) -> Unit raise VmError {
49
- set_aot_commands_runtime(vm, commands_json)
50
- }
51
-
52
- ///|
53
- pub fn vm_get_variable_number_by_id(
54
- vm : Vm,
55
- target_index : Int,
56
- variable_id : String,
57
- ) -> Double {
58
- if variable_id == "" {
59
- return 0.0
60
- }
61
- if target_index < 0 || target_index >= vm.targets.length() {
62
- return 0.0
63
- }
64
- let current = read_variable(vm, target_index, Some(variable_id), None)
65
- json_to_number_value(current)
66
- }
67
-
68
- ///|
69
- pub fn vm_set_variable_number_by_id(
70
- vm : Vm,
71
- target_index : Int,
72
- variable_id : String,
73
- value : Double,
74
- ) -> Unit {
75
- if variable_id == "" {
76
- return
77
- }
78
- if target_index < 0 || target_index >= vm.targets.length() {
79
- return
80
- }
81
- write_variable(vm, target_index, Some(variable_id), None, json_number(value))
82
- }
83
-
84
- ///|
85
- pub fn vm_set_variable_json_by_id(
86
- vm : Vm,
87
- target_index : Int,
88
- variable_id : String,
89
- value_json : String,
90
- ) -> Unit {
91
- if variable_id == "" {
92
- return
93
- }
94
- if target_index < 0 || target_index >= vm.targets.length() {
95
- return
96
- }
97
- if value_json.trim().is_empty() {
98
- write_variable(vm, target_index, Some(variable_id), None, Json::null())
99
- return
100
- }
101
- let parsed = try? @json.parse(value_json)
102
- match parsed {
103
- Ok(value) =>
104
- write_variable(vm, target_index, Some(variable_id), None, value)
105
- Err(_) =>
106
- write_variable(vm, target_index, Some(variable_id), None, Json::null())
107
- }
108
- }
109
-
110
- ///|
111
- pub fn vm_exec_script_tail_by_pc(
112
- vm : Vm,
113
- target_index : Int,
114
- start_pc : Int,
115
- ) -> Int {
116
- exec_script_tail_runtime(vm, target_index, start_pc)
117
- }
118
-
119
- ///|
120
- pub fn vm_exec_opcode_once_by_pc(vm : Vm, target_index : Int, pc : Int) -> Int {
121
- exec_opcode_once_runtime(vm, target_index, pc)
122
- }
123
-
124
- ///|
125
- pub fn vm_exec_draw_opcode(
126
- vm : Vm,
127
- target_index : Int,
128
- opcode : String,
129
- arg0 : Double,
130
- arg1 : Double,
131
- extra : Int,
132
- ) -> Int {
133
- exec_draw_opcode_runtime(vm, target_index, opcode, arg0, arg1, extra)
134
- }
135
-
136
- ///|
137
- pub fn vm_broadcast(vm : Vm, message : String) -> Unit {
138
- broadcast_runtime(vm, message)
139
- }
140
-
141
- ///|
142
- pub fn vm_stop_all(vm : Vm) -> Unit {
143
- clear_threads(vm)
144
- push_effect(vm, HostEffect::StopAllSounds)
145
- }
146
-
147
- ///|
148
- pub fn vm_take_effects_json(vm : Vm) -> String {
149
- let effects = take_effects(vm).map(effect_to_json)
150
- json_array(effects).stringify()
151
- }
152
-
153
- ///|
154
- pub fn vm_snapshot_json(vm : Vm) -> String {
155
- snapshot_to_json(vm).stringify(indent=2)
156
- }
157
-
158
- ///|
159
- pub fn vm_render_frame(vm : Vm) -> RenderFrame {
160
- render_scene_to_frame(vm)
161
- }
@@ -1,184 +0,0 @@
1
- ///|
2
- fn parse_aot_command(raw : Json, index : Int) -> AotCommand? raise VmError {
3
- let obj = expect_object(raw, "aot_commands[\{index}]")
4
- let op = object_get_string_or(obj, "op", "")
5
- match op {
6
- "set_var" => {
7
- let target_index = object_get_number_or(obj, "target", -1.0).to_int()
8
- if target_index < 0 {
9
- invalid_project("aot_commands[\{index}].target must be >= 0")
10
- }
11
- let variable_id = object_get_string_or(obj, "id", "")
12
- if variable_id == "" {
13
- invalid_project("aot_commands[\{index}].id must be non-empty")
14
- }
15
- let value = object_get_or(obj, "value", Json::null())
16
- Some(AotCommand::SetVariable(target_index, variable_id, value))
17
- }
18
- "change_var" => {
19
- let target_index = object_get_number_or(obj, "target", -1.0).to_int()
20
- if target_index < 0 {
21
- invalid_project("aot_commands[\{index}].target must be >= 0")
22
- }
23
- let variable_id = object_get_string_or(obj, "id", "")
24
- if variable_id == "" {
25
- invalid_project("aot_commands[\{index}].id must be non-empty")
26
- }
27
- let delta = object_get_number_or(obj, "delta", 0.0)
28
- Some(AotCommand::ChangeVariable(target_index, variable_id, delta))
29
- }
30
- "host_tail" => {
31
- let target_index = object_get_number_or(obj, "target", -1.0).to_int()
32
- if target_index < 0 {
33
- invalid_project("aot_commands[\{index}].target must be >= 0")
34
- }
35
- let start_pc = object_get_number_or(obj, "pc", -1.0).to_int()
36
- if start_pc < 0 {
37
- invalid_project("aot_commands[\{index}].pc must be >= 0")
38
- }
39
- Some(AotCommand::HostTail(target_index, start_pc))
40
- }
41
- "host_opcode" => {
42
- let target_index = object_get_number_or(obj, "target", -1.0).to_int()
43
- if target_index < 0 {
44
- invalid_project("aot_commands[\{index}].target must be >= 0")
45
- }
46
- let pc = object_get_number_or(obj, "pc", -1.0).to_int()
47
- if pc < 0 {
48
- invalid_project("aot_commands[\{index}].pc must be >= 0")
49
- }
50
- Some(AotCommand::HostOpcode(target_index, pc))
51
- }
52
- _ => None
53
- }
54
- }
55
-
56
- ///|
57
- fn parse_aot_exec_commands(parsed : Json) -> Array[AotCommand] raise VmError {
58
- let commands = match parsed {
59
- Array(values) => values
60
- Object(obj) =>
61
- match obj.get("exec") {
62
- Some(raw_exec) => expect_array(raw_exec, "aot_commands.exec")
63
- None => []
64
- }
65
- _ => expect_array(parsed, "aot_commands")
66
- }
67
- let out = []
68
- for index, command in commands {
69
- match parse_aot_command(command, index) {
70
- Some(parsed) => out.push(parsed)
71
- None => ()
72
- }
73
- }
74
- out
75
- }
76
-
77
- ///|
78
- fn parse_aot_full_green_flag_start_entries(
79
- raw : Json,
80
- ) -> (Map[Int, Array[Int]], Bool) raise VmError {
81
- let entries = expect_array(raw, "aot_commands.full_green_flag_starts")
82
- let out : Map[Int, Array[Int]] = {}
83
- let mut has_any_start = false
84
- for entry_index, raw_entry in entries {
85
- let entry = expect_object(
86
- raw_entry,
87
- "aot_commands.full_green_flag_starts[\{entry_index}]",
88
- )
89
- let target_index = object_get_number_or(entry, "target", -1.0).to_int()
90
- if target_index < 0 {
91
- invalid_project(
92
- "aot_commands.full_green_flag_starts[\{entry_index}].target must be >= 0",
93
- )
94
- }
95
- let pcs_json = expect_array(
96
- object_get_or(entry, "pcs", json_array([])),
97
- "aot_commands.full_green_flag_starts[\{entry_index}].pcs",
98
- )
99
- let merged = match out.get(target_index) {
100
- Some(existing) => existing.copy()
101
- None => []
102
- }
103
- for pc_index, raw_pc in pcs_json {
104
- let pc = json_to_number_value(raw_pc).to_int()
105
- if pc < 0 {
106
- invalid_project(
107
- "aot_commands.full_green_flag_starts[\{entry_index}].pcs[\{pc_index}] must be >= 0",
108
- )
109
- }
110
- merged.push(pc)
111
- has_any_start = true
112
- }
113
- out[target_index] = merged
114
- }
115
- (out, has_any_start)
116
- }
117
-
118
- ///|
119
- fn parse_aot_full_green_flag_starts(
120
- parsed : Json,
121
- ) -> (Map[Int, Array[Int]], Bool) raise VmError {
122
- match parsed {
123
- Object(obj) =>
124
- match obj.get("full_green_flag_starts") {
125
- Some(raw) => parse_aot_full_green_flag_start_entries(raw)
126
- None => ({}, false)
127
- }
128
- _ => ({}, false)
129
- }
130
- }
131
-
132
- ///|
133
- fn parse_aot_exec_mode(parsed : Json, has_any_start : Bool) -> (Bool, Bool) {
134
- match parsed {
135
- Object(obj) =>
136
- match obj.get("exec_mode") {
137
- Some(String(raw_mode)) => {
138
- let mode = raw_mode.trim().to_lower()
139
- if mode == "full" || mode == "wasm" || mode == "wasm_full" {
140
- (true, false)
141
- } else if mode == "wasm_only" {
142
- (false, true)
143
- } else if mode == "linear" || mode == "linear_fast" {
144
- (false, false)
145
- } else {
146
- (has_any_start, false)
147
- }
148
- }
149
- _ => (has_any_start, false)
150
- }
151
- _ => (false, false)
152
- }
153
- }
154
-
155
- ///|
156
- fn parse_aot_commands_json(
157
- commands_json : String,
158
- ) -> (Array[AotCommand], Map[Int, Array[Int]], Bool, Bool) raise VmError {
159
- if commands_json.trim().is_empty() {
160
- return ([], {}, false, false)
161
- }
162
- let parsed = parse_json_or_fail(commands_json)
163
- let commands = parse_aot_exec_commands(parsed)
164
- let (full_green_flag_starts, has_any_start) = parse_aot_full_green_flag_starts(
165
- parsed,
166
- )
167
- let (use_full_exec, wasm_only) = parse_aot_exec_mode(parsed, has_any_start)
168
- (commands, full_green_flag_starts, use_full_exec, wasm_only)
169
- }
170
-
171
- ///|
172
- fn set_aot_commands_runtime(
173
- vm : Vm,
174
- commands_json : String,
175
- ) -> Unit raise VmError {
176
- let (commands, full_green_flag_starts, use_full_exec, wasm_only) = parse_aot_commands_json(
177
- commands_json,
178
- )
179
- vm.aot_commands = commands
180
- vm.aot_full_green_flag_starts = full_green_flag_starts
181
- vm.aot_use_full_exec = use_full_exec
182
- vm.aot_wasm_only = wasm_only
183
- vm.aot_pending = false
184
- }
@@ -1,72 +0,0 @@
1
- ///|
2
- fn effect_to_json(effect : HostEffect) -> Json {
3
- match effect {
4
- PlaySound(target, sound) =>
5
- json_object({
6
- "type": json_string("play_sound"),
7
- "target": json_string(target),
8
- "sound": json_string(sound),
9
- })
10
- PlayNote(target, note, beats, instrument, tempo) =>
11
- json_object({
12
- "type": json_string("music_play_note"),
13
- "target": json_string(target),
14
- "note": json_number(Double::from_int(note)),
15
- "beats": json_number(beats),
16
- "instrument": json_number(Double::from_int(instrument)),
17
- "tempo": json_number(tempo),
18
- })
19
- PlayDrum(target, drum, beats, tempo) =>
20
- json_object({
21
- "type": json_string("music_play_drum"),
22
- "target": json_string(target),
23
- "drum": json_number(Double::from_int(drum)),
24
- "beats": json_number(beats),
25
- "tempo": json_number(tempo),
26
- })
27
- TextToSpeech(target, words, voice, language, wait_key) =>
28
- json_object({
29
- "type": json_string("text_to_speech"),
30
- "target": json_string(target),
31
- "words": json_string(words),
32
- "voice": json_string(voice),
33
- "language": json_string(language),
34
- "waitKey": json_string(wait_key),
35
- })
36
- TranslateRequest(words, language) =>
37
- json_object({
38
- "type": json_string("translate_request"),
39
- "words": json_string(words),
40
- "language": json_string(language),
41
- })
42
- StopAllSounds => json_object({ "type": json_string("stop_all_sounds") })
43
- Say(target, message) =>
44
- json_object({
45
- "type": json_string("say"),
46
- "target": json_string(target),
47
- "message": json_string(message),
48
- })
49
- Think(target, message) =>
50
- json_object({
51
- "type": json_string("think"),
52
- "target": json_string(target),
53
- "message": json_string(message),
54
- })
55
- Ask(question) =>
56
- json_object({
57
- "type": json_string("ask"),
58
- "question": json_string(question),
59
- })
60
- Broadcast(message) =>
61
- json_object({
62
- "type": json_string("broadcast"),
63
- "message": json_string(message),
64
- })
65
- Log(level, message) =>
66
- json_object({
67
- "type": json_string("log"),
68
- "level": json_string(level),
69
- "message": json_string(message),
70
- })
71
- }
72
- }
@@ -1,60 +0,0 @@
1
- ///|
2
- fn parse_options_json(options_json : String?) -> VmOptions raise VmError {
3
- let options = default_vm_options()
4
- match options_json {
5
- Some(raw) => {
6
- if raw.trim().is_empty() {
7
- return options
8
- }
9
- let parsed = parse_json_or_fail(raw)
10
- let obj = expect_object(parsed, "options")
11
- options.turbo = object_get_bool_or(obj, "turbo", options.turbo)
12
- options.compatibility_30tps = object_get_bool_or(
13
- obj,
14
- "compatibility_30tps",
15
- options.compatibility_30tps,
16
- )
17
- options.max_clones = object_get_number_or(
18
- obj,
19
- "max_clones",
20
- Double::from_int(options.max_clones),
21
- ).to_int()
22
- options.deterministic = object_get_bool_or(
23
- obj,
24
- "deterministic",
25
- options.deterministic,
26
- )
27
- options.seed = object_get_number_or(
28
- obj,
29
- "seed",
30
- Double::from_int(options.seed),
31
- ).to_int()
32
- options.pen_width = object_get_number_or(
33
- obj,
34
- "pen_width",
35
- Double::from_int(options.pen_width),
36
- ).to_int()
37
- options.pen_height = object_get_number_or(
38
- obj,
39
- "pen_height",
40
- Double::from_int(options.pen_height),
41
- ).to_int()
42
- options.step_timeout_ticks = object_get_number_or(
43
- obj,
44
- "step_timeout_ticks",
45
- Double::from_int(options.step_timeout_ticks),
46
- ).to_int()
47
- if options.pen_width <= 0 {
48
- options.pen_width = 480
49
- }
50
- if options.pen_height <= 0 {
51
- options.pen_height = 360
52
- }
53
- if options.step_timeout_ticks <= 0 {
54
- options.step_timeout_ticks = 2048
55
- }
56
- options
57
- }
58
- None => options
59
- }
60
- }