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.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/docs/index.html +4 -3
  3. data/lib/milk_tea/base.rb +1 -1
  4. data/std/asset_pack.mt +267 -0
  5. data/std/async/libuv_runtime.mt +539 -0
  6. data/std/async/mailbox.mt +191 -0
  7. data/std/async/runtime.mt +87 -0
  8. data/std/async.mt +87 -0
  9. data/std/base64.mt +185 -0
  10. data/std/behavior_tree.mt +396 -0
  11. data/std/binary.mt +314 -0
  12. data/std/binary_heap.mt +157 -0
  13. data/std/bitset.mt +239 -0
  14. data/std/box2d.mt +535 -0
  15. data/std/bytes.mt +46 -0
  16. data/std/c/box2d.mt +1254 -0
  17. data/std/c/cgltf.mt +647 -0
  18. data/std/c/cjson.mt +106 -0
  19. data/std/c/crypto.mt +11 -0
  20. data/std/c/crypto_support.h +51 -0
  21. data/std/c/ctype.mt +19 -0
  22. data/std/c/ctype_bindgen.h +29 -0
  23. data/std/c/curl.mt +1223 -0
  24. data/std/c/enet.mt +473 -0
  25. data/std/c/errno.mt +41 -0
  26. data/std/c/errno_bindgen.h +53 -0
  27. data/std/c/flecs.mt +2945 -0
  28. data/std/c/fs.linux.mt +43 -0
  29. data/std/c/fs.windows.mt +43 -0
  30. data/std/c/fs_support.h +954 -0
  31. data/std/c/gl.mt +2065 -0
  32. data/std/c/gl_registry_helpers.h +10748 -0
  33. data/std/c/glfw.mt +499 -0
  34. data/std/c/libc.mt +167 -0
  35. data/std/c/libuv.mt +1491 -0
  36. data/std/c/math.mt +22 -0
  37. data/std/c/math_bindgen.h +31 -0
  38. data/std/c/miniaudio.mt +3420 -0
  39. data/std/c/pcre2.mt +735 -0
  40. data/std/c/process.mt +58 -0
  41. data/std/c/process_support.h +1147 -0
  42. data/std/c/raygui.mt +1602 -0
  43. data/std/c/raylib.mt +1245 -0
  44. data/std/c/raymath.mt +163 -0
  45. data/std/c/rlgl.mt +434 -0
  46. data/std/c/rpng.mt +60 -0
  47. data/std/c/rres.mt +187 -0
  48. data/std/c/sdl3.mt +4132 -0
  49. data/std/c/sqlite3.mt +951 -0
  50. data/std/c/stb_image.mt +52 -0
  51. data/std/c/stb_image_resize2.mt +128 -0
  52. data/std/c/stb_image_write.mt +19 -0
  53. data/std/c/stb_rect_pack.mt +38 -0
  54. data/std/c/stb_truetype.mt +175 -0
  55. data/std/c/stb_vorbis.mt +31 -0
  56. data/std/c/stdio.mt +90 -0
  57. data/std/c/steamworks.h +5769 -0
  58. data/std/c/steamworks.mt +4771 -0
  59. data/std/c/string.mt +16 -0
  60. data/std/c/string_bindgen.h +36 -0
  61. data/std/c/sync.mt +33 -0
  62. data/std/c/sync_support.h +219 -0
  63. data/std/c/terminal.mt +24 -0
  64. data/std/c/terminal_support.h +408 -0
  65. data/std/c/time.mt +26 -0
  66. data/std/c/tls.mt +24 -0
  67. data/std/c/tls_support.h +626 -0
  68. data/std/c/tracy.mt +53 -0
  69. data/std/c/zlib.mt +20 -0
  70. data/std/c/zlib_support.h +239 -0
  71. data/std/c/zstd.mt +231 -0
  72. data/std/cell.mt +60 -0
  73. data/std/cgltf.mt +115 -0
  74. data/std/cjson.mt +90 -0
  75. data/std/cli.mt +768 -0
  76. data/std/cookie.mt +198 -0
  77. data/std/counter.mt +160 -0
  78. data/std/crypto.mt +74 -0
  79. data/std/cstring.mt +13 -0
  80. data/std/ctype.mt +52 -0
  81. data/std/curl/runtime.mt +261 -0
  82. data/std/curl.mt +38 -0
  83. data/std/deque.mt +348 -0
  84. data/std/encoding.mt +93 -0
  85. data/std/enet.mt +133 -0
  86. data/std/env.mt +41 -0
  87. data/std/errno.mt +47 -0
  88. data/std/flecs.mt +978 -0
  89. data/std/fmt.mt +271 -0
  90. data/std/fs.linux.mt +696 -0
  91. data/std/fs.windows.mt +711 -0
  92. data/std/fsm.mt +267 -0
  93. data/std/gl.mt +2062 -0
  94. data/std/glfw.mt +471 -0
  95. data/std/goap.mt +342 -0
  96. data/std/graph.mt +521 -0
  97. data/std/gzip.mt +77 -0
  98. data/std/hash.mt +429 -0
  99. data/std/http/server.mt +810 -0
  100. data/std/http.mt +1227 -0
  101. data/std/intern.mt +53 -0
  102. data/std/jobs.mt +288 -0
  103. data/std/json.mt +627 -0
  104. data/std/libc.mt +34 -0
  105. data/std/libuv.mt +554 -0
  106. data/std/linear_algebra.mt +243 -0
  107. data/std/linked_map.mt +372 -0
  108. data/std/linked_map_view.mt +49 -0
  109. data/std/linked_set.mt +117 -0
  110. data/std/log.mt +69 -0
  111. data/std/map.mt +418 -0
  112. data/std/math.mt +24 -0
  113. data/std/mem/arena.mt +137 -0
  114. data/std/mem/endian.mt +51 -0
  115. data/std/mem/heap.mt +298 -0
  116. data/std/mem/pool.mt +164 -0
  117. data/std/mem/stack.mt +47 -0
  118. data/std/mem/tracking.mt +119 -0
  119. data/std/miniaudio.mt +1299 -0
  120. data/std/multiset.mt +191 -0
  121. data/std/net/channel.mt +727 -0
  122. data/std/net/clock.mt +237 -0
  123. data/std/net/discovery.mt +277 -0
  124. data/std/net/lobby.mt +813 -0
  125. data/std/net/manager.mt +539 -0
  126. data/std/net/mux.mt +839 -0
  127. data/std/net/nat.mt +122 -0
  128. data/std/net/packet.mt +219 -0
  129. data/std/net/punch.mt +162 -0
  130. data/std/net/rpc.mt +119 -0
  131. data/std/net/session.mt +1157 -0
  132. data/std/net/stun.mt +252 -0
  133. data/std/net/sync.mt +183 -0
  134. data/std/net/turn.mt +459 -0
  135. data/std/net.mt +2944 -0
  136. data/std/oauth2.mt +408 -0
  137. data/std/option.mt +51 -0
  138. data/std/ordered_map.mt +497 -0
  139. data/std/ordered_set.mt +348 -0
  140. data/std/path.mt +368 -0
  141. data/std/pcre2/runtime.mt +35 -0
  142. data/std/pcre2.mt +78 -0
  143. data/std/priority_queue.mt +55 -0
  144. data/std/process.mt +837 -0
  145. data/std/queue.mt +55 -0
  146. data/std/random.mt +146 -0
  147. data/std/raygui.mt +99 -0
  148. data/std/raylib/debug_console.mt +71 -0
  149. data/std/raylib/easing.mt +388 -0
  150. data/std/raylib/packed_assets.mt +255 -0
  151. data/std/raylib/runtime.mt +30 -0
  152. data/std/raylib/tracy_gpu.mt +37 -0
  153. data/std/raylib.mt +1510 -0
  154. data/std/raymath.mt +153 -0
  155. data/std/result.mt +89 -0
  156. data/std/rlgl.mt +268 -0
  157. data/std/rpng.mt +46 -0
  158. data/std/rres.mt +36 -0
  159. data/std/sdl3/runtime.mt +54 -0
  160. data/std/sdl3.mt +1731 -0
  161. data/std/serialize.mt +68 -0
  162. data/std/set.mt +124 -0
  163. data/std/spatial.mt +176 -0
  164. data/std/sqlite3.mt +151 -0
  165. data/std/stack.mt +55 -0
  166. data/std/stb_image.mt +47 -0
  167. data/std/stb_image_resize2.mt +41 -0
  168. data/std/stb_image_write.mt +17 -0
  169. data/std/stb_rect_pack.mt +15 -0
  170. data/std/stb_truetype.mt +77 -0
  171. data/std/stb_vorbis.mt +16 -0
  172. data/std/stdio.mt +88 -0
  173. data/std/steamworks.mt +1542 -0
  174. data/std/str.mt +293 -0
  175. data/std/string.mt +234 -0
  176. data/std/sync.mt +194 -0
  177. data/std/tar.mt +704 -0
  178. data/std/terminal.mt +1002 -0
  179. data/std/testing.mt +266 -0
  180. data/std/thread.mt +120 -0
  181. data/std/time.mt +105 -0
  182. data/std/tls.mt +616 -0
  183. data/std/toml.mt +1310 -0
  184. data/std/tracy.mt +42 -0
  185. data/std/uri.mt +118 -0
  186. data/std/url.mt +372 -0
  187. data/std/vec.mt +433 -0
  188. data/std/zstd.mt +94 -0
  189. metadata +187 -2
