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.async as aio
2
+ import std.bytes as bytes
3
+ import std.deque as deque
4
+ import std.net as net
5
+ import std.net.clock as clock
6
+ import std.net.mux as mux
7
+ import std.net.session as sess
8
+ import std.string as string
9
+ import std.vec as vec
10
+
11
+ const channel_system: ubyte = 0
12
+
13
+ const type_assign_id: ushort = 0xF000
14
+
15
+ const assign_id_bytes: ptr_uint = 4
16
+
17
+ public struct NetworkConfig:
18
+ max_payload_bytes: ptr_uint
19
+ max_players: ubyte
20
+
21
+ public enum NetworkEventKind: ubyte
22
+ connected = 0
23
+ disconnected = 1
24
+ player_joined = 2
25
+ player_left = 3
26
+ message = 4
27
+
28
+ public struct NetworkEvent:
29
+ kind: NetworkEventKind
30
+ player_id: uint
31
+ channel_id: ubyte
32
+ type_id: ushort
33
+ payload: bytes.Bytes
34
+
35
+ public struct NetworkManager:
36
+ is_server: bool
37
+ max_players: ubyte
38
+ mux_session: mux.MuxedSession
39
+ mux_connection: mux.MuxedConnection
40
+ local_player_id: uint
41
+ players: vec.Vec[PlayerState]
42
+ next_player_id: uint
43
+ events: deque.Deque[NetworkEvent]
44
+ tick_clock: clock.TickClock
45
+ connected: bool
46
+ config: NetworkConfig
47
+ stored_peer_id_events: deque.Deque[PlayerJoinEvent]
48
+
49
+ struct PlayerState:
50
+ player_id: uint
51
+ connected: bool
52
+
53
+ struct PlayerJoinEvent:
54
+ player_id: uint
55
+
56
+
57
+ extending PlayerJoinEvent:
58
+ public editable function release() -> void:
59
+ pass
60
+
61
+
62
+ extending NetworkConfig:
63
+ public static function default(max_payload_bytes: ptr_uint) -> NetworkConfig:
64
+ return NetworkConfig(
65
+ max_payload_bytes = max_payload_bytes,
66
+ max_players = 8
67
+ )
68
+
69
+
70
+ extending NetworkEvent:
71
+ public editable function release() -> void:
72
+ this.payload.release()
73
+
74
+
75
+ public static function connected(player_id: uint) -> NetworkEvent:
76
+ return NetworkEvent(
77
+ kind = NetworkEventKind.connected,
78
+ player_id = player_id,
79
+ channel_id = 0ub,
80
+ type_id = 0us,
81
+ payload = bytes.Bytes.empty()
82
+ )
83
+
84
+
85
+ public static function disconnected() -> NetworkEvent:
86
+ return NetworkEvent(
87
+ kind = NetworkEventKind.disconnected,
88
+ player_id = 0u,
89
+ channel_id = 0ub,
90
+ type_id = 0us,
91
+ payload = bytes.Bytes.empty()
92
+ )
93
+
94
+
95
+ public static function player_joined(player_id: uint) -> NetworkEvent:
96
+ return NetworkEvent(
97
+ kind = NetworkEventKind.player_joined,
98
+ player_id = player_id,
99
+ channel_id = 0ub,
100
+ type_id = 0us,
101
+ payload = bytes.Bytes.empty()
102
+ )
103
+
104
+
105
+ public static function player_left(player_id: uint) -> NetworkEvent:
106
+ return NetworkEvent(
107
+ kind = NetworkEventKind.player_left,
108
+ player_id = player_id,
109
+ channel_id = 0ub,
110
+ type_id = 0us,
111
+ payload = bytes.Bytes.empty()
112
+ )
113
+
114
+
115
+ public static function message_event(
116
+ player_id: uint,
117
+ channel_id: ubyte,
118
+ type_id: ushort,
119
+ payload: bytes.Bytes
120
+ ) -> NetworkEvent:
121
+ return NetworkEvent(
122
+ kind = NetworkEventKind.message,
123
+ player_id = player_id,
124
+ channel_id = channel_id,
125
+ type_id = type_id,
126
+ payload = payload
127
+ )
128
+
129
+
130
+ function mux_config_for(config: NetworkConfig) -> mux.MuxedConfig:
131
+ return mux.MuxedConfig(
132
+ fragment_size = config.max_payload_bytes,
133
+ fragment_timeout_frames = 120
134
+ )
135
+
136
+
137
+ function build_assign_id(player_id: uint) -> bytes.Bytes:
138
+ let encoded = encode_uint(player_id)
139
+ return bytes.Bytes.copy(encoded.as_span())
140
+
141
+
142
+ function parse_assign_id(payload: span[ubyte]) -> Result[uint, net.Error]:
143
+ if payload.len < assign_id_bytes:
144
+ return Result[uint, net.Error].failure(error = net.net_error("assign id payload too short"))
145
+ return Result[uint, net.Error].success(value = decode_uint(payload, 0))
146
+
147
+
148
+ function encode_uint(value: uint) -> array[ubyte, 4]:
149
+ return array[ubyte, 4](
150
+ ubyte<-((value >> 24) & 255),
151
+ ubyte<-((value >> 16) & 255),
152
+ ubyte<-((value >> 8) & 255),
153
+ ubyte<-(value & 255)
154
+ )
155
+
156
+
157
+ function decode_uint(data: span[ubyte], offset: ptr_uint) -> uint:
158
+ return (
159
+ ((uint<-data[offset]) << 24)
160
+ | ((uint<-data[offset + 1]) << 16)
161
+ | ((uint<-data[offset + 2]) << 8)
162
+ | (uint<-data[offset + 3])
163
+ )
164
+
165
+
166
+ extending NetworkManager:
167
+ public editable function release() -> void:
168
+ this.mux_session.release()
169
+ this.mux_connection.release()
170
+
171
+ while true:
172
+ let ev = this.events.pop_front()
173
+ match ev:
174
+ Option.none:
175
+ break
176
+ Option.some as p:
177
+ var e = p.value
178
+ e.release()
179
+
180
+ this.events.release()
181
+
182
+ while true:
183
+ let je = this.stored_peer_id_events.pop_front()
184
+ match je:
185
+ Option.none:
186
+ break
187
+ Option.some as p:
188
+ var j = p.value
189
+ j.release()
190
+
191
+ this.stored_peer_id_events.release()
192
+
193
+ this.players.release()
194
+
195
+
196
+ public function is_server() -> bool:
197
+ return this.is_server
198
+
199
+
200
+ public function is_connected() -> bool:
201
+ return this.connected
202
+
203
+
204
+ public function local_player_id() -> uint:
205
+ return this.local_player_id
206
+
207
+
208
+ public function player_count() -> ptr_uint:
209
+ return this.players.len()
210
+
211
+
212
+ public function get_player(player_id: uint) -> Option[PlayerState]:
213
+ var index: ptr_uint = 0
214
+ while index < this.players.len():
215
+ let player_ptr = this.players.get(index) else:
216
+ return Option[PlayerState].none
217
+ if unsafe: read(player_ptr).player_id == player_id:
218
+ return Option[PlayerState].some(value = unsafe: read(player_ptr))
219
+ index += 1
220
+ return Option[PlayerState].none
221
+
222
+
223
+ public function config() -> NetworkConfig:
224
+ return this.config
225
+
226
+
227
+ public async editable function tick(frame: uint) -> Result[bool, net.Error]:
228
+ this.tick_clock.advance()
229
+
230
+ if this.is_server:
231
+ return await tick_server(ref_of(this), frame)
232
+ return await tick_client(ref_of(this), frame)
233
+
234
+
235
+ public editable function try_recv() -> Option[NetworkEvent]:
236
+ return this.events.pop_front()
237
+
238
+
239
+ public async editable function send_to_server(
240
+ channel_id: ubyte,
241
+ type_id: ushort,
242
+ payload: span[ubyte],
243
+ send_flags: ubyte
244
+ ) -> Result[bool, net.Error]:
245
+ if this.is_server:
246
+ return Result[bool, net.Error].failure(
247
+ error = net.net_error("send_to_server requires a client manager")
248
+ )
249
+
250
+ match await this.mux_connection.mux_send(channel_id, type_id, payload, send_flags):
251
+ Result.failure as p:
252
+ return Result[bool, net.Error].failure(error = p.error)
253
+ Result.success:
254
+ return Result[bool, net.Error].success(value = true)
255
+
256
+
257
+ public async editable function send_to(
258
+ player_id: uint,
259
+ channel_id: ubyte,
260
+ type_id: ushort,
261
+ payload: span[ubyte],
262
+ send_flags: ubyte
263
+ ) -> Result[bool, net.Error]:
264
+ if not this.is_server:
265
+ return Result[bool, net.Error].failure(
266
+ error = net.net_error("send_to requires a server manager")
267
+ )
268
+
269
+ match await this.mux_session.mux_send(player_id, channel_id, type_id, payload, send_flags):
270
+ Result.failure as p:
271
+ return Result[bool, net.Error].failure(error = p.error)
272
+ Result.success:
273
+ return Result[bool, net.Error].success(value = true)
274
+
275
+
276
+ public async editable function broadcast(
277
+ channel_id: ubyte,
278
+ type_id: ushort,
279
+ payload: span[ubyte],
280
+ send_flags: ubyte
281
+ ) -> Result[bool, net.Error]:
282
+ if not this.is_server:
283
+ return Result[bool, net.Error].failure(
284
+ error = net.net_error("broadcast requires a server manager")
285
+ )
286
+
287
+ var index: ptr_uint = 0
288
+ while index < this.players.len():
289
+ let player_ptr = this.players.get(index) else:
290
+ break
291
+
292
+ if unsafe: read(player_ptr).connected:
293
+ let peer_id = unsafe: read(player_ptr).player_id
294
+ match await this.mux_session.mux_send(peer_id, channel_id, type_id, payload, send_flags):
295
+ Result.failure as p:
296
+ return Result[bool, net.Error].failure(error = p.error)
297
+ Result.success:
298
+ pass
299
+
300
+ index += 1
301
+
302
+ return Result[bool, net.Error].success(value = true)
303
+
304
+
305
+ public async editable function rpc_server(rpc_id: ushort, data: span[ubyte]) -> Result[bool, net.Error]:
306
+ return await this.send_to_server(channel_system, rpc_id, data, mux.flag_reliable)
307
+
308
+
309
+ public async editable function rpc_to(
310
+ player_id: uint,
311
+ rpc_id: ushort,
312
+ data: span[ubyte]
313
+ ) -> Result[bool, net.Error]:
314
+ return await this.send_to(player_id, channel_system, rpc_id, data, mux.flag_reliable)
315
+
316
+
317
+ public async editable function rpc_all(rpc_id: ushort, data: span[ubyte]) -> Result[bool, net.Error]:
318
+ return await this.broadcast(channel_system, rpc_id, data, mux.flag_reliable)
319
+
320
+
321
+ public function create_server(
322
+ address: net.SocketAddress,
323
+ config: NetworkConfig
324
+ ) -> Result[NetworkManager, net.Error]:
325
+ let mux_config = mux_config_for(config)
326
+ match mux.mux_listen(address, mux_config):
327
+ Result.failure as p:
328
+ return Result[NetworkManager, net.Error].failure(error = p.error)
329
+ Result.success as session_p:
330
+ let mgr = NetworkManager(
331
+ is_server = true,
332
+ max_players = config.max_players,
333
+ mux_session = session_p.value,
334
+ mux_connection = unsafe: zero[mux.MuxedConnection],
335
+ local_player_id = 0u,
336
+ players = vec.Vec[PlayerState].create(),
337
+ next_player_id = 1u,
338
+ events = deque.Deque[NetworkEvent].create(),
339
+ tick_clock = clock.TickClock(tick = 0u, rate = 60u, epoch = clock.monotonic_ns()),
340
+ connected = true,
341
+ config = config,
342
+ stored_peer_id_events = deque.Deque[PlayerJoinEvent].create()
343
+ )
344
+ return Result[NetworkManager, net.Error].success(value = mgr)
345
+
346
+
347
+ public function create_client(
348
+ local_address: net.SocketAddress,
349
+ server_address: net.SocketAddress,
350
+ config: NetworkConfig
351
+ ) -> Result[NetworkManager, net.Error]:
352
+ let mux_config = mux_config_for(config)
353
+ match mux.mux_connect_on(aio.current_runtime(), local_address, server_address, mux_config):
354
+ Result.failure as p:
355
+ return Result[NetworkManager, net.Error].failure(error = p.error)
356
+ Result.success as mux_conn_p:
357
+ let client_mgr = NetworkManager(
358
+ is_server = false,
359
+ max_players = config.max_players,
360
+ mux_session = unsafe: zero[mux.MuxedSession],
361
+ mux_connection = mux_conn_p.value,
362
+ local_player_id = 0u,
363
+ players = vec.Vec[PlayerState].create(),
364
+ next_player_id = 0u,
365
+ events = deque.Deque[NetworkEvent].create(),
366
+ tick_clock = clock.TickClock(tick = 0u, rate = 60u, epoch = clock.monotonic_ns()),
367
+ connected = false,
368
+ config = config,
369
+ stored_peer_id_events = deque.Deque[PlayerJoinEvent].create()
370
+ )
371
+ return Result[NetworkManager, net.Error].success(value = client_mgr)
372
+
373
+
374
+ async function tick_server(manager: ref[NetworkManager], frame: uint) -> Result[bool, net.Error]:
375
+ await process_stored_peer_id_events(manager)
376
+
377
+ match await manager.mux_session.tick(frame):
378
+ Result.failure as p:
379
+ return Result[bool, net.Error].failure(error = p.error)
380
+ Result.success:
381
+ pass
382
+
383
+ drain_mux_events_server(manager)
384
+
385
+ return Result[bool, net.Error].success(value = true)
386
+
387
+
388
+ async function tick_client(manager: ref[NetworkManager], frame: uint) -> Result[bool, net.Error]:
389
+ if manager.mux_connection.state() == sess.ConnectionState.disconnected:
390
+ match await manager.mux_connection.connect_to_peer():
391
+ Result.failure as p:
392
+ return Result[bool, net.Error].failure(error = p.error)
393
+ Result.success:
394
+ pass
395
+
396
+ match await manager.mux_connection.tick(frame):
397
+ Result.failure as p:
398
+ if manager.connected:
399
+ manager.connected = false
400
+ manager.events.push_back(NetworkEvent.disconnected())
401
+ return Result[bool, net.Error].failure(error = p.error)
402
+ Result.success:
403
+ pass
404
+
405
+ drain_mux_events_client(manager)
406
+
407
+ return Result[bool, net.Error].success(value = true)
408
+
409
+
410
+ async function process_stored_peer_id_events(manager: ref[NetworkManager]) -> void:
411
+ while true:
412
+ let je = manager.stored_peer_id_events.pop_front()
413
+ match je:
414
+ Option.none:
415
+ break
416
+ Option.some as p:
417
+ var join_event = p.value
418
+ let player_id = join_event.player_id
419
+ join_event.release()
420
+ var assign_data = build_assign_id(player_id)
421
+ defer assign_data.release()
422
+ let _ = await manager.mux_session.mux_send(
423
+ player_id,
424
+ channel_system,
425
+ type_assign_id,
426
+ assign_data.as_span(),
427
+ mux.flag_reliable
428
+ )
429
+
430
+
431
+ function drain_mux_events_server(manager: ref[NetworkManager]) -> void:
432
+ while true:
433
+ let ev = manager.mux_session.try_recv()
434
+ match ev:
435
+ Option.none:
436
+ break
437
+ Option.some as p:
438
+ var msg = p.value
439
+ handle_mux_message_server(manager, ref_of(msg))
440
+
441
+
442
+ function drain_mux_events_client(manager: ref[NetworkManager]) -> void:
443
+ while true:
444
+ let ev = manager.mux_connection.try_recv()
445
+ match ev:
446
+ Option.none:
447
+ break
448
+ Option.some as p:
449
+ var msg = p.value
450
+ handle_mux_message_client(manager, ref_of(msg))
451
+
452
+
453
+ function handle_mux_message_server(manager: ref[NetworkManager], msg: ref[mux.MuxedMessage]) -> void:
454
+ if msg.channel_id == mux.meta_channel:
455
+ if msg.type_id == mux.type_peer_joined:
456
+ let peer_id = msg.peer_id
457
+ msg.release()
458
+
459
+ ensure_player_slot(manager, peer_id)
460
+ manager.stored_peer_id_events.push_back(PlayerJoinEvent(player_id = peer_id))
461
+ return
462
+
463
+ if msg.type_id == mux.type_peer_left:
464
+ let peer_id = msg.peer_id
465
+ msg.release()
466
+
467
+ mark_player_disconnected(manager, peer_id)
468
+ manager.events.push_back(NetworkEvent.player_left(peer_id))
469
+ return
470
+
471
+ msg.release()
472
+ return
473
+
474
+ if msg.channel_id == channel_system and msg.type_id == type_assign_id:
475
+ msg.release()
476
+ return
477
+
478
+ manager.events.push_back(NetworkEvent.message_event(
479
+ msg.peer_id,
480
+ msg.channel_id,
481
+ msg.type_id,
482
+ msg.payload
483
+ ))
484
+
485
+ unsafe:
486
+ read(ptr[mux.MuxedMessage]<-msg).payload = bytes.Bytes.empty()
487
+
488
+
489
+ function handle_mux_message_client(manager: ref[NetworkManager], msg: ref[mux.MuxedMessage]) -> void:
490
+ if msg.channel_id == mux.meta_channel:
491
+ msg.release()
492
+ return
493
+
494
+ if msg.channel_id == channel_system and msg.type_id == type_assign_id:
495
+ let id_result = parse_assign_id(msg.payload.as_span())
496
+ match id_result:
497
+ Result.success as p:
498
+ manager.local_player_id = p.value
499
+ manager.connected = true
500
+ manager.events.push_back(NetworkEvent.connected(p.value))
501
+ Result.failure:
502
+ pass
503
+ msg.release()
504
+ return
505
+
506
+ manager.events.push_back(NetworkEvent.message_event(
507
+ msg.peer_id,
508
+ msg.channel_id,
509
+ msg.type_id,
510
+ msg.payload
511
+ ))
512
+
513
+ unsafe:
514
+ read(ptr[mux.MuxedMessage]<-msg).payload = bytes.Bytes.empty()
515
+
516
+
517
+ function ensure_player_slot(manager: ref[NetworkManager], player_id: uint) -> void:
518
+ var index: ptr_uint = 0
519
+ while index < manager.players.len():
520
+ let player_ptr = manager.players.get(index) else:
521
+ break
522
+ if unsafe: read(player_ptr).player_id == player_id:
523
+ unsafe: read(player_ptr).connected = true
524
+ return
525
+ index += 1
526
+
527
+ manager.players.push(PlayerState(player_id = player_id, connected = true))
528
+ manager.events.push_back(NetworkEvent.player_joined(player_id))
529
+
530
+
531
+ function mark_player_disconnected(manager: ref[NetworkManager], player_id: uint) -> void:
532
+ var index: ptr_uint = 0
533
+ while index < manager.players.len():
534
+ let player_ptr = manager.players.get(index) else:
535
+ break
536
+ if unsafe: read(player_ptr).player_id == player_id:
537
+ unsafe: read(player_ptr).connected = false
538
+ return
539
+ index += 1