From b6261d014d64642c5c5cac2cb7436da0670c0acf Mon Sep 17 00:00:00 2001 From: koniifer Date: Wed, 13 Nov 2024 23:08:20 +0000 Subject: [PATCH] bad frame synchronisation implementation --- Cargo.lock | 6 +- sysdata/libraries/sunset_proto/src/client.hb | 12 ++-- sysdata/libraries/sunset_proto/src/lib.hb | 14 ++--- sysdata/libraries/sunset_proto/src/server.hb | 59 ++++++++++++-------- sysdata/programs/sunset_client/src/main.hb | 16 ++++-- 5 files changed, 62 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a1a426..bc4f684 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -228,12 +228,12 @@ dependencies = [ [[package]] name = "hbbytecode" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#f524013c34ff5868eadc0afdf1168239f31c7ee0" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d01e31b2034e53098f92dfb07b183a21857ded1e" [[package]] name = "hblang" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#f524013c34ff5868eadc0afdf1168239f31c7ee0" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d01e31b2034e53098f92dfb07b183a21857ded1e" dependencies = [ "hashbrown 0.15.1", "hbbytecode", @@ -245,7 +245,7 @@ dependencies = [ [[package]] name = "hbvm" version = "0.1.0" -source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#f524013c34ff5868eadc0afdf1168239f31c7ee0" +source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d01e31b2034e53098f92dfb07b183a21857ded1e" dependencies = [ "hbbytecode", ] diff --git a/sysdata/libraries/sunset_proto/src/client.hb b/sysdata/libraries/sunset_proto/src/client.hb index 9346e6c..d47f5a8 100644 --- a/sysdata/libraries/sunset_proto/src/client.hb +++ b/sysdata/libraries/sunset_proto/src/client.hb @@ -1,13 +1,15 @@ .{math: .{Vec2}, buffer, log, memory, string} := @use("../../stn/src/lib.hb"); -.{Channel, Window, send_header, send_message, await_channel, await_message, message, BUFFER_SERVER, BUFFER_CLIENT, WindowProps, WindowData} := @use("./lib.hb"); +.{Channel, Window, send_header, send_message, await_channel, await_header, await_message, message, BUFFER_SERVER, BUFFER_CLIENT, WindowProps, WindowData} := @use("./lib.hb"); .{new_surface, Color} := @use("../../render/src/lib.hb") // ! in the future this should be safely handled -channel := @as(Channel, idk) +channel := Channel.(0, 0) find_server := fn(): void { log.info("client: locating server\0") - channel = await_channel() + channel2 := await_channel(channel) + channel.server = channel2.server + channel.client = channel2.client log.info("client: server located\0") } @@ -15,7 +17,6 @@ new := fn(props: WindowProps): ?Window { send_header(message.syn, channel.server) response := await_message(Channel, channel.client) if response.header.kind != message.ack { - log.info(string.display_int(@bitcast(response.header.kind), "\0\0\0\0\0\0\0\0\0\0\0\0\0", 10)) return null } log.info("client: recv ack\0") @@ -57,9 +58,8 @@ send_frame := fn(client: Window): bool { if response.header.kind != message.ack { return false } - log.info("client: recv ack\0") // ! FOR NOW, server will ALWAYS be local, // ! so we can send pointer to surface. send_message(^Color, message.ack, client.surface.buf, server_id) - return true + return await_header(client_id).kind == message.ack } \ No newline at end of file diff --git a/sysdata/libraries/sunset_proto/src/lib.hb b/sysdata/libraries/sunset_proto/src/lib.hb index 498447f..630d960 100644 --- a/sysdata/libraries/sunset_proto/src/lib.hb +++ b/sysdata/libraries/sunset_proto/src/lib.hb @@ -46,16 +46,14 @@ $recv_header := fn(buffer_id: uint): ?MessageHeader { return response } -await_channel := fn(): Channel { - server_id := 0 - loop if server_id == 0 { - server_id = buffer.search(BUFFER_SERVER) +await_channel := fn(channel: Channel): Channel { + loop if channel.server != 0 break else { + channel.server = buffer.search(BUFFER_SERVER) } - client_id := 0 - loop if client_id == 0 { - client_id = buffer.search(BUFFER_CLIENT) + loop if channel.client != 0 break else { + channel.client = buffer.search(BUFFER_CLIENT) } - return .{client: client_id, server: server_id} + return channel } await_message := fn($Expr: type, buffer_id: uint): Message(Expr) { diff --git a/sysdata/libraries/sunset_proto/src/server.hb b/sysdata/libraries/sunset_proto/src/server.hb index f44bb44..23e250b 100644 --- a/sysdata/libraries/sunset_proto/src/server.hb +++ b/sysdata/libraries/sunset_proto/src/server.hb @@ -1,19 +1,27 @@ .{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb"); -.{Color, Surface, new_surface, put_surface, sync} := @use("../../render/src/lib.hb"); +.{Color, Surface, new_surface, put_surface, sync, put_rect, put_filled_rect, text, put_text} := @use("../../render/src/lib.hb"); .{Channel, Window, WindowProps, WindowData, MessageHeader, BUFFER_SERVER, BUFFER_CLIENT, message, permissions, recv_header, recv_message, send_message, send_header, await_message} := @use("./lib.hb") WindowServer := struct { window_count: uint, channel: Channel, - // ! replace this with an actual collection when we get an allocator + // ! replace this with a collection when we get an allocator windows: [?WindowData; 10], + font: text.Font, } // ! in the future this should be safely handled server := @as(WindowServer, idk) +psf := @embed("../../../assets/consolefonts/tamsyn/10x20r.psf") + start := fn(): void { - server = .(0, .{client: buffer.create(BUFFER_CLIENT), server: buffer.create(BUFFER_SERVER)}, .(null, null, null, null, null, null, null, null, null, null)) + font := text.font_from_psf2(@bitcast(&psf), false) + if font == null { + log.error("server: failed to load asset\0") + return + } + server = .(0, .{client: buffer.create(BUFFER_CLIENT), server: buffer.create(BUFFER_SERVER)}, .(null, null, null, null, null, null, null, null, null, null), @as(text.Font, font)) log.info("server: started server\0") } @@ -25,36 +33,43 @@ incoming := fn(): bool { if msg.kind == message.syn { log.info("server: recv syn\0") channel := Channel.(buffer.create_nameless(), buffer.create_nameless()) - send_message(Channel, message.ack, channel, channel.client) + send_message(Channel, message.ack, channel, server.channel.client) props := await_message(WindowProps, channel.server) if props.header.kind != message.props { return true } log.info("server: recv props\0") // ! do inspection of requested props here - send_message(WindowData, message.ack, .(props.body, channel, permissions.default), channel.client) + data := WindowData.(props.body, channel, permissions.default) + send_message(WindowData, message.ack, data, channel.client) + server.windows[server.window_count] = data + server.window_count += 1 } return true } render_clients := fn(screen: Surface): void { - i := 0 - loop if i == 10 break else { - window := server.windows[i] - if window == null { - continue - } - header := recv_header(window.channel.server) - if header == null | @unwrap(header).kind != message.frame_ready { - continue - } - send_header(message.ack, window.channel.client) - ptr := await_message(^Color, window.channel.server) - if ptr.header.kind != message.ack { - continue - } - put_surface(screen, .(ptr.body, window.props.dimensions.x, window.props.dimensions.y, window.props.dimensions.x * window.props.dimensions.y), window.props.position, false) - i += 1 + // support one window for test case + window := server.windows[0] + if window == null { + return } + header := recv_header(window.channel.server) + if header == null { + return + } + if header.kind != message.frame_ready { + return + } + send_header(message.ack, window.channel.client) + ptr := await_message(^Color, window.channel.server) + if ptr.header.kind != message.ack { + return + } + put_surface(screen, .(ptr.body, window.props.dimensions.x, window.props.dimensions.y, window.props.dimensions.x * window.props.dimensions.y), window.props.position, false) + put_rect(screen, window.props.position - .(1, 1), window.props.dimensions + .(1, 1), .(255, 255, 255, 255)) + put_filled_rect(screen, window.props.position - .(1, 21), .(window.props.dimensions.x + 2, 20), .(255, 255, 255, 255)) + put_text(screen, server.font, window.props.position - .(-2, 20), .(0, 0, 0, 255), window.props.title) sync(screen) + send_header(message.ack, window.channel.client) } \ No newline at end of file diff --git a/sysdata/programs/sunset_client/src/main.hb b/sysdata/programs/sunset_client/src/main.hb index eec5c12..8b46a12 100644 --- a/sysdata/programs/sunset_client/src/main.hb +++ b/sysdata/programs/sunset_client/src/main.hb @@ -1,17 +1,21 @@ -.{log, string} := @use("../../../libraries/stn/src/lib.hb") +.{log} := @use("../../../libraries/stn/src/lib.hb") sunset := @use("../../../libraries/sunset_proto/src/lib.hb") render := @use("../../../libraries/render/src/lib.hb") main := fn(): void { sunset.client.find_server() - - window := sunset.client.new(.(.(100, 100), .(100, 100), "Hello, World!\0")) + window := sunset.client.new(.(.(100, 100), .(700, 100), "Hello, World!\0")) if window == null { log.error("got no window\0") return } - render.put_filled_circle(window.surface, .(50, 50), 25, render.white) - if sunset.client.send_frame(window) == false { - log.error("did not send frame\0") + x := 0 + loop { + render.clear(window.surface, render.cyan) + render.put_filled_circle(window.surface, .(50 + x % window.data.props.dimensions.x, 50), 25, render.magenta) + if sunset.client.send_frame(window) == false { + log.error("did not send frame\0") + } + x += 1 } } \ No newline at end of file