diff options
-rw-r--r-- | client/main.ha | 14 | ||||
-rw-r--r-- | packet_reader/packet_reader.ha | 41 | ||||
-rw-r--r-- | server/main.ha | 18 |
3 files changed, 61 insertions, 12 deletions
diff --git a/client/main.ha b/client/main.ha index 242a101..4e6fb9f 100644 --- a/client/main.ha +++ b/client/main.ha @@ -99,8 +99,18 @@ export fn main() void = { case let op: packet_reader::packet_drawop => const opc = op as drawing::op_circle; drawing::perform(pictures, opc); - case => - abort("other packet not supported yet"); + case let packet: packet_reader::packet_sendchunk => + fmt::println(packet.world_pos.0, packet.world_pos.1, len(packet.chunk_data))!; + let did_set = false; + for (let pic &.. pictures) { + if (pic.world_pos.0 == packet.world_pos.0 && pic.world_pos.1 == packet.world_pos.1) { + pic.d[..len(packet.chunk_data)] = packet.chunk_data[..]; + fmt::printfln("setting {},{}",pic.world_pos.0,pic.world_pos.1)!; + did_set = true; + break; + }; + }; + if (!did_set) fmt::println("did not set anything {},{} ....",packet.world_pos.0,packet.world_pos.1)!; }; }; }; 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)?; }; }; diff --git a/server/main.ha b/server/main.ha index 9f21932..ae7d9eb 100644 --- a/server/main.ha +++ b/server/main.ha @@ -41,7 +41,13 @@ export fn main() void = { for (const p &.. pictures) drawing::clear_picture(p, 0xffffff); - const listener = tcp::listen(ip::ANY_V4, PORT)!; + const listener = match(tcp::listen(ip::ANY_V4, PORT)) { + case let err: net::error => + fmt::fatalf(net::strerror(err)); + case let sock: net::socket => + yield sock; + }; + loop(listener, pictures); }; @@ -111,6 +117,7 @@ fn loop(listener: net::socket, pictures: []drawing::picture) void = { }); append(packet_readers, packet_reader::new()); fmt::printfln("there are now {},{} conns.",len(pollfds),len(packet_readers))!; + send_world(new_conn, pictures)!; }; for (let connidx = 1z; connidx < len(pollfds); connidx += 1) { if (0 != pollfds[connidx].revents & poll::event::POLLIN) { @@ -153,3 +160,12 @@ fn handle_packet(pictures: []drawing::picture, pollfds: []poll::pollfd, packet: }; }; +fn send_world(conn: io::file, pictures: []drawing::picture) (void | io::error) = { + for (const pic &.. pictures) { + packet_reader::send(conn, packet_reader::packet_sendchunk { + world_pos = pic.world_pos, + chunk_data = pic.d[..pic.w*pic.h], + })?; + }; + +}; |