diff options
Diffstat (limited to 'packet_reader')
-rw-r--r-- | packet_reader/packet_reader.ha | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/packet_reader/packet_reader.ha b/packet_reader/packet_reader.ha index 9cae444..02ecdba 100644 --- a/packet_reader/packet_reader.ha +++ b/packet_reader/packet_reader.ha @@ -19,13 +19,22 @@ export fn new() packet_reader = { return pr; }; +fn cast_u32s_to_u8s(in: []u32) []u8 = + (in: *[*]u32: *[*]u8)[..len(in)*4]; +fn cast_u8s_to_u32s(in: []u8) []u32 = + (in: *[*]u8: *[*]u32)[..len(in)/4]; + export type packet_type = enum u8 { DRAW_OP, SEND_CHUNK, }; export type packet_drawop = drawing::op; -export type packet_sendchunk = []u32; +export type packet_sendchunk = struct { + world_pos: drawing::pos, + chunk_data: []u32, +}; + export type packet = (packet_drawop | packet_sendchunk); // call when input is ready. could block otherwise @@ -73,19 +82,29 @@ export fn next(pr: *packet_reader) (packet | done | error) = { const op = drawing::deser_op(packet_bytes[8..]); return op: packet_drawop; case packet_type::SEND_CHUNK => - // in an ideal world we would need no copies - const totally_necessary_copy = alloc(packet_bytes[8..]...); - return totally_necessary_copy: packet_sendchunk; + // return value is BORROWED from the BUFFER + const pos_bytes = packet_bytes[8..16]; + const chunk_data_bytes = packet_bytes[16..]; + const pos = ( + endian::legetu32(pos_bytes[0..4]): i32, + endian::legetu32(pos_bytes[4..8]): i32 + ): drawing::pos; + const d = cast_u8s_to_u32s(chunk_data_bytes); + assert(len(d) == 512*512,"wrong chunk size??"); + return packet_sendchunk { world_pos = pos, chunk_data = d }; }; }; -export fn send_raw(sock: io::file, ty: packet_type, data: []u8) (void | io::error) = { +export fn send_raw(sock: io::file, ty: packet_type, datas: []u8...) (void | io::error) = { // ehh const header: [8]u8 = [0...]; - endian::leputu32(header[0..4], 8u32 + len(data):u32); + let total_len = 8u32; + for (const data .. datas) total_len += len(data): u32; + endian::leputu32(header[0..4], total_len); endian::leputu32(header[4..8], ty); io::writeall(sock, header)?; - io::writeall(sock, data)?; + for (const data .. datas) + io::writeall(sock, data)?; }; export fn send(sock: io::file, packet: packet) (void | io::error) = { @@ -94,7 +113,11 @@ export fn send(sock: io::file, packet: packet) (void | io::error) = { const ser_op = drawing::ser_op(op); defer free(ser_op); send_raw(sock, packet_type::DRAW_OP, ser_op)?; - case let chunkdata: packet_sendchunk => - abort("not implemented sendchunk yet"); + case let packet: packet_sendchunk => + const pos_buf: [8]u8 = [0...]; + endian::leputu32(pos_buf[0..4],packet.world_pos.0: u32); + endian::leputu32(pos_buf[4..8],packet.world_pos.1: u32); + const chunk_data_bytes = cast_u32s_to_u8s(packet.chunk_data); + send_raw(sock, packet_type::SEND_CHUNK, pos_buf, chunk_data_bytes)?; }; }; |