mt-lang 0.2.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/docs/index.html +4 -3
- data/lib/milk_tea/base.rb +1 -1
- data/std/asset_pack.mt +267 -0
- data/std/async/libuv_runtime.mt +539 -0
- data/std/async/mailbox.mt +191 -0
- data/std/async/runtime.mt +87 -0
- data/std/async.mt +87 -0
- data/std/base64.mt +185 -0
- data/std/behavior_tree.mt +396 -0
- data/std/binary.mt +314 -0
- data/std/binary_heap.mt +157 -0
- data/std/bitset.mt +239 -0
- data/std/box2d.mt +535 -0
- data/std/bytes.mt +46 -0
- data/std/c/box2d.mt +1254 -0
- data/std/c/cgltf.mt +647 -0
- data/std/c/cjson.mt +106 -0
- data/std/c/crypto.mt +11 -0
- data/std/c/crypto_support.h +51 -0
- data/std/c/ctype.mt +19 -0
- data/std/c/ctype_bindgen.h +29 -0
- data/std/c/curl.mt +1223 -0
- data/std/c/enet.mt +473 -0
- data/std/c/errno.mt +41 -0
- data/std/c/errno_bindgen.h +53 -0
- data/std/c/flecs.mt +2945 -0
- data/std/c/fs.linux.mt +43 -0
- data/std/c/fs.windows.mt +43 -0
- data/std/c/fs_support.h +954 -0
- data/std/c/gl.mt +2065 -0
- data/std/c/gl_registry_helpers.h +10748 -0
- data/std/c/glfw.mt +499 -0
- data/std/c/libc.mt +167 -0
- data/std/c/libuv.mt +1491 -0
- data/std/c/math.mt +22 -0
- data/std/c/math_bindgen.h +31 -0
- data/std/c/miniaudio.mt +3420 -0
- data/std/c/pcre2.mt +735 -0
- data/std/c/process.mt +58 -0
- data/std/c/process_support.h +1147 -0
- data/std/c/raygui.mt +1602 -0
- data/std/c/raylib.mt +1245 -0
- data/std/c/raymath.mt +163 -0
- data/std/c/rlgl.mt +434 -0
- data/std/c/rpng.mt +60 -0
- data/std/c/rres.mt +187 -0
- data/std/c/sdl3.mt +4132 -0
- data/std/c/sqlite3.mt +951 -0
- data/std/c/stb_image.mt +52 -0
- data/std/c/stb_image_resize2.mt +128 -0
- data/std/c/stb_image_write.mt +19 -0
- data/std/c/stb_rect_pack.mt +38 -0
- data/std/c/stb_truetype.mt +175 -0
- data/std/c/stb_vorbis.mt +31 -0
- data/std/c/stdio.mt +90 -0
- data/std/c/steamworks.h +5769 -0
- data/std/c/steamworks.mt +4771 -0
- data/std/c/string.mt +16 -0
- data/std/c/string_bindgen.h +36 -0
- data/std/c/sync.mt +33 -0
- data/std/c/sync_support.h +219 -0
- data/std/c/terminal.mt +24 -0
- data/std/c/terminal_support.h +408 -0
- data/std/c/time.mt +26 -0
- data/std/c/tls.mt +24 -0
- data/std/c/tls_support.h +626 -0
- data/std/c/tracy.mt +53 -0
- data/std/c/zlib.mt +20 -0
- data/std/c/zlib_support.h +239 -0
- data/std/c/zstd.mt +231 -0
- data/std/cell.mt +60 -0
- data/std/cgltf.mt +115 -0
- data/std/cjson.mt +90 -0
- data/std/cli.mt +768 -0
- data/std/cookie.mt +198 -0
- data/std/counter.mt +160 -0
- data/std/crypto.mt +74 -0
- data/std/cstring.mt +13 -0
- data/std/ctype.mt +52 -0
- data/std/curl/runtime.mt +261 -0
- data/std/curl.mt +38 -0
- data/std/deque.mt +348 -0
- data/std/encoding.mt +93 -0
- data/std/enet.mt +133 -0
- data/std/env.mt +41 -0
- data/std/errno.mt +47 -0
- data/std/flecs.mt +978 -0
- data/std/fmt.mt +271 -0
- data/std/fs.linux.mt +696 -0
- data/std/fs.windows.mt +711 -0
- data/std/fsm.mt +267 -0
- data/std/gl.mt +2062 -0
- data/std/glfw.mt +471 -0
- data/std/goap.mt +342 -0
- data/std/graph.mt +521 -0
- data/std/gzip.mt +77 -0
- data/std/hash.mt +429 -0
- data/std/http/server.mt +810 -0
- data/std/http.mt +1227 -0
- data/std/intern.mt +53 -0
- data/std/jobs.mt +288 -0
- data/std/json.mt +627 -0
- data/std/libc.mt +34 -0
- data/std/libuv.mt +554 -0
- data/std/linear_algebra.mt +243 -0
- data/std/linked_map.mt +372 -0
- data/std/linked_map_view.mt +49 -0
- data/std/linked_set.mt +117 -0
- data/std/log.mt +69 -0
- data/std/map.mt +418 -0
- data/std/math.mt +24 -0
- data/std/mem/arena.mt +137 -0
- data/std/mem/endian.mt +51 -0
- data/std/mem/heap.mt +298 -0
- data/std/mem/pool.mt +164 -0
- data/std/mem/stack.mt +47 -0
- data/std/mem/tracking.mt +119 -0
- data/std/miniaudio.mt +1299 -0
- data/std/multiset.mt +191 -0
- data/std/net/channel.mt +727 -0
- data/std/net/clock.mt +237 -0
- data/std/net/discovery.mt +277 -0
- data/std/net/lobby.mt +813 -0
- data/std/net/manager.mt +539 -0
- data/std/net/mux.mt +839 -0
- data/std/net/nat.mt +122 -0
- data/std/net/packet.mt +219 -0
- data/std/net/punch.mt +162 -0
- data/std/net/rpc.mt +119 -0
- data/std/net/session.mt +1157 -0
- data/std/net/stun.mt +252 -0
- data/std/net/sync.mt +183 -0
- data/std/net/turn.mt +459 -0
- data/std/net.mt +2944 -0
- data/std/oauth2.mt +408 -0
- data/std/option.mt +51 -0
- data/std/ordered_map.mt +497 -0
- data/std/ordered_set.mt +348 -0
- data/std/path.mt +368 -0
- data/std/pcre2/runtime.mt +35 -0
- data/std/pcre2.mt +78 -0
- data/std/priority_queue.mt +55 -0
- data/std/process.mt +837 -0
- data/std/queue.mt +55 -0
- data/std/random.mt +146 -0
- data/std/raygui.mt +99 -0
- data/std/raylib/debug_console.mt +71 -0
- data/std/raylib/easing.mt +388 -0
- data/std/raylib/packed_assets.mt +255 -0
- data/std/raylib/runtime.mt +30 -0
- data/std/raylib/tracy_gpu.mt +37 -0
- data/std/raylib.mt +1510 -0
- data/std/raymath.mt +153 -0
- data/std/result.mt +89 -0
- data/std/rlgl.mt +268 -0
- data/std/rpng.mt +46 -0
- data/std/rres.mt +36 -0
- data/std/sdl3/runtime.mt +54 -0
- data/std/sdl3.mt +1731 -0
- data/std/serialize.mt +68 -0
- data/std/set.mt +124 -0
- data/std/spatial.mt +176 -0
- data/std/sqlite3.mt +151 -0
- data/std/stack.mt +55 -0
- data/std/stb_image.mt +47 -0
- data/std/stb_image_resize2.mt +41 -0
- data/std/stb_image_write.mt +17 -0
- data/std/stb_rect_pack.mt +15 -0
- data/std/stb_truetype.mt +77 -0
- data/std/stb_vorbis.mt +16 -0
- data/std/stdio.mt +88 -0
- data/std/steamworks.mt +1542 -0
- data/std/str.mt +293 -0
- data/std/string.mt +234 -0
- data/std/sync.mt +194 -0
- data/std/tar.mt +704 -0
- data/std/terminal.mt +1002 -0
- data/std/testing.mt +266 -0
- data/std/thread.mt +120 -0
- data/std/time.mt +105 -0
- data/std/tls.mt +616 -0
- data/std/toml.mt +1310 -0
- data/std/tracy.mt +42 -0
- data/std/uri.mt +118 -0
- data/std/url.mt +372 -0
- data/std/vec.mt +433 -0
- data/std/zstd.mt +94 -0
- metadata +187 -2
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import std.vec as vec
|
|
2
|
+
|
|
3
|
+
public enum Status: ubyte
|
|
4
|
+
success = 0
|
|
5
|
+
failure = 1
|
|
6
|
+
running = 2
|
|
7
|
+
|
|
8
|
+
public enum NodeKind: ubyte
|
|
9
|
+
sequence = 0
|
|
10
|
+
selector = 1
|
|
11
|
+
parallel_all = 2
|
|
12
|
+
parallel_any = 3
|
|
13
|
+
condition = 4
|
|
14
|
+
action = 5
|
|
15
|
+
inverter = 6
|
|
16
|
+
succeeder = 7
|
|
17
|
+
failer = 8
|
|
18
|
+
repeater = 9
|
|
19
|
+
until_success = 10
|
|
20
|
+
until_failure = 11
|
|
21
|
+
|
|
22
|
+
struct RuntimeState:
|
|
23
|
+
active_child: ptr_uint
|
|
24
|
+
repeat_count: ptr_uint
|
|
25
|
+
|
|
26
|
+
public struct Node[Context]:
|
|
27
|
+
kind: NodeKind
|
|
28
|
+
condition_fn: fn(context: ptr[Context]) -> bool
|
|
29
|
+
action_fn: fn(context: ptr[Context]) -> Status
|
|
30
|
+
repeat_limit: ptr_uint
|
|
31
|
+
children: vec.Vec[ptr_uint]
|
|
32
|
+
|
|
33
|
+
public struct Tree[Context]:
|
|
34
|
+
nodes: vec.Vec[Node[Context]]
|
|
35
|
+
runtime: vec.Vec[RuntimeState]
|
|
36
|
+
root: ptr_uint
|
|
37
|
+
has_root: bool
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
function default_condition[Context](_context: ptr[Context]) -> bool:
|
|
41
|
+
return false
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
function default_action[Context](_context: ptr[Context]) -> Status:
|
|
45
|
+
return Status.failure
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
function create_runtime_state() -> RuntimeState:
|
|
49
|
+
return RuntimeState(active_child = 0, repeat_count = 0)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
function child_exists[Context](tree: ref[Tree[Context]], node_id: ptr_uint) -> bool:
|
|
53
|
+
return node_id < tree.nodes.len()
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
function reset_runtime_state(runtime: ptr[RuntimeState]) -> void:
|
|
57
|
+
unsafe:
|
|
58
|
+
read(runtime).active_child = 0
|
|
59
|
+
read(runtime).repeat_count = 0
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
function tick_node[Context](tree: ref[Tree[Context]], node_id: ptr_uint, context: ref[Context]) -> Status:
|
|
63
|
+
let node_ptr = tree.nodes.get(node_id) else:
|
|
64
|
+
return Status.failure
|
|
65
|
+
|
|
66
|
+
let runtime_ptr = tree.runtime.get(node_id) else:
|
|
67
|
+
return Status.failure
|
|
68
|
+
|
|
69
|
+
unsafe:
|
|
70
|
+
let node = ptr[Node[Context]]<-node_ptr
|
|
71
|
+
let runtime = ptr[RuntimeState]<-runtime_ptr
|
|
72
|
+
match read(node).kind:
|
|
73
|
+
NodeKind.sequence:
|
|
74
|
+
if read(node).children.is_empty():
|
|
75
|
+
reset_runtime_state(runtime)
|
|
76
|
+
return Status.success
|
|
77
|
+
|
|
78
|
+
var child_index = read(runtime).active_child
|
|
79
|
+
while child_index < read(node).children.len():
|
|
80
|
+
let child_ptr = read(node).children.get(child_index) else:
|
|
81
|
+
reset_runtime_state(runtime)
|
|
82
|
+
return Status.failure
|
|
83
|
+
|
|
84
|
+
let child_status = tick_node(tree, read(child_ptr), context)
|
|
85
|
+
match child_status:
|
|
86
|
+
Status.success:
|
|
87
|
+
child_index += 1
|
|
88
|
+
continue
|
|
89
|
+
Status.failure:
|
|
90
|
+
reset_runtime_state(runtime)
|
|
91
|
+
return Status.failure
|
|
92
|
+
Status.running:
|
|
93
|
+
read(runtime).active_child = child_index
|
|
94
|
+
return Status.running
|
|
95
|
+
|
|
96
|
+
reset_runtime_state(runtime)
|
|
97
|
+
return Status.success
|
|
98
|
+
|
|
99
|
+
NodeKind.selector:
|
|
100
|
+
if read(node).children.is_empty():
|
|
101
|
+
reset_runtime_state(runtime)
|
|
102
|
+
return Status.failure
|
|
103
|
+
|
|
104
|
+
var child_index = read(runtime).active_child
|
|
105
|
+
while child_index < read(node).children.len():
|
|
106
|
+
let child_ptr = read(node).children.get(child_index) else:
|
|
107
|
+
reset_runtime_state(runtime)
|
|
108
|
+
return Status.failure
|
|
109
|
+
|
|
110
|
+
let child_status = tick_node(tree, read(child_ptr), context)
|
|
111
|
+
match child_status:
|
|
112
|
+
Status.success:
|
|
113
|
+
reset_runtime_state(runtime)
|
|
114
|
+
return Status.success
|
|
115
|
+
Status.failure:
|
|
116
|
+
child_index += 1
|
|
117
|
+
continue
|
|
118
|
+
Status.running:
|
|
119
|
+
read(runtime).active_child = child_index
|
|
120
|
+
return Status.running
|
|
121
|
+
|
|
122
|
+
reset_runtime_state(runtime)
|
|
123
|
+
return Status.failure
|
|
124
|
+
|
|
125
|
+
NodeKind.parallel_all:
|
|
126
|
+
if read(node).children.is_empty():
|
|
127
|
+
return Status.failure
|
|
128
|
+
|
|
129
|
+
var saw_running = false
|
|
130
|
+
for child_ptr in read(node).children:
|
|
131
|
+
let child_status = tick_node(tree, unsafe: read(child_ptr), context)
|
|
132
|
+
match child_status:
|
|
133
|
+
Status.success:
|
|
134
|
+
pass
|
|
135
|
+
Status.failure:
|
|
136
|
+
return Status.failure
|
|
137
|
+
Status.running:
|
|
138
|
+
saw_running = true
|
|
139
|
+
|
|
140
|
+
if saw_running:
|
|
141
|
+
return Status.running
|
|
142
|
+
|
|
143
|
+
return Status.success
|
|
144
|
+
|
|
145
|
+
NodeKind.parallel_any:
|
|
146
|
+
if read(node).children.is_empty():
|
|
147
|
+
return Status.failure
|
|
148
|
+
|
|
149
|
+
var saw_running = false
|
|
150
|
+
for child_ptr in read(node).children:
|
|
151
|
+
let child_status = tick_node(tree, unsafe: read(child_ptr), context)
|
|
152
|
+
match child_status:
|
|
153
|
+
Status.success:
|
|
154
|
+
return Status.success
|
|
155
|
+
Status.failure:
|
|
156
|
+
pass
|
|
157
|
+
Status.running:
|
|
158
|
+
saw_running = true
|
|
159
|
+
|
|
160
|
+
if saw_running:
|
|
161
|
+
return Status.running
|
|
162
|
+
|
|
163
|
+
return Status.failure
|
|
164
|
+
|
|
165
|
+
NodeKind.condition:
|
|
166
|
+
if read(node).condition_fn(ptr_of(context)):
|
|
167
|
+
return Status.success
|
|
168
|
+
|
|
169
|
+
return Status.failure
|
|
170
|
+
|
|
171
|
+
NodeKind.action:
|
|
172
|
+
return read(node).action_fn(ptr_of(context))
|
|
173
|
+
|
|
174
|
+
NodeKind.inverter:
|
|
175
|
+
let child_ptr = read(node).children.first() else:
|
|
176
|
+
return Status.failure
|
|
177
|
+
|
|
178
|
+
let child_status = tick_node(tree, read(child_ptr), context)
|
|
179
|
+
match child_status:
|
|
180
|
+
Status.success:
|
|
181
|
+
return Status.failure
|
|
182
|
+
Status.failure:
|
|
183
|
+
return Status.success
|
|
184
|
+
Status.running:
|
|
185
|
+
return Status.running
|
|
186
|
+
|
|
187
|
+
NodeKind.succeeder:
|
|
188
|
+
let child_ptr = read(node).children.first() else:
|
|
189
|
+
return Status.success
|
|
190
|
+
|
|
191
|
+
let child_status = tick_node(tree, read(child_ptr), context)
|
|
192
|
+
if child_status == Status.running:
|
|
193
|
+
return Status.running
|
|
194
|
+
|
|
195
|
+
return Status.success
|
|
196
|
+
|
|
197
|
+
NodeKind.failer:
|
|
198
|
+
let child_ptr = read(node).children.first() else:
|
|
199
|
+
return Status.failure
|
|
200
|
+
|
|
201
|
+
let child_status = tick_node(tree, read(child_ptr), context)
|
|
202
|
+
if child_status == Status.running:
|
|
203
|
+
return Status.running
|
|
204
|
+
|
|
205
|
+
return Status.failure
|
|
206
|
+
|
|
207
|
+
NodeKind.repeater:
|
|
208
|
+
let child_ptr = read(node).children.first() else:
|
|
209
|
+
return Status.failure
|
|
210
|
+
|
|
211
|
+
if read(node).repeat_limit == 0:
|
|
212
|
+
return Status.success
|
|
213
|
+
|
|
214
|
+
let child_status = tick_node(tree, read(child_ptr), context)
|
|
215
|
+
match child_status:
|
|
216
|
+
Status.success:
|
|
217
|
+
read(runtime).repeat_count += 1
|
|
218
|
+
if read(runtime).repeat_count >= read(node).repeat_limit:
|
|
219
|
+
reset_runtime_state(runtime)
|
|
220
|
+
return Status.success
|
|
221
|
+
return Status.running
|
|
222
|
+
Status.failure:
|
|
223
|
+
reset_runtime_state(runtime)
|
|
224
|
+
return Status.failure
|
|
225
|
+
Status.running:
|
|
226
|
+
return Status.running
|
|
227
|
+
|
|
228
|
+
NodeKind.until_success:
|
|
229
|
+
let child_ptr = read(node).children.first() else:
|
|
230
|
+
return Status.failure
|
|
231
|
+
|
|
232
|
+
let child_status = tick_node(tree, read(child_ptr), context)
|
|
233
|
+
match child_status:
|
|
234
|
+
Status.success:
|
|
235
|
+
return Status.success
|
|
236
|
+
Status.failure:
|
|
237
|
+
return Status.running
|
|
238
|
+
Status.running:
|
|
239
|
+
return Status.running
|
|
240
|
+
|
|
241
|
+
NodeKind.until_failure:
|
|
242
|
+
let child_ptr = read(node).children.first() else:
|
|
243
|
+
return Status.failure
|
|
244
|
+
|
|
245
|
+
let child_status = tick_node(tree, read(child_ptr), context)
|
|
246
|
+
match child_status:
|
|
247
|
+
Status.success:
|
|
248
|
+
return Status.running
|
|
249
|
+
Status.failure:
|
|
250
|
+
return Status.success
|
|
251
|
+
Status.running:
|
|
252
|
+
return Status.running
|
|
253
|
+
|
|
254
|
+
return Status.failure
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
extending Node[Context]:
|
|
258
|
+
static function create(kind: NodeKind) -> Node[Context]:
|
|
259
|
+
return Node[Context](
|
|
260
|
+
kind = kind,
|
|
261
|
+
condition_fn = default_condition[Context],
|
|
262
|
+
action_fn = default_action[Context],
|
|
263
|
+
repeat_limit = 0,
|
|
264
|
+
children = vec.Vec[ptr_uint].create()
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
public static function sequence() -> Node[Context]:
|
|
269
|
+
return Node[Context].create(NodeKind.sequence)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
public static function selector() -> Node[Context]:
|
|
273
|
+
return Node[Context].create(NodeKind.selector)
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
public static function parallel_all() -> Node[Context]:
|
|
277
|
+
return Node[Context].create(NodeKind.parallel_all)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
public static function parallel_any() -> Node[Context]:
|
|
281
|
+
return Node[Context].create(NodeKind.parallel_any)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
public static function condition(check: fn(context: ptr[Context]) -> bool) -> Node[Context]:
|
|
285
|
+
var result = Node[Context].create(NodeKind.condition)
|
|
286
|
+
result.condition_fn = check
|
|
287
|
+
return result
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
public static function action(run: fn(context: ptr[Context]) -> Status) -> Node[Context]:
|
|
291
|
+
var result = Node[Context].create(NodeKind.action)
|
|
292
|
+
result.action_fn = run
|
|
293
|
+
return result
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
public static function inverter() -> Node[Context]:
|
|
297
|
+
return Node[Context].create(NodeKind.inverter)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
public static function succeeder() -> Node[Context]:
|
|
301
|
+
return Node[Context].create(NodeKind.succeeder)
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
public static function failer() -> Node[Context]:
|
|
305
|
+
return Node[Context].create(NodeKind.failer)
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
public static function repeater(limit: ptr_uint) -> Node[Context]:
|
|
309
|
+
var result = Node[Context].create(NodeKind.repeater)
|
|
310
|
+
result.repeat_limit = limit
|
|
311
|
+
return result
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
public static function until_success() -> Node[Context]:
|
|
315
|
+
return Node[Context].create(NodeKind.until_success)
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
public static function until_failure() -> Node[Context]:
|
|
319
|
+
return Node[Context].create(NodeKind.until_failure)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
public editable function release() -> void:
|
|
323
|
+
this.children.release()
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
extending Tree[Context]:
|
|
327
|
+
public static function create() -> Tree[Context]:
|
|
328
|
+
return Tree[Context](
|
|
329
|
+
nodes = vec.Vec[Node[Context]].create(),
|
|
330
|
+
runtime = vec.Vec[RuntimeState].create(),
|
|
331
|
+
root = 0,
|
|
332
|
+
has_root = false
|
|
333
|
+
)
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
public editable function release() -> void:
|
|
337
|
+
for node_ptr in this.nodes:
|
|
338
|
+
unsafe:
|
|
339
|
+
read(node_ptr).release()
|
|
340
|
+
this.nodes.release()
|
|
341
|
+
this.runtime.release()
|
|
342
|
+
this.root = 0
|
|
343
|
+
this.has_root = false
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
public editable function reset() -> void:
|
|
347
|
+
for entry in this.runtime:
|
|
348
|
+
reset_runtime_state(unsafe: ptr[RuntimeState]<-entry)
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
public function node_count() -> ptr_uint:
|
|
352
|
+
return this.nodes.len()
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
public function root_node() -> Option[ptr_uint]:
|
|
356
|
+
if not this.has_root:
|
|
357
|
+
return Option[ptr_uint].none
|
|
358
|
+
|
|
359
|
+
return Option[ptr_uint].some(value = this.root)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
public editable function add_node(node: Node[Context]) -> ptr_uint:
|
|
363
|
+
let node_id = this.nodes.len()
|
|
364
|
+
this.nodes.push(node)
|
|
365
|
+
this.runtime.push(create_runtime_state())
|
|
366
|
+
return node_id
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
public editable function set_root(node_id: ptr_uint) -> bool:
|
|
370
|
+
if not child_exists(ref_of(this), node_id):
|
|
371
|
+
return false
|
|
372
|
+
|
|
373
|
+
this.root = node_id
|
|
374
|
+
this.has_root = true
|
|
375
|
+
return true
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
public editable function add_child(parent_id: ptr_uint, child_id: ptr_uint) -> bool:
|
|
379
|
+
if not child_exists(ref_of(this), parent_id):
|
|
380
|
+
return false
|
|
381
|
+
if not child_exists(ref_of(this), child_id):
|
|
382
|
+
return false
|
|
383
|
+
|
|
384
|
+
let parent_ptr = this.nodes.get(parent_id) else:
|
|
385
|
+
return false
|
|
386
|
+
|
|
387
|
+
unsafe:
|
|
388
|
+
read(parent_ptr).children.push(child_id)
|
|
389
|
+
return true
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
public editable function tick(context: ref[Context]) -> Status:
|
|
393
|
+
if not this.has_root:
|
|
394
|
+
return Status.failure
|
|
395
|
+
|
|
396
|
+
return tick_node(ref_of(this), this.root, context)
|
data/std/binary.mt
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import std.bytes as bytes
|
|
2
|
+
import std.str as text
|
|
3
|
+
import std.string as string
|
|
4
|
+
import std.vec as vec
|
|
5
|
+
|
|
6
|
+
public struct Error:
|
|
7
|
+
code: int
|
|
8
|
+
message: string.String
|
|
9
|
+
|
|
10
|
+
public struct Writer:
|
|
11
|
+
buffer: vec.Vec[ubyte]
|
|
12
|
+
|
|
13
|
+
public struct Reader:
|
|
14
|
+
data: span[ubyte]
|
|
15
|
+
position: ptr_uint
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
function binary_error(code: int, message: str) -> Error:
|
|
19
|
+
return Error(code = code, message = string.String.from_str(message))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
function writer_append_byte(writer: ref[Writer], value: ubyte) -> void:
|
|
23
|
+
writer.buffer.push(value)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
function writer_append_span(writer: ref[Writer], data: span[ubyte]) -> void:
|
|
27
|
+
writer.buffer.append_span(data)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
extending Error:
|
|
31
|
+
public editable function release() -> void:
|
|
32
|
+
this.message.release()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
extending Writer:
|
|
36
|
+
public static function create() -> Writer:
|
|
37
|
+
return Writer(buffer = vec.Vec[ubyte].create())
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
public static function with_capacity(capacity: ptr_uint) -> Writer:
|
|
41
|
+
return Writer(buffer = vec.Vec[ubyte].with_capacity(capacity))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
public editable function write_ubyte(value: ubyte) -> void:
|
|
45
|
+
writer_append_byte(ref_of(this), value)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
public editable function write_ushort(value: ushort) -> void:
|
|
49
|
+
writer_append_byte(ref_of(this), ubyte<-(value & 0xFF))
|
|
50
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 8) & 0xFF))
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
public editable function write_uint(value: uint) -> void:
|
|
54
|
+
writer_append_byte(ref_of(this), ubyte<-(value & 0xFF))
|
|
55
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 8) & 0xFF))
|
|
56
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 16) & 0xFF))
|
|
57
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 24) & 0xFF))
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
public editable function write_ulong(value: ulong) -> void:
|
|
61
|
+
writer_append_byte(ref_of(this), ubyte<-(value & 0xFF))
|
|
62
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 8) & 0xFF))
|
|
63
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 16) & 0xFF))
|
|
64
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 24) & 0xFF))
|
|
65
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 32) & 0xFF))
|
|
66
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 40) & 0xFF))
|
|
67
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 48) & 0xFF))
|
|
68
|
+
writer_append_byte(ref_of(this), ubyte<-((value >> 56) & 0xFF))
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
public editable function write_byte(value: byte) -> void:
|
|
72
|
+
writer_append_byte(ref_of(this), ubyte<-value)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
public editable function write_short(value: short) -> void:
|
|
76
|
+
this.write_ushort(ushort<-value)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
public editable function write_int(value: int) -> void:
|
|
80
|
+
this.write_uint(uint<-value)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
public editable function write_long(value: long) -> void:
|
|
84
|
+
this.write_ulong(ulong<-value)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
public editable function write_float(value: float) -> void:
|
|
88
|
+
let bits = unsafe: reinterpret[uint](value)
|
|
89
|
+
this.write_uint(bits)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
public editable function write_double(value: double) -> void:
|
|
93
|
+
let bits = unsafe: reinterpret[ulong](value)
|
|
94
|
+
this.write_ulong(bits)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
public editable function write_bool(value: bool) -> void:
|
|
98
|
+
if value:
|
|
99
|
+
writer_append_byte(ref_of(this), 1)
|
|
100
|
+
else:
|
|
101
|
+
writer_append_byte(ref_of(this), 0)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
public editable function write_bytes(data: span[ubyte]) -> void:
|
|
105
|
+
writer_append_span(ref_of(this), data)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
public editable function write_str(value: str) -> void:
|
|
109
|
+
this.write_uint(uint<-value.len)
|
|
110
|
+
if value.len > 0:
|
|
111
|
+
writer_append_span(ref_of(this), text.as_byte_span(value))
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
public editable function write_uint_at(position: ptr_uint, value: uint) -> void:
|
|
115
|
+
let buffer_span = this.buffer.as_span()
|
|
116
|
+
if position + 4 > buffer_span.len:
|
|
117
|
+
fatal(c"binary.write_u32_at position out of bounds")
|
|
118
|
+
unsafe:
|
|
119
|
+
read(buffer_span.data + position) = ubyte<-(value & 0xFF)
|
|
120
|
+
read(buffer_span.data + position + 1) = ubyte<-((value >> 8) & 0xFF)
|
|
121
|
+
read(buffer_span.data + position + 2) = ubyte<-((value >> 16) & 0xFF)
|
|
122
|
+
read(buffer_span.data + position + 3) = ubyte<-((value >> 24) & 0xFF)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
public function len() -> ptr_uint:
|
|
126
|
+
return this.buffer.len()
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
public function as_span() -> span[ubyte]:
|
|
130
|
+
return this.buffer.as_span()
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
public editable function finish() -> bytes.Bytes:
|
|
134
|
+
let result = bytes.Bytes.copy(this.buffer.as_span())
|
|
135
|
+
this.buffer.release()
|
|
136
|
+
return result
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
public editable function reset() -> void:
|
|
140
|
+
this.buffer.clear()
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
public editable function release() -> void:
|
|
144
|
+
this.buffer.release()
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
public function reader(data: span[ubyte]) -> Reader:
|
|
148
|
+
return Reader(data = data, position = 0)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
public function reader_from_bytes(data: bytes.Bytes) -> Reader:
|
|
152
|
+
return Reader(data = data.as_span(), position = 0)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
function reader_check_remaining(reader: ref[Reader], count: ptr_uint) -> Result[bool, Error]:
|
|
156
|
+
if reader.position > reader.data.len:
|
|
157
|
+
return Result[bool, Error].failure(error = binary_error(-1, "binary reader position overflow"))
|
|
158
|
+
if reader.data.len - reader.position < count:
|
|
159
|
+
return Result[bool, Error].failure(error = binary_error(-1, "binary reader unexpected end of buffer"))
|
|
160
|
+
return Result[bool, Error].success(value = true)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
function reader_read_byte(reader: ref[Reader]) -> Result[ubyte, Error]:
|
|
164
|
+
reader_check_remaining(reader, 1)?
|
|
165
|
+
let value = unsafe: read(reader.data.data + reader.position)
|
|
166
|
+
reader.position += 1
|
|
167
|
+
return Result[ubyte, Error].success(value = value)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
extending Reader:
|
|
171
|
+
public editable function read_ubyte() -> Result[ubyte, Error]:
|
|
172
|
+
return reader_read_byte(ref_of(this))
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
public editable function read_ushort() -> Result[ushort, Error]:
|
|
176
|
+
reader_check_remaining(ref_of(this), 2)?
|
|
177
|
+
let low = ushort<-unsafe: read(this.data.data + this.position)
|
|
178
|
+
let high = ushort<-unsafe: read(this.data.data + this.position + 1)
|
|
179
|
+
this.position += 2
|
|
180
|
+
return Result[ushort, Error].success(value = (high << 8) | low)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
public editable function read_uint() -> Result[uint, Error]:
|
|
184
|
+
reader_check_remaining(ref_of(this), 4)?
|
|
185
|
+
var value: uint = 0
|
|
186
|
+
unsafe:
|
|
187
|
+
let b0 = uint<-read(this.data.data + this.position)
|
|
188
|
+
let b1 = uint<-read(this.data.data + this.position + 1)
|
|
189
|
+
let b2 = uint<-read(this.data.data + this.position + 2)
|
|
190
|
+
let b3 = uint<-read(this.data.data + this.position + 3)
|
|
191
|
+
value = b0 | (b1 << 8) | (b2 << 16) | (b3 << 24)
|
|
192
|
+
this.position += 4
|
|
193
|
+
return Result[uint, Error].success(value = value)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
public editable function read_ulong() -> Result[ulong, Error]:
|
|
197
|
+
reader_check_remaining(ref_of(this), 8)?
|
|
198
|
+
var value: ulong = 0
|
|
199
|
+
unsafe:
|
|
200
|
+
let b0 = ulong<-read(this.data.data + this.position)
|
|
201
|
+
let b1 = ulong<-read(this.data.data + this.position + 1)
|
|
202
|
+
let b2 = ulong<-read(this.data.data + this.position + 2)
|
|
203
|
+
let b3 = ulong<-read(this.data.data + this.position + 3)
|
|
204
|
+
let b4 = ulong<-read(this.data.data + this.position + 4)
|
|
205
|
+
let b5 = ulong<-read(this.data.data + this.position + 5)
|
|
206
|
+
let b6 = ulong<-read(this.data.data + this.position + 6)
|
|
207
|
+
let b7 = ulong<-read(this.data.data + this.position + 7)
|
|
208
|
+
value = (
|
|
209
|
+
b0 | (b1 << 8) | (b2 << 16) | (b3 << 24)
|
|
210
|
+
| (b4 << 32) | (b5 << 40) | (b6 << 48) | (b7 << 56)
|
|
211
|
+
)
|
|
212
|
+
this.position += 8
|
|
213
|
+
return Result[ulong, Error].success(value = value)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
public editable function read_byte() -> Result[byte, Error]:
|
|
217
|
+
let value = this.read_ubyte()?
|
|
218
|
+
return Result[byte, Error].success(value = byte<-value)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
public editable function read_short() -> Result[short, Error]:
|
|
222
|
+
let value = this.read_ushort()?
|
|
223
|
+
return Result[short, Error].success(value = short<-value)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
public editable function read_int() -> Result[int, Error]:
|
|
227
|
+
let value = this.read_uint()?
|
|
228
|
+
return Result[int, Error].success(value = int<-value)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
public editable function read_long() -> Result[long, Error]:
|
|
232
|
+
let value = this.read_ulong()?
|
|
233
|
+
return Result[long, Error].success(value = long<-value)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
public editable function read_float() -> Result[float, Error]:
|
|
237
|
+
let value = this.read_uint()?
|
|
238
|
+
return Result[float, Error].success(value = unsafe: reinterpret[float](value))
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
public editable function read_double() -> Result[double, Error]:
|
|
242
|
+
let value = this.read_ulong()?
|
|
243
|
+
return Result[double, Error].success(value = unsafe: reinterpret[double](value))
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
public editable function read_bool() -> Result[bool, Error]:
|
|
247
|
+
let value = this.read_ubyte()?
|
|
248
|
+
if value == 0:
|
|
249
|
+
return Result[bool, Error].success(value = false)
|
|
250
|
+
if value == 1:
|
|
251
|
+
return Result[bool, Error].success(value = true)
|
|
252
|
+
return Result[bool, Error].failure(error = binary_error(-2, "binary reader invalid bool value"))
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
public editable function read_bytes(count: ptr_uint) -> Result[bytes.Bytes, Error]:
|
|
256
|
+
if count == 0:
|
|
257
|
+
return Result[bytes.Bytes, Error].success(value = bytes.Bytes.empty())
|
|
258
|
+
|
|
259
|
+
reader_check_remaining(ref_of(this), count)?
|
|
260
|
+
unsafe:
|
|
261
|
+
let result = bytes.Bytes.copy(span[ubyte](
|
|
262
|
+
data = this.data.data + this.position,
|
|
263
|
+
len = count
|
|
264
|
+
))
|
|
265
|
+
this.position += count
|
|
266
|
+
return Result[bytes.Bytes, Error].success(value = result)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
public editable function read_span(count: ptr_uint) -> Result[span[ubyte], Error]:
|
|
270
|
+
if count == 0:
|
|
271
|
+
let empty = unsafe: span[ubyte](data = this.data.data, len = 0)
|
|
272
|
+
return Result[span[ubyte], Error].success(value = empty)
|
|
273
|
+
|
|
274
|
+
reader_check_remaining(ref_of(this), count)?
|
|
275
|
+
unsafe:
|
|
276
|
+
let result = span[ubyte](data = this.data.data + this.position, len = count)
|
|
277
|
+
this.position += count
|
|
278
|
+
return Result[span[ubyte], Error].success(value = result)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
public editable function read_str() -> Result[string.String, Error]:
|
|
282
|
+
let length = ptr_uint<-this.read_uint()?
|
|
283
|
+
if length == 0:
|
|
284
|
+
return Result[string.String, Error].success(value = string.String.create())
|
|
285
|
+
|
|
286
|
+
var data = this.read_bytes(length)?
|
|
287
|
+
let str_opt = text.utf8_byte_span_as_str(data.as_span())
|
|
288
|
+
match str_opt:
|
|
289
|
+
Option.none:
|
|
290
|
+
data.release()
|
|
291
|
+
return Result[string.String, Error].failure(error = binary_error(
|
|
292
|
+
-2,
|
|
293
|
+
"binary reader invalid UTF-8 string"
|
|
294
|
+
))
|
|
295
|
+
Option.some as str_payload:
|
|
296
|
+
let result = string.String.from_str(str_payload.value)
|
|
297
|
+
data.release()
|
|
298
|
+
return Result[string.String, Error].success(value = result)
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
public editable function skip(count: ptr_uint) -> Result[bool, Error]:
|
|
302
|
+
reader_check_remaining(ref_of(this), count)?
|
|
303
|
+
this.position += count
|
|
304
|
+
return Result[bool, Error].success(value = true)
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
public function remaining() -> ptr_uint:
|
|
308
|
+
if this.position >= this.data.len:
|
|
309
|
+
return 0
|
|
310
|
+
return this.data.len - this.position
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
public function has_more() -> bool:
|
|
314
|
+
return this.position < this.data.len
|