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
data/std/net/mux.mt
ADDED
|
@@ -0,0 +1,839 @@
|
|
|
1
|
+
import std.async as aio
|
|
2
|
+
import std.binary as bin
|
|
3
|
+
import std.bytes as bytes
|
|
4
|
+
import std.deque as deque
|
|
5
|
+
import std.mem.heap as heap
|
|
6
|
+
import std.net as net
|
|
7
|
+
import std.net.session as sess
|
|
8
|
+
import std.vec as vec
|
|
9
|
+
|
|
10
|
+
public const flag_reliable: ubyte = 0x01
|
|
11
|
+
public const flag_fragmented: ubyte = 0x04
|
|
12
|
+
|
|
13
|
+
public const meta_channel: ubyte = 0xFF
|
|
14
|
+
public const type_peer_joined: ushort = 0xFFFE
|
|
15
|
+
public const type_peer_left: ushort = 0xFFFD
|
|
16
|
+
|
|
17
|
+
const wire_header_size: ptr_uint = 4
|
|
18
|
+
const fragment_header_size: ptr_uint = 6
|
|
19
|
+
|
|
20
|
+
public struct MuxedSendOptions:
|
|
21
|
+
reliable: bool
|
|
22
|
+
fragmented: bool
|
|
23
|
+
|
|
24
|
+
public struct MuxedConfig:
|
|
25
|
+
fragment_size: ptr_uint
|
|
26
|
+
fragment_timeout_frames: uint
|
|
27
|
+
|
|
28
|
+
public struct MuxedMessage:
|
|
29
|
+
peer_id: uint
|
|
30
|
+
channel_id: ubyte
|
|
31
|
+
type_id: ushort
|
|
32
|
+
msg_flags: ubyte
|
|
33
|
+
payload: bytes.Bytes
|
|
34
|
+
|
|
35
|
+
public struct MuxedConnection:
|
|
36
|
+
conn: sess.Connection
|
|
37
|
+
config: MuxedConfig
|
|
38
|
+
event_queue: deque.Deque[MuxedMessage]
|
|
39
|
+
frag_buffers: vec.Vec[FragBuffer]
|
|
40
|
+
next_group_id: ushort
|
|
41
|
+
current_frame: uint
|
|
42
|
+
|
|
43
|
+
public struct MuxedSession:
|
|
44
|
+
session: sess.Session
|
|
45
|
+
config: MuxedConfig
|
|
46
|
+
event_queue: deque.Deque[MuxedMessage]
|
|
47
|
+
frag_buffers: vec.Vec[FragBuffer]
|
|
48
|
+
next_group_id: ushort
|
|
49
|
+
current_frame: uint
|
|
50
|
+
|
|
51
|
+
struct FragBuffer:
|
|
52
|
+
group_id: ushort
|
|
53
|
+
peer_id: uint
|
|
54
|
+
channel_id: ubyte
|
|
55
|
+
type_id: ushort
|
|
56
|
+
msg_flags: ubyte
|
|
57
|
+
total: ushort
|
|
58
|
+
received_count: ushort
|
|
59
|
+
received_bits: uint
|
|
60
|
+
data: bytes.Bytes
|
|
61
|
+
last_frame: uint
|
|
62
|
+
|
|
63
|
+
struct WireHeader:
|
|
64
|
+
channel_id: ubyte
|
|
65
|
+
type_id: ushort
|
|
66
|
+
msg_flags: ubyte
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
extending MuxedSendOptions:
|
|
70
|
+
public function to_flags() -> ubyte:
|
|
71
|
+
var send_flags: ubyte = 0
|
|
72
|
+
if this.reliable:
|
|
73
|
+
send_flags |= flag_reliable
|
|
74
|
+
if this.fragmented:
|
|
75
|
+
send_flags |= flag_fragmented
|
|
76
|
+
return send_flags
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
extending MuxedConfig:
|
|
80
|
+
public static function default() -> MuxedConfig:
|
|
81
|
+
return MuxedConfig(
|
|
82
|
+
fragment_size = 1000,
|
|
83
|
+
fragment_timeout_frames = 120
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
extending MuxedMessage:
|
|
88
|
+
public editable function release() -> void:
|
|
89
|
+
this.payload.release()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
public function mux_connect_on(
|
|
93
|
+
runtime: aio.Runtime,
|
|
94
|
+
local_address: net.SocketAddress,
|
|
95
|
+
remote_address: net.SocketAddress,
|
|
96
|
+
config: MuxedConfig
|
|
97
|
+
) -> Result[MuxedConnection, net.Error]:
|
|
98
|
+
let payload_size = config.fragment_size + wire_header_size + fragment_header_size + 32
|
|
99
|
+
let session_config = sess.Config.default(payload_size)
|
|
100
|
+
let conn_result = sess.connect_on(runtime, local_address, remote_address, session_config)
|
|
101
|
+
match conn_result:
|
|
102
|
+
Result.failure as p:
|
|
103
|
+
return Result[MuxedConnection, net.Error].failure(
|
|
104
|
+
error = p.error
|
|
105
|
+
)
|
|
106
|
+
Result.success as p:
|
|
107
|
+
let conn = MuxedConnection(
|
|
108
|
+
conn = p.value,
|
|
109
|
+
config = config,
|
|
110
|
+
event_queue = deque.Deque[MuxedMessage].create(),
|
|
111
|
+
frag_buffers = vec.Vec[FragBuffer].create(),
|
|
112
|
+
next_group_id = 1,
|
|
113
|
+
current_frame = 0
|
|
114
|
+
)
|
|
115
|
+
return Result[MuxedConnection, net.Error].success(value = conn)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
public async function mux_connect(
|
|
119
|
+
local_address: net.SocketAddress,
|
|
120
|
+
remote_address: net.SocketAddress,
|
|
121
|
+
config: MuxedConfig
|
|
122
|
+
) -> Result[MuxedConnection, net.Error]:
|
|
123
|
+
match mux_connect_on(aio.current_runtime(), local_address, remote_address, config):
|
|
124
|
+
Result.failure as p:
|
|
125
|
+
return Result[MuxedConnection, net.Error].failure(error = p.error)
|
|
126
|
+
Result.success as p:
|
|
127
|
+
var mux_conn = p.value
|
|
128
|
+
match await mux_conn.connect_to_peer():
|
|
129
|
+
Result.failure as cp:
|
|
130
|
+
mux_conn.release()
|
|
131
|
+
return Result[MuxedConnection, net.Error].failure(error = cp.error)
|
|
132
|
+
Result.success:
|
|
133
|
+
return Result[MuxedConnection, net.Error].success(value = mux_conn)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
public function mux_listen_on(
|
|
137
|
+
runtime: aio.Runtime,
|
|
138
|
+
local_address: net.SocketAddress,
|
|
139
|
+
config: MuxedConfig
|
|
140
|
+
) -> Result[MuxedSession, net.Error]:
|
|
141
|
+
let payload_size = config.fragment_size + wire_header_size + fragment_header_size + 32
|
|
142
|
+
let session_config = sess.Config.default(payload_size)
|
|
143
|
+
let listen_result = sess.listen_on(runtime, local_address, session_config)
|
|
144
|
+
match listen_result:
|
|
145
|
+
Result.failure as p:
|
|
146
|
+
return Result[MuxedSession, net.Error].failure(
|
|
147
|
+
error = p.error
|
|
148
|
+
)
|
|
149
|
+
Result.success as p:
|
|
150
|
+
return Result[MuxedSession, net.Error].success(value = MuxedSession(
|
|
151
|
+
session = p.value,
|
|
152
|
+
config = config,
|
|
153
|
+
event_queue = deque.Deque[MuxedMessage].create(),
|
|
154
|
+
frag_buffers = vec.Vec[FragBuffer].create(),
|
|
155
|
+
next_group_id = 1,
|
|
156
|
+
current_frame = 0
|
|
157
|
+
))
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
public function mux_listen(
|
|
161
|
+
local_address: net.SocketAddress,
|
|
162
|
+
config: MuxedConfig
|
|
163
|
+
) -> Result[MuxedSession, net.Error]:
|
|
164
|
+
return mux_listen_on(aio.current_runtime(), local_address, config)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
extending MuxedConnection:
|
|
168
|
+
public editable function release() -> void:
|
|
169
|
+
release_frag_buffers(ref_of(this.frag_buffers))
|
|
170
|
+
this.frag_buffers.release()
|
|
171
|
+
release_event_queue(ref_of(this.event_queue))
|
|
172
|
+
this.event_queue.release()
|
|
173
|
+
this.conn.release()
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
public function state() -> sess.ConnectionState:
|
|
177
|
+
return this.conn.state()
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
public function local_address() -> Result[net.SocketAddress, net.Error]:
|
|
181
|
+
return this.conn.local_address()
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
public function peer_address() -> Result[net.SocketAddress, net.Error]:
|
|
185
|
+
return this.conn.peer_address()
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
public async editable function connect_to_peer() -> Result[bool, net.Error]:
|
|
189
|
+
match await this.conn.connect_to_peer():
|
|
190
|
+
Result.failure as p:
|
|
191
|
+
return Result[bool, net.Error].failure(error = p.error)
|
|
192
|
+
Result.success as p:
|
|
193
|
+
return Result[bool, net.Error].success(value = p.value)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
public async editable function tick(frame: uint) -> Result[bool, net.Error]:
|
|
197
|
+
this.current_frame = frame
|
|
198
|
+
let conn_result = await this.conn.tick(frame)
|
|
199
|
+
drain_incoming_conn(ref_of(this))
|
|
200
|
+
prune_frag_buffers(ref_of(this.frag_buffers), frame, this.config.fragment_timeout_frames)
|
|
201
|
+
match conn_result:
|
|
202
|
+
Result.failure as p:
|
|
203
|
+
return Result[bool, net.Error].failure(error = p.error)
|
|
204
|
+
Result.success as p:
|
|
205
|
+
return Result[bool, net.Error].success(value = p.value)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
public editable function try_recv() -> Option[MuxedMessage]:
|
|
209
|
+
return this.event_queue.pop_front()
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
public async editable function recv() -> Result[Option[MuxedMessage], net.Error]:
|
|
213
|
+
while true:
|
|
214
|
+
let ev = this.try_recv()
|
|
215
|
+
match ev:
|
|
216
|
+
Option.some as p:
|
|
217
|
+
return Result[Option[MuxedMessage], net.Error].success(
|
|
218
|
+
value = Option[MuxedMessage].some(value = p.value)
|
|
219
|
+
)
|
|
220
|
+
Option.none:
|
|
221
|
+
let sess_result = await this.conn.recv()
|
|
222
|
+
match sess_result:
|
|
223
|
+
Result.failure as p:
|
|
224
|
+
return Result[Option[MuxedMessage], net.Error].failure(
|
|
225
|
+
error = p.error
|
|
226
|
+
)
|
|
227
|
+
Result.success as sess_p:
|
|
228
|
+
match sess_p.value:
|
|
229
|
+
Option.none:
|
|
230
|
+
pass
|
|
231
|
+
Option.some as msg_p:
|
|
232
|
+
var msg = msg_p.value
|
|
233
|
+
demux_conn(ref_of(this), ref_of(msg), this.current_frame)
|
|
234
|
+
let queued = this.try_recv()
|
|
235
|
+
match queued:
|
|
236
|
+
Option.some as q:
|
|
237
|
+
return Result[Option[MuxedMessage], net.Error].success(
|
|
238
|
+
value = Option[MuxedMessage].some(value = q.value)
|
|
239
|
+
)
|
|
240
|
+
Option.none:
|
|
241
|
+
pass
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
public async editable function mux_send(
|
|
245
|
+
channel_id: ubyte,
|
|
246
|
+
type_id: ushort,
|
|
247
|
+
data: span[ubyte],
|
|
248
|
+
send_flags: ubyte
|
|
249
|
+
) -> Result[bool, net.Error]:
|
|
250
|
+
if (send_flags & flag_fragmented) != 0 and data.len > this.config.fragment_size:
|
|
251
|
+
return await send_fragmented_conn(ref_of(this), channel_id, type_id, data, send_flags)
|
|
252
|
+
return await send_single_conn(ref_of(this), channel_id, type_id, data, send_flags)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
public async editable function disconnect() -> Result[bool, net.Error]:
|
|
256
|
+
match await this.conn.disconnect_peer():
|
|
257
|
+
Result.failure as p:
|
|
258
|
+
return Result[bool, net.Error].failure(error = p.error)
|
|
259
|
+
Result.success as p:
|
|
260
|
+
return Result[bool, net.Error].success(value = p.value)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
extending MuxedSession:
|
|
264
|
+
public editable function release() -> void:
|
|
265
|
+
release_frag_buffers(ref_of(this.frag_buffers))
|
|
266
|
+
this.frag_buffers.release()
|
|
267
|
+
release_event_queue(ref_of(this.event_queue))
|
|
268
|
+
this.event_queue.release()
|
|
269
|
+
this.session.release()
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
public function local_address() -> Result[net.SocketAddress, net.Error]:
|
|
273
|
+
return this.session.local_address()
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
public function peer_count() -> ptr_uint:
|
|
277
|
+
return this.session.peer_count()
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
public async editable function tick(frame: uint) -> Result[bool, net.Error]:
|
|
281
|
+
this.current_frame = frame
|
|
282
|
+
let sess_result = await this.session.tick(frame)
|
|
283
|
+
drain_incoming_session(ref_of(this))
|
|
284
|
+
prune_frag_buffers(ref_of(this.frag_buffers), frame, this.config.fragment_timeout_frames)
|
|
285
|
+
match sess_result:
|
|
286
|
+
Result.failure as p:
|
|
287
|
+
return Result[bool, net.Error].failure(error = p.error)
|
|
288
|
+
Result.success as p:
|
|
289
|
+
return Result[bool, net.Error].success(value = p.value)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
public editable function try_recv() -> Option[MuxedMessage]:
|
|
293
|
+
return this.event_queue.pop_front()
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
public async editable function recv() -> Result[Option[MuxedMessage], net.Error]:
|
|
297
|
+
while true:
|
|
298
|
+
let ev = this.try_recv()
|
|
299
|
+
match ev:
|
|
300
|
+
Option.some as p:
|
|
301
|
+
return Result[Option[MuxedMessage], net.Error].success(
|
|
302
|
+
value = Option[MuxedMessage].some(value = p.value)
|
|
303
|
+
)
|
|
304
|
+
Option.none:
|
|
305
|
+
let sess_result = await this.session.recv()
|
|
306
|
+
match sess_result:
|
|
307
|
+
Result.failure as p:
|
|
308
|
+
return Result[Option[MuxedMessage], net.Error].failure(
|
|
309
|
+
error = p.error
|
|
310
|
+
)
|
|
311
|
+
Result.success as sess_p:
|
|
312
|
+
match sess_p.value:
|
|
313
|
+
Option.none:
|
|
314
|
+
pass
|
|
315
|
+
Option.some as msg_p:
|
|
316
|
+
var msg = msg_p.value
|
|
317
|
+
demux_session(ref_of(this), ref_of(msg), this.current_frame)
|
|
318
|
+
let queued = this.try_recv()
|
|
319
|
+
match queued:
|
|
320
|
+
Option.some as q:
|
|
321
|
+
return Result[Option[MuxedMessage], net.Error].success(
|
|
322
|
+
value = Option[MuxedMessage].some(value = q.value)
|
|
323
|
+
)
|
|
324
|
+
Option.none:
|
|
325
|
+
pass
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
public async editable function mux_send(
|
|
329
|
+
peer_id: uint,
|
|
330
|
+
channel_id: ubyte,
|
|
331
|
+
type_id: ushort,
|
|
332
|
+
data: span[ubyte],
|
|
333
|
+
send_flags: ubyte
|
|
334
|
+
) -> Result[bool, net.Error]:
|
|
335
|
+
if (send_flags & flag_fragmented) != 0 and data.len > this.config.fragment_size:
|
|
336
|
+
return await send_fragmented_session(ref_of(this), peer_id, channel_id, type_id, data, send_flags)
|
|
337
|
+
return await send_single_session(ref_of(this), peer_id, channel_id, type_id, data, send_flags)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
public async editable function kick(peer_id: uint, reason: ubyte) -> Result[bool, net.Error]:
|
|
341
|
+
match await this.session.kick(peer_id, reason):
|
|
342
|
+
Result.failure as p:
|
|
343
|
+
return Result[bool, net.Error].failure(error = p.error)
|
|
344
|
+
Result.success as p:
|
|
345
|
+
return Result[bool, net.Error].success(value = p.value)
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
function encode_frame(channel_id: ubyte, type_id: ushort, msg_flags: ubyte, payload: span[ubyte]) -> bytes.Bytes:
|
|
349
|
+
var w = bin.Writer.with_capacity(wire_header_size + payload.len)
|
|
350
|
+
w.write_ubyte(channel_id)
|
|
351
|
+
w.write_ushort(type_id)
|
|
352
|
+
w.write_ubyte(msg_flags)
|
|
353
|
+
w.write_bytes(payload)
|
|
354
|
+
return w.finish()
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
function encode_fragment_frame(
|
|
358
|
+
channel_id: ubyte,
|
|
359
|
+
type_id: ushort,
|
|
360
|
+
msg_flags: ubyte,
|
|
361
|
+
group_id: ushort,
|
|
362
|
+
frag_index: ushort,
|
|
363
|
+
total: ushort,
|
|
364
|
+
payload: span[ubyte]
|
|
365
|
+
) -> bytes.Bytes:
|
|
366
|
+
var w = bin.Writer.with_capacity(wire_header_size + fragment_header_size + payload.len)
|
|
367
|
+
w.write_ubyte(channel_id)
|
|
368
|
+
w.write_ushort(type_id)
|
|
369
|
+
w.write_ubyte(msg_flags | flag_fragmented)
|
|
370
|
+
w.write_ushort(group_id)
|
|
371
|
+
w.write_ushort(frag_index)
|
|
372
|
+
w.write_ushort(total)
|
|
373
|
+
w.write_bytes(payload)
|
|
374
|
+
return w.finish()
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
async function send_single_conn(
|
|
378
|
+
mux: ref[MuxedConnection],
|
|
379
|
+
channel_id: ubyte,
|
|
380
|
+
type_id: ushort,
|
|
381
|
+
data: span[ubyte],
|
|
382
|
+
send_flags: ubyte
|
|
383
|
+
) -> Result[bool, net.Error]:
|
|
384
|
+
var frame = encode_frame(channel_id, type_id, send_flags, data)
|
|
385
|
+
defer frame.release()
|
|
386
|
+
if (send_flags & flag_reliable) != 0:
|
|
387
|
+
let result = await mux.conn.send_reliable(frame.as_span(), 0)
|
|
388
|
+
return result
|
|
389
|
+
let result = await mux.conn.send(frame.as_span())
|
|
390
|
+
return result
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
async function send_single_session(
|
|
394
|
+
mux: ref[MuxedSession],
|
|
395
|
+
peer_id: uint,
|
|
396
|
+
channel_id: ubyte,
|
|
397
|
+
type_id: ushort,
|
|
398
|
+
data: span[ubyte],
|
|
399
|
+
send_flags: ubyte
|
|
400
|
+
) -> Result[bool, net.Error]:
|
|
401
|
+
var frame = encode_frame(channel_id, type_id, send_flags, data)
|
|
402
|
+
defer frame.release()
|
|
403
|
+
if (send_flags & flag_reliable) != 0:
|
|
404
|
+
let result = await mux.session.send_reliable(peer_id, frame.as_span(), 0)
|
|
405
|
+
return result
|
|
406
|
+
let result = await mux.session.send(peer_id, frame.as_span())
|
|
407
|
+
return result
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
async function send_fragmented_conn(
|
|
411
|
+
mux: ref[MuxedConnection],
|
|
412
|
+
channel_id: ubyte,
|
|
413
|
+
type_id: ushort,
|
|
414
|
+
data: span[ubyte],
|
|
415
|
+
send_flags: ubyte
|
|
416
|
+
) -> Result[bool, net.Error]:
|
|
417
|
+
let group_id = mux.next_group_id
|
|
418
|
+
mux.next_group_id += 1
|
|
419
|
+
let frag_flags = send_flags | flag_fragmented
|
|
420
|
+
let chunk_size = mux.config.fragment_size
|
|
421
|
+
var total: ushort = 0
|
|
422
|
+
var remaining = data.len
|
|
423
|
+
while remaining > 0:
|
|
424
|
+
let chunk_len = if remaining < chunk_size: remaining else: chunk_size
|
|
425
|
+
if chunk_len == 0:
|
|
426
|
+
break
|
|
427
|
+
total += 1
|
|
428
|
+
remaining -= chunk_len
|
|
429
|
+
|
|
430
|
+
remaining = data.len
|
|
431
|
+
var offset: ptr_uint = 0
|
|
432
|
+
var frag_index: ushort = 0
|
|
433
|
+
while remaining > 0:
|
|
434
|
+
let chunk_len = if remaining < chunk_size: remaining else: chunk_size
|
|
435
|
+
if chunk_len == 0:
|
|
436
|
+
break
|
|
437
|
+
let chunk = unsafe: span[ubyte](data = data.data + offset, len = chunk_len)
|
|
438
|
+
var frame = encode_fragment_frame(channel_id, type_id, frag_flags, group_id, frag_index, total, chunk)
|
|
439
|
+
defer frame.release()
|
|
440
|
+
if (send_flags & flag_reliable) != 0:
|
|
441
|
+
let _ = await mux.conn.send_reliable(frame.as_span(), 0)
|
|
442
|
+
else:
|
|
443
|
+
let _ = await mux.conn.send(frame.as_span())
|
|
444
|
+
offset += chunk_len
|
|
445
|
+
remaining -= chunk_len
|
|
446
|
+
frag_index += 1
|
|
447
|
+
return Result[bool, net.Error].success(value = true)
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
async function send_fragmented_session(
|
|
451
|
+
mux: ref[MuxedSession],
|
|
452
|
+
peer_id: uint,
|
|
453
|
+
channel_id: ubyte,
|
|
454
|
+
type_id: ushort,
|
|
455
|
+
data: span[ubyte],
|
|
456
|
+
send_flags: ubyte
|
|
457
|
+
) -> Result[bool, net.Error]:
|
|
458
|
+
let group_id = mux.next_group_id
|
|
459
|
+
mux.next_group_id += 1
|
|
460
|
+
let frag_flags = send_flags | flag_fragmented
|
|
461
|
+
let chunk_size = mux.config.fragment_size
|
|
462
|
+
var total: ushort = 0
|
|
463
|
+
var remaining = data.len
|
|
464
|
+
while remaining > 0:
|
|
465
|
+
let chunk_len = if remaining < chunk_size: remaining else: chunk_size
|
|
466
|
+
if chunk_len == 0:
|
|
467
|
+
break
|
|
468
|
+
total += 1
|
|
469
|
+
remaining -= chunk_len
|
|
470
|
+
|
|
471
|
+
remaining = data.len
|
|
472
|
+
var offset: ptr_uint = 0
|
|
473
|
+
var frag_index: ushort = 0
|
|
474
|
+
while remaining > 0:
|
|
475
|
+
let chunk_len = if remaining < chunk_size: remaining else: chunk_size
|
|
476
|
+
if chunk_len == 0:
|
|
477
|
+
break
|
|
478
|
+
let chunk = unsafe: span[ubyte](data = data.data + offset, len = chunk_len)
|
|
479
|
+
var frame = encode_fragment_frame(channel_id, type_id, frag_flags, group_id, frag_index, total, chunk)
|
|
480
|
+
defer frame.release()
|
|
481
|
+
if (send_flags & flag_reliable) != 0:
|
|
482
|
+
let _ = await mux.session.send_reliable(peer_id, frame.as_span(), 0)
|
|
483
|
+
else:
|
|
484
|
+
let _ = await mux.session.send(peer_id, frame.as_span())
|
|
485
|
+
offset += chunk_len
|
|
486
|
+
remaining -= chunk_len
|
|
487
|
+
frag_index += 1
|
|
488
|
+
return Result[bool, net.Error].success(value = true)
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
function decode_wire_header(data: span[ubyte]) -> Result[WireHeader, net.Error]:
|
|
492
|
+
if data.len < wire_header_size:
|
|
493
|
+
return Result[WireHeader, net.Error].failure(error = net.net_error("mux payload too short"))
|
|
494
|
+
var r = bin.reader(data)
|
|
495
|
+
let channel_id = r.read_ubyte() else:
|
|
496
|
+
return Result[WireHeader, net.Error].failure(error = net.net_error("mux malformed header"))
|
|
497
|
+
let type_id = r.read_ushort() else:
|
|
498
|
+
return Result[WireHeader, net.Error].failure(error = net.net_error("mux malformed header"))
|
|
499
|
+
let wire_flags = r.read_ubyte() else:
|
|
500
|
+
return Result[WireHeader, net.Error].failure(error = net.net_error("mux malformed header"))
|
|
501
|
+
return Result[WireHeader, net.Error].success(value = WireHeader(
|
|
502
|
+
channel_id = channel_id,
|
|
503
|
+
type_id = type_id,
|
|
504
|
+
msg_flags = wire_flags
|
|
505
|
+
))
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
function drain_incoming_conn(mux: ref[MuxedConnection]) -> void:
|
|
509
|
+
while true:
|
|
510
|
+
let ev = mux.conn.try_recv()
|
|
511
|
+
match ev:
|
|
512
|
+
Option.none:
|
|
513
|
+
break
|
|
514
|
+
Option.some as p:
|
|
515
|
+
var e = p.value
|
|
516
|
+
demux_conn(mux, ref_of(e), mux.current_frame)
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
function drain_incoming_session(mux: ref[MuxedSession]) -> void:
|
|
520
|
+
while true:
|
|
521
|
+
let ev = mux.session.try_recv()
|
|
522
|
+
match ev:
|
|
523
|
+
Option.none:
|
|
524
|
+
break
|
|
525
|
+
Option.some as p:
|
|
526
|
+
var e = p.value
|
|
527
|
+
demux_session(mux, ref_of(e), mux.current_frame)
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
function demux_conn(mux: ref[MuxedConnection], ev: ref[sess.PeerEvent], frame: uint) -> void:
|
|
531
|
+
if ev.kind == sess.PeerEventKind.peer_joined:
|
|
532
|
+
mux.event_queue.push_back(MuxedMessage(
|
|
533
|
+
peer_id = ev.peer_id,
|
|
534
|
+
channel_id = meta_channel,
|
|
535
|
+
type_id = type_peer_joined,
|
|
536
|
+
msg_flags = 0,
|
|
537
|
+
payload = bytes.Bytes.empty()
|
|
538
|
+
))
|
|
539
|
+
ev.release()
|
|
540
|
+
return
|
|
541
|
+
|
|
542
|
+
if ev.kind == sess.PeerEventKind.peer_left:
|
|
543
|
+
mux.event_queue.push_back(MuxedMessage(
|
|
544
|
+
peer_id = ev.peer_id,
|
|
545
|
+
channel_id = meta_channel,
|
|
546
|
+
type_id = type_peer_left,
|
|
547
|
+
msg_flags = 0,
|
|
548
|
+
payload = bytes.Bytes.empty()
|
|
549
|
+
))
|
|
550
|
+
ev.release()
|
|
551
|
+
return
|
|
552
|
+
|
|
553
|
+
if ev.kind != sess.PeerEventKind.user_data:
|
|
554
|
+
ev.release()
|
|
555
|
+
return
|
|
556
|
+
|
|
557
|
+
let data = ev.payload.as_span()
|
|
558
|
+
if data.len < wire_header_size:
|
|
559
|
+
ev.release()
|
|
560
|
+
return
|
|
561
|
+
|
|
562
|
+
let header_result = decode_wire_header(data)
|
|
563
|
+
match header_result:
|
|
564
|
+
Result.failure:
|
|
565
|
+
ev.release()
|
|
566
|
+
return
|
|
567
|
+
Result.success as hp:
|
|
568
|
+
let h = hp.value
|
|
569
|
+
if (h.msg_flags & flag_fragmented) != 0:
|
|
570
|
+
handle_fragment_conn(mux, h, data, frame)
|
|
571
|
+
else:
|
|
572
|
+
let payload_len = data.len - wire_header_size
|
|
573
|
+
var payload = bytes.Bytes.empty()
|
|
574
|
+
if payload_len > 0:
|
|
575
|
+
unsafe:
|
|
576
|
+
payload = bytes.Bytes.copy(span[ubyte](data = data.data + wire_header_size, len = payload_len))
|
|
577
|
+
mux.event_queue.push_back(MuxedMessage(
|
|
578
|
+
peer_id = ev.peer_id,
|
|
579
|
+
channel_id = h.channel_id,
|
|
580
|
+
type_id = h.type_id,
|
|
581
|
+
msg_flags = h.msg_flags,
|
|
582
|
+
payload = payload
|
|
583
|
+
))
|
|
584
|
+
ev.release()
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
function demux_session(mux: ref[MuxedSession], ev: ref[sess.PeerEvent], frame: uint) -> void:
|
|
588
|
+
if ev.kind == sess.PeerEventKind.peer_joined:
|
|
589
|
+
mux.event_queue.push_back(MuxedMessage(
|
|
590
|
+
peer_id = ev.peer_id,
|
|
591
|
+
channel_id = meta_channel,
|
|
592
|
+
type_id = type_peer_joined,
|
|
593
|
+
msg_flags = 0,
|
|
594
|
+
payload = bytes.Bytes.empty()
|
|
595
|
+
))
|
|
596
|
+
ev.release()
|
|
597
|
+
return
|
|
598
|
+
|
|
599
|
+
if ev.kind == sess.PeerEventKind.peer_left:
|
|
600
|
+
mux.event_queue.push_back(MuxedMessage(
|
|
601
|
+
peer_id = ev.peer_id,
|
|
602
|
+
channel_id = meta_channel,
|
|
603
|
+
type_id = type_peer_left,
|
|
604
|
+
msg_flags = 0,
|
|
605
|
+
payload = bytes.Bytes.empty()
|
|
606
|
+
))
|
|
607
|
+
ev.release()
|
|
608
|
+
return
|
|
609
|
+
|
|
610
|
+
if ev.kind != sess.PeerEventKind.user_data:
|
|
611
|
+
ev.release()
|
|
612
|
+
return
|
|
613
|
+
|
|
614
|
+
let data = ev.payload.as_span()
|
|
615
|
+
if data.len < wire_header_size:
|
|
616
|
+
ev.release()
|
|
617
|
+
return
|
|
618
|
+
|
|
619
|
+
let header_result = decode_wire_header(data)
|
|
620
|
+
match header_result:
|
|
621
|
+
Result.failure:
|
|
622
|
+
ev.release()
|
|
623
|
+
return
|
|
624
|
+
Result.success as hp:
|
|
625
|
+
let h = hp.value
|
|
626
|
+
if (h.msg_flags & flag_fragmented) != 0:
|
|
627
|
+
handle_fragment_session(mux, h, data, frame, ev.peer_id)
|
|
628
|
+
else:
|
|
629
|
+
let payload_len = data.len - wire_header_size
|
|
630
|
+
var payload = bytes.Bytes.empty()
|
|
631
|
+
if payload_len > 0:
|
|
632
|
+
unsafe:
|
|
633
|
+
payload = bytes.Bytes.copy(span[ubyte](data = data.data + wire_header_size, len = payload_len))
|
|
634
|
+
mux.event_queue.push_back(MuxedMessage(
|
|
635
|
+
peer_id = ev.peer_id,
|
|
636
|
+
channel_id = h.channel_id,
|
|
637
|
+
type_id = h.type_id,
|
|
638
|
+
msg_flags = h.msg_flags,
|
|
639
|
+
payload = payload
|
|
640
|
+
))
|
|
641
|
+
ev.release()
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
function handle_fragment_conn(mux: ref[MuxedConnection], h: WireHeader, data: span[ubyte], frame: uint) -> void:
|
|
645
|
+
if data.len < wire_header_size + fragment_header_size:
|
|
646
|
+
return
|
|
647
|
+
unsafe:
|
|
648
|
+
let group_lo = ushort<-read(data.data + wire_header_size)
|
|
649
|
+
let group_hi = ushort<-read(data.data + wire_header_size + 1)
|
|
650
|
+
let group_id = group_lo | (group_hi << 8)
|
|
651
|
+
let index_lo = ushort<-read(data.data + wire_header_size + 2)
|
|
652
|
+
let index_hi = ushort<-read(data.data + wire_header_size + 3)
|
|
653
|
+
let frag_index = index_lo | (index_hi << 8)
|
|
654
|
+
let total_lo = ushort<-read(data.data + wire_header_size + 4)
|
|
655
|
+
let total_hi = ushort<-read(data.data + wire_header_size + 5)
|
|
656
|
+
let total = total_lo | (total_hi << 8)
|
|
657
|
+
assemble_fragment(
|
|
658
|
+
ref_of(mux.frag_buffers),
|
|
659
|
+
ref_of(mux.event_queue),
|
|
660
|
+
mux.config,
|
|
661
|
+
h,
|
|
662
|
+
group_id,
|
|
663
|
+
frag_index,
|
|
664
|
+
total,
|
|
665
|
+
data,
|
|
666
|
+
frame,
|
|
667
|
+
0
|
|
668
|
+
)
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
function handle_fragment_session(
|
|
672
|
+
mux: ref[MuxedSession],
|
|
673
|
+
h: WireHeader,
|
|
674
|
+
data: span[ubyte],
|
|
675
|
+
frame: uint,
|
|
676
|
+
peer_id: uint
|
|
677
|
+
) -> void:
|
|
678
|
+
if data.len < wire_header_size + fragment_header_size:
|
|
679
|
+
return
|
|
680
|
+
unsafe:
|
|
681
|
+
let group_lo = ushort<-read(data.data + wire_header_size)
|
|
682
|
+
let group_hi = ushort<-read(data.data + wire_header_size + 1)
|
|
683
|
+
let group_id = group_lo | (group_hi << 8)
|
|
684
|
+
let index_lo = ushort<-read(data.data + wire_header_size + 2)
|
|
685
|
+
let index_hi = ushort<-read(data.data + wire_header_size + 3)
|
|
686
|
+
let frag_index = index_lo | (index_hi << 8)
|
|
687
|
+
let total_lo = ushort<-read(data.data + wire_header_size + 4)
|
|
688
|
+
let total_hi = ushort<-read(data.data + wire_header_size + 5)
|
|
689
|
+
let total = total_lo | (total_hi << 8)
|
|
690
|
+
assemble_fragment(
|
|
691
|
+
ref_of(mux.frag_buffers),
|
|
692
|
+
ref_of(mux.event_queue),
|
|
693
|
+
mux.config,
|
|
694
|
+
h,
|
|
695
|
+
group_id,
|
|
696
|
+
frag_index,
|
|
697
|
+
total,
|
|
698
|
+
data,
|
|
699
|
+
frame,
|
|
700
|
+
peer_id
|
|
701
|
+
)
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
function assemble_fragment(
|
|
705
|
+
buffers: ref[vec.Vec[FragBuffer]],
|
|
706
|
+
queue: ref[deque.Deque[MuxedMessage]],
|
|
707
|
+
config: MuxedConfig,
|
|
708
|
+
h: WireHeader,
|
|
709
|
+
group_id: ushort,
|
|
710
|
+
frag_index: ushort,
|
|
711
|
+
total: ushort,
|
|
712
|
+
data: span[ubyte],
|
|
713
|
+
frame: uint,
|
|
714
|
+
peer_id: uint
|
|
715
|
+
) -> void:
|
|
716
|
+
let payload_start = wire_header_size + fragment_header_size
|
|
717
|
+
if data.len <= payload_start:
|
|
718
|
+
return
|
|
719
|
+
let payload_len = data.len - payload_start
|
|
720
|
+
if frag_index >= total:
|
|
721
|
+
return
|
|
722
|
+
|
|
723
|
+
let buf_index = find_frag_buffer(buffers, peer_id, group_id)
|
|
724
|
+
if buf_index < 0:
|
|
725
|
+
let full_size = ptr_uint<-total * config.fragment_size
|
|
726
|
+
var buf = bytes.Bytes.empty()
|
|
727
|
+
if full_size > 0:
|
|
728
|
+
let buf_data = heap.must_alloc[ubyte](full_size)
|
|
729
|
+
var fill: ptr_uint = 0
|
|
730
|
+
while fill < full_size:
|
|
731
|
+
unsafe: read(buf_data + fill) = 0
|
|
732
|
+
fill += 1
|
|
733
|
+
buf = bytes.Bytes(data = buf_data, len = full_size)
|
|
734
|
+
buffers.push(FragBuffer(
|
|
735
|
+
group_id = group_id,
|
|
736
|
+
peer_id = peer_id,
|
|
737
|
+
channel_id = h.channel_id,
|
|
738
|
+
type_id = h.type_id,
|
|
739
|
+
msg_flags = h.msg_flags,
|
|
740
|
+
total = total,
|
|
741
|
+
received_count = 1,
|
|
742
|
+
received_bits = (1 << (uint<-frag_index)),
|
|
743
|
+
data = buf,
|
|
744
|
+
last_frame = frame
|
|
745
|
+
))
|
|
746
|
+
let dest_start = ptr_uint<-frag_index * config.fragment_size
|
|
747
|
+
if dest_start + payload_len <= full_size:
|
|
748
|
+
unsafe:
|
|
749
|
+
copy_bytes(ptr[ubyte]<-buf.data, dest_start, data, payload_start, payload_len)
|
|
750
|
+
return
|
|
751
|
+
|
|
752
|
+
let buf_ptr = buffers.get(ptr_uint<-buf_index) else:
|
|
753
|
+
return
|
|
754
|
+
let bit_flag: uint = 1 << uint<-frag_index
|
|
755
|
+
if (unsafe: read(buf_ptr).received_bits & bit_flag) != 0:
|
|
756
|
+
return
|
|
757
|
+
|
|
758
|
+
unsafe: read(buf_ptr).received_count += 1
|
|
759
|
+
unsafe: read(buf_ptr).received_bits |= bit_flag
|
|
760
|
+
unsafe: read(buf_ptr).last_frame = frame
|
|
761
|
+
let dest_start = ptr_uint<-frag_index * config.fragment_size
|
|
762
|
+
let full_size = ptr_uint<-total * config.fragment_size
|
|
763
|
+
if dest_start + payload_len <= full_size:
|
|
764
|
+
unsafe:
|
|
765
|
+
copy_bytes(ptr[ubyte]<-read(buf_ptr).data.data, dest_start, data, payload_start, payload_len)
|
|
766
|
+
|
|
767
|
+
if unsafe: read(buf_ptr).received_count == unsafe: read(buf_ptr).total:
|
|
768
|
+
var final_data = bytes.Bytes.empty()
|
|
769
|
+
if full_size > 0:
|
|
770
|
+
let copy_src = unsafe: read(buf_ptr).data.data
|
|
771
|
+
unsafe:
|
|
772
|
+
final_data = bytes.Bytes.copy(span[ubyte](data = ptr[ubyte]<-copy_src, len = full_size))
|
|
773
|
+
queue.push_back(MuxedMessage(
|
|
774
|
+
peer_id = peer_id,
|
|
775
|
+
channel_id = h.channel_id,
|
|
776
|
+
type_id = h.type_id,
|
|
777
|
+
msg_flags = h.msg_flags,
|
|
778
|
+
payload = final_data
|
|
779
|
+
))
|
|
780
|
+
unsafe: read(buf_ptr).data.release()
|
|
781
|
+
buffers.remove(ptr_uint<-buf_index)
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
function copy_bytes(
|
|
785
|
+
dest: ptr[ubyte],
|
|
786
|
+
dest_offset: ptr_uint,
|
|
787
|
+
src_data: span[ubyte],
|
|
788
|
+
src_offset: ptr_uint,
|
|
789
|
+
count: ptr_uint
|
|
790
|
+
) -> void:
|
|
791
|
+
unsafe:
|
|
792
|
+
var i: ptr_uint = 0
|
|
793
|
+
while i < count:
|
|
794
|
+
read(dest + dest_offset + i) = read(src_data.data + src_offset + i)
|
|
795
|
+
i += 1
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
function find_frag_buffer(buffers: ref[vec.Vec[FragBuffer]], peer_id: uint, group_id: ushort) -> int:
|
|
799
|
+
var index: ptr_uint = 0
|
|
800
|
+
while index < buffers.len():
|
|
801
|
+
let buf_ptr = buffers.get(index) else:
|
|
802
|
+
return -1
|
|
803
|
+
if unsafe: read(buf_ptr).group_id == group_id and unsafe: read(buf_ptr).peer_id == peer_id:
|
|
804
|
+
return int<-index
|
|
805
|
+
index += 1
|
|
806
|
+
return -1
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
function prune_frag_buffers(buffers: ref[vec.Vec[FragBuffer]], frame: uint, timeout_frames: uint) -> void:
|
|
810
|
+
var index: int = int<-(buffers.len())
|
|
811
|
+
index -= 1
|
|
812
|
+
while index >= 0:
|
|
813
|
+
let buf_ptr = buffers.get(ptr_uint<-index) else:
|
|
814
|
+
return
|
|
815
|
+
if frame > unsafe: read(buf_ptr).last_frame + timeout_frames:
|
|
816
|
+
unsafe: read(buf_ptr).data.release()
|
|
817
|
+
buffers.remove(ptr_uint<-index)
|
|
818
|
+
index -= 1
|
|
819
|
+
|
|
820
|
+
|
|
821
|
+
function release_frag_buffers(buffers: ref[vec.Vec[FragBuffer]]) -> void:
|
|
822
|
+
var index: ptr_uint = 0
|
|
823
|
+
while index < buffers.len():
|
|
824
|
+
let buf_ptr = buffers.get(index) else:
|
|
825
|
+
return
|
|
826
|
+
unsafe: read(buf_ptr).data.release()
|
|
827
|
+
index += 1
|
|
828
|
+
buffers.clear()
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
function release_event_queue(queue: ref[deque.Deque[MuxedMessage]]) -> void:
|
|
832
|
+
while true:
|
|
833
|
+
let msg = queue.pop_front()
|
|
834
|
+
match msg:
|
|
835
|
+
Option.none:
|
|
836
|
+
break
|
|
837
|
+
Option.some as p:
|
|
838
|
+
var m = p.value
|
|
839
|
+
m.release()
|