@@ -0,0 +1,539 @@
1
+ import std.libuv as libuv
2
+ import std.mem.heap as heap
3
+
4
+ public type NativeLoopHandle = libuv.uv_loop_t
5
+
6
+ type NativeHandle = libuv.uv_handle_t
7
+ type NativeTimerHandle = libuv.uv_timer_t
8
+ type NativeRequest = libuv.uv_req_t
9
+ type NativeWorkRequest = libuv.uv_work_t
10
+
11
+ public struct Runtime:
12
+ loop: ptr[NativeLoopHandle]?
13
+ active: bool
14
+
15
+ var current_runtime: Runtime = zero[Runtime]
16
+ var current_runtime_active: bool = false
17
+
18
+ struct SleepState:
19
+ ready: bool
20
+ status: int
21
+ waiter_frame: ptr[void]?
22
+ waiter: fn(frame: ptr[void]) -> void
23
+ waiter_registered: bool
24
+ timer: ptr[NativeTimerHandle]?
25
+ closing: bool
26
+ closed: bool
27
+ released: bool
28
+
29
+ struct WorkState[T]:
30
+ ready: bool
31
+ status: int
32
+ waiter_frame: ptr[void]?
33
+ waiter: fn(frame: ptr[void]) -> void
34
+ waiter_registered: bool
35
+ work: ptr[NativeWorkRequest]?
36
+ queued: bool
37
+ released: bool
38
+ execute: fn(state_frame: ptr[void]) -> void
39
+ run_work: fn() -> T
40
+ result: T
41
+
42
+ struct WorkStateBase:
43
+ ready: bool
44
+ status: int
45
+ waiter_frame: ptr[void]?
46
+ waiter: fn(frame: ptr[void]) -> void
47
+ waiter_registered: bool
48
+ work: ptr[NativeWorkRequest]?
49
+ queued: bool
50
+ released: bool
51
+ execute: fn(state_frame: ptr[void]) -> void
52
+
53
+
54
+ function sleep_state(frame: ptr[void]) -> ptr[SleepState]:
55
+ return unsafe: ptr[SleepState]<-frame
56
+
57
+
58
+ function work_state[T](frame: ptr[void]) -> ptr[WorkState[T]]:
59
+ return unsafe: ptr[WorkState[T]]<-frame
60
+
61
+
62
+ function work_state_base(frame: ptr[void]) -> ptr[WorkStateBase]:
63
+ return unsafe: ptr[WorkStateBase]<-frame
64
+
65
+
66
+ function timer_as_handle(timer: ptr[NativeTimerHandle]) -> ptr[NativeHandle]:
67
+ return unsafe: ptr[NativeHandle]<-timer
68
+
69
+
70
+ function handle_as_timer(handle: ptr[NativeHandle]) -> ptr[NativeTimerHandle]:
71
+ return unsafe: ptr[NativeTimerHandle]<-handle
72
+
73
+
74
+ function req_as_work(req: ptr[NativeRequest]) -> ptr[NativeWorkRequest]:
75
+ return unsafe: ptr[NativeWorkRequest]<-req
76
+
77
+
78
+ function work_as_req(work: ptr[NativeWorkRequest]) -> ptr[NativeRequest]:
79
+ return unsafe: ptr[NativeRequest]<-work
80
+
81
+
82
+ function close_all_handles_cb(handle: ptr[NativeHandle], arg: ptr[void]) -> void:
83
+ if libuv.is_closing(handle) == 0:
84
+ libuv.close(handle, close_all_handles_close_cb)
85
+ unsafe: arg
86
+
87
+
88
+ function close_all_handles_close_cb(handle: ptr[NativeHandle]) -> void:
89
+ unsafe: ptr[void]<-handle
90
+
91
+
92
+ function noop_waiter(frame: ptr[void]) -> void:
93
+ unsafe: frame
94
+
95
+
96
+ function require_current_runtime() -> Runtime:
97
+ if not current_runtime_active:
98
+ fatal(c"async runtime requires an active runtime; use async.wait or async.run, or call the explicit *_on helpers")
99
+ return current_runtime
100
+
101
+
102
+ function require_live_runtime(runtime: Runtime) -> void:
103
+ if not runtime.active or runtime.loop == null:
104
+ fatal(c"async runtime requires a live runtime")
105
+
106
+
107
+ function live_loop(runtime: Runtime) -> ptr[NativeLoopHandle]:
108
+ require_live_runtime(runtime)
109
+ return unsafe: ptr[NativeLoopHandle]<-runtime.loop
110
+
111
+
112
+ public function current_runtime_handle() -> Runtime:
113
+ return require_current_runtime()
114
+
115
+
116
+ public function runtime_loop(runtime: Runtime) -> ptr[NativeLoopHandle]:
117
+ return live_loop(runtime)
118
+
119
+
120
+ function activate_current_runtime(runtime: Runtime) -> void:
121
+ current_runtime = runtime
122
+ current_runtime_active = true
123
+
124
+
125
+ function deactivate_current_runtime() -> void:
126
+ current_runtime = zero[Runtime]
127
+ current_runtime_active = false
128
+
129
+
130
+ function sleep_task(state: ptr[SleepState]) -> Task[int]:
131
+ return unsafe: Task[int](
132
+ frame = ptr[void]<-state,
133
+ ready = sleep_ready,
134
+ set_waiter = sleep_set_waiter,
135
+ release = sleep_release,
136
+ take_result = sleep_take_result
137
+ )
138
+
139
+
140
+ function work_task[T](state: ptr[WorkState[T]]) -> Task[T]:
141
+ return unsafe: Task[T](
142
+ frame = ptr[void]<-state,
143
+ ready = work_ready[T],
144
+ set_waiter = work_set_waiter[T],
145
+ release = work_release[T],
146
+ take_result = work_take_result[T]
147
+ )
148
+
149
+
150
+ function sleep_timer_close(handle: ptr[NativeHandle]) -> void:
151
+ let state_raw = libuv.handle_get_data(handle) else:
152
+ unsafe: heap.release_bytes(ptr[void]<-handle_as_timer(handle))
153
+ return
154
+
155
+ let state = unsafe: ptr[SleepState]<-state_raw
156
+ unsafe:
157
+ state.closed = true
158
+
159
+ let timer = handle_as_timer(handle)
160
+ heap.release_bytes(ptr[void]<-timer)
161
+ state.timer = null
162
+
163
+ if state.released:
164
+ heap.release(state)
165
+
166
+
167
+ function sleep_timer_fire(timer: ptr[NativeTimerHandle]) -> void:
168
+ let handle = timer_as_handle(timer)
169
+ let state_raw = libuv.handle_get_data(handle) else:
170
+ return
171
+
172
+ let state = unsafe: ptr[SleepState]<-state_raw
173
+ unsafe:
174
+ state.status = 0
175
+ state.ready = true
176
+
177
+ if not state.closing and not state.closed:
178
+ state.closing = true
179
+ libuv.timer_stop(timer)
180
+ libuv.close(handle, sleep_timer_close)
181
+
182
+ if state.waiter_registered:
183
+ state.waiter(ptr[void]<-state.waiter_frame)
184
+
185
+
186
+ public function runtime_create() -> Runtime:
187
+ let loop_size = libuv.loop_size()
188
+ let loop = unsafe: ptr[NativeLoopHandle]<-heap.must_alloc_zeroed_bytes(1, loop_size)
189
+ let init_status = libuv.loop_init(loop)
190
+ if init_status != 0:
191
+ unsafe: heap.release_bytes(ptr[void]<-loop)
192
+ fatal(c"async libuv runtime could not initialize event loop")
193
+
194
+ return Runtime(loop = loop, active = true)
195
+
196
+
197
+ public function runtime_activate(runtime: Runtime) -> void:
198
+ require_live_runtime(runtime)
199
+ activate_current_runtime(runtime)
200
+
201
+
202
+ public function runtime_deactivate() -> void:
203
+ deactivate_current_runtime()
204
+
205
+
206
+ public function runtime_release(runtime: ref[Runtime]) -> void:
207
+ if release_runtime(runtime) != 0:
208
+ fatal(c"async runtime release failed")
209
+
210
+
211
+ public function runtime_poll(runtime: Runtime) -> int:
212
+ return libuv.run(live_loop(runtime), libuv.uv_run_mode.UV_RUN_ONCE)
213
+
214
+
215
+ public function sleep_ready(frame: ptr[void]) -> bool:
216
+ return unsafe: sleep_state(frame).ready
217
+
218
+
219
+ public function sleep_set_waiter(
220
+ frame: ptr[void],
221
+ waiter_frame: ptr[void],
222
+ waiter: fn(frame: ptr[void]) -> void
223
+ ) -> void:
224
+ let state = sleep_state(frame)
225
+ unsafe:
226
+ if state.ready:
227
+ waiter(waiter_frame)
228
+ return
229
+
230
+ state.waiter_frame = waiter_frame
231
+ state.waiter = waiter
232
+ state.waiter_registered = true
233
+
234
+
235
+ public function sleep_release(frame: ptr[void]) -> void:
236
+ let state = sleep_state(frame)
237
+
238
+ unsafe:
239
+ if state.closed:
240
+ heap.release(state)
241
+ return
242
+
243
+ state.released = true
244
+ if state.timer == null:
245
+ heap.release(state)
246
+ return
247
+
248
+ if not state.closing:
249
+ state.closing = true
250
+ let handle = timer_as_handle(unsafe: ptr[NativeTimerHandle]<-state.timer)
251
+ libuv.close(handle, sleep_timer_close)
252
+
253
+
254
+ public function sleep_take_result(frame: ptr[void]) -> int:
255
+ return unsafe: sleep_state(frame).status
256
+
257
+
258
+ public function work_ready[T](frame: ptr[void]) -> bool:
259
+ return work_state[T](frame).ready
260
+
261
+
262
+ function work_execute(req: ptr[NativeWorkRequest]) -> void:
263
+ let state_raw = libuv.req_get_data(work_as_req(req)) else:
264
+ return
265
+
266
+ let state = work_state_base(state_raw)
267
+ unsafe:
268
+ state.execute(ptr[void]<-state)
269
+
270
+
271
+ function work_complete(req: ptr[NativeWorkRequest], status_code: int) -> void:
272
+ let state_raw = libuv.req_get_data(work_as_req(req)) else:
273
+ unsafe: heap.release_bytes(ptr[void]<-req)
274
+ return
275
+
276
+ let state = work_state_base(state_raw)
277
+ unsafe:
278
+ state.status = status_code
279
+ state.ready = true
280
+ state.queued = false
281
+
282
+ if state.waiter_registered:
283
+ state.waiter(ptr[void]<-state.waiter_frame)
284
+
285
+ if state.released:
286
+ if state.work != null:
287
+ heap.release_bytes(ptr[void]<-state.work)
288
+ state.work = null
289
+ heap.release(state)
290
+
291
+
292
+ function work_execute_state[T](state_frame: ptr[void]) -> void:
293
+ let state = work_state[T](state_frame)
294
+ unsafe:
295
+ state.result = state.run_work()
296
+
297
+
298
+ public function work_set_waiter[T](
299
+ frame: ptr[void],
300
+ waiter_frame: ptr[void],
301
+ waiter: fn(frame: ptr[void]) -> void
302
+ ) -> void:
303
+ let state = work_state[T](frame)
304
+ unsafe:
305
+ if state.ready:
306
+ waiter(waiter_frame)
307
+ return
308
+
309
+ state.waiter_frame = waiter_frame
310
+ state.waiter = waiter
311
+ state.waiter_registered = true
312
+
313
+
314
+ public function work_release[T](frame: ptr[void]) -> void:
315
+ let state = work_state[T](frame)
316
+ unsafe:
317
+ if state.ready:
318
+ if state.work != null:
319
+ heap.release_bytes(ptr[void]<-state.work)
320
+ state.work = null
321
+ heap.release(state)
322
+ return
323
+
324
+ state.released = true
325
+ if state.queued and state.work != null:
326
+ libuv.cancel(work_as_req(unsafe: ptr[NativeWorkRequest]<-state.work))
327
+
328
+
329
+ public function work_take_result[T](frame: ptr[void]) -> T:
330
+ let state = work_state[T](frame)
331
+ if state.status != 0:
332
+ fatal(c"async work failed")
333
+ return state.result
334
+
335
+
336
+ public function sleep_on(runtime: Runtime, timeout: ptr_uint) -> Task[int]:
337
+ let loop = live_loop(runtime)
338
+
339
+ let state = heap.must_alloc_zeroed[SleepState](1)
340
+ unsafe:
341
+ state.ready = false
342
+ state.status = 0
343
+ state.waiter_frame = null
344
+ state.waiter = noop_waiter
345
+ state.waiter_registered = false
346
+ state.timer = null
347
+ state.closing = false
348
+ state.closed = false
349
+ state.released = false
350
+
351
+ let timer_size = libuv.handle_size(libuv.uv_handle_type.UV_TIMER)
352
+ let timer = unsafe: ptr[NativeTimerHandle]<-heap.must_alloc_zeroed_bytes(1, timer_size)
353
+ unsafe: state.timer = timer
354
+
355
+ let init_status = libuv.timer_init(loop, timer)
356
+ if init_status != 0:
357
+ unsafe:
358
+ heap.release_bytes(ptr[void]<-timer)
359
+ state.timer = null
360
+ state.closed = true
361
+ state.ready = true
362
+ state.status = init_status
363
+ return sleep_task(state)
364
+
365
+ unsafe:
366
+ libuv.handle_set_data(timer_as_handle(timer), ptr[void]<-state)
367
+
368
+ let start_status = libuv.timer_start(timer, sleep_timer_fire, timeout, 0)
369
+ if start_status != 0:
370
+ unsafe:
371
+ state.status = start_status
372
+ state.ready = true
373
+ state.closing = true
374
+ libuv.close(timer_as_handle(timer), sleep_timer_close)
375
+
376
+ return sleep_task(state)
377
+
378
+
379
+ public function sleep(timeout: ptr_uint) -> Task[int]:
380
+ return sleep_on(require_current_runtime(), timeout)
381
+
382
+
383
+ public function create_runtime() -> Result[Runtime, int]:
384
+ let loop_size = libuv.loop_size()
385
+ let loop = unsafe: ptr[NativeLoopHandle]<-heap.must_alloc_zeroed_bytes(1, loop_size)
386
+ let init_status = libuv.loop_init(loop)
387
+ if init_status != 0:
388
+ unsafe: heap.release_bytes(ptr[void]<-loop)
389
+ return Result[Runtime, int].failure(error= init_status)
390
+
391
+ return Result[Runtime, int].success(value= Runtime(loop = loop, active = true))
392
+
393
+
394
+ public function release_runtime(runtime: ref[Runtime]) -> int:
395
+ if not runtime.active:
396
+ return 0
397
+
398
+ var is_current = false
399
+ if current_runtime_active and current_runtime.loop == runtime.loop:
400
+ is_current = true
401
+
402
+ if runtime.loop == null:
403
+ runtime.active = false
404
+ if is_current:
405
+ runtime_deactivate()
406
+ return 0
407
+
408
+ let loop = unsafe: ptr[NativeLoopHandle]<-runtime.loop
409
+
410
+ var dummy: int = 0
411
+ libuv.walk(loop, close_all_handles_cb, unsafe: ptr[void]<-ptr_of(dummy))
412
+
413
+ var close_status = libuv.loop_close(loop)
414
+ while close_status != 0:
415
+ libuv.run(loop, libuv.uv_run_mode.UV_RUN_DEFAULT)
416
+ close_status = libuv.loop_close(loop)
417
+
418
+ unsafe: heap.release_bytes(ptr[void]<-loop)
419
+ runtime.loop = null
420
+ runtime.active = false
421
+
422
+ if is_current:
423
+ runtime_deactivate()
424
+
425
+ return 0
426
+
427
+
428
+ public function work_on[T](runtime: Runtime, run_work: fn() -> T) -> Task[T]:
429
+ let loop = live_loop(runtime)
430
+ let state = heap.must_alloc_zeroed[WorkState[T]](1)
431
+
432
+ let req_size = libuv.req_size(libuv.uv_req_type.UV_WORK)
433
+ let req = unsafe: ptr[NativeWorkRequest]<-heap.must_alloc_zeroed_bytes(1, req_size)
434
+
435
+ unsafe:
436
+ state.ready = false
437
+ state.status = 0
438
+ state.execute = work_execute_state[T]
439
+ state.run_work = run_work
440
+ state.waiter_frame = null
441
+ state.waiter = noop_waiter
442
+ state.waiter_registered = false
443
+ state.work = req
444
+ state.queued = false
445
+ state.released = false
446
+
447
+ libuv.req_set_data(work_as_req(req), ptr[void]<-state)
448
+
449
+ let queue_status = libuv.queue_work(loop, req, work_execute, work_complete)
450
+ unsafe:
451
+ if queue_status != 0:
452
+ state.status = queue_status
453
+ state.ready = true
454
+ state.queued = false
455
+ else:
456
+ state.queued = true
457
+
458
+ return work_task[T](state)
459
+
460
+
461
+ public function work[T](run_work: fn() -> T) -> Task[T]:
462
+ return work_on[T](require_current_runtime(), run_work)
463
+
464
+
465
+ public function pump(runtime: Runtime) -> void:
466
+ require_live_runtime(runtime)
467
+ runtime_poll(runtime)
468
+
469
+
470
+ public function completed[T](task: Task[T]) -> bool:
471
+ return task.ready(task.frame)
472
+
473
+
474
+ public function result[T](task: Task[T]) -> T:
475
+ if not completed[T](task):
476
+ fatal(c"async.result called before task completed")
477
+
478
+ defer task.release(task.frame)
479
+ return task.take_result(task.frame)
480
+
481
+
482
+ public function wait_on[T](runtime: Runtime, task: Task[T]) -> T:
483
+ require_live_runtime(runtime)
484
+ while not task.ready(task.frame):
485
+ runtime_poll(runtime)
486
+
487
+ defer task.release(task.frame)
488
+ return task.take_result(task.frame)
489
+
490
+
491
+ public function run_on(runtime: Runtime, task: Task[void]) -> void:
492
+ require_live_runtime(runtime)
493
+ while not task.ready(task.frame):
494
+ runtime_poll(runtime)
495
+
496
+ task.take_result(task.frame)
497
+ task.release(task.frame)
498
+
499
+
500
+ public function wait[T](root: proc() -> Task[T]) -> T:
501
+ if current_runtime_active:
502
+ return wait_on[T](current_runtime, root())
503
+
504
+ var runtime = runtime_create()
505
+ runtime_activate(runtime)
506
+ defer runtime_release(ref_of(runtime))
507
+ return wait_on[T](runtime, root())
508
+
509
+
510
+ public function run(root: proc() -> Task[void]) -> void:
511
+ if current_runtime_active:
512
+ run_on(current_runtime, root())
513
+ return
514
+
515
+ var runtime = runtime_create()
516
+ runtime_activate(runtime)
517
+ defer runtime_release(ref_of(runtime))
518
+ run_on(runtime, root())
519
+
520
+
521
+ public function with_runtime[T](body: proc(runtime: Runtime) -> T) -> T:
522
+ if current_runtime_active:
523
+ return body(current_runtime)
524
+
525
+ var runtime = runtime_create()
526
+ runtime_activate(runtime)
527
+ defer runtime_release(ref_of(runtime))
528
+ return body(runtime)
529
+
530
+
531
+ public function run_with_runtime(body: proc(runtime: Runtime) -> void) -> void:
532
+ if current_runtime_active:
533
+ body(current_runtime)
534
+ return
535
+
536
+ var runtime = runtime_create()
537
+ runtime_activate(runtime)
538
+ defer runtime_release(ref_of(runtime))
539
+ body(runtime)