From 95b4a921dc4e5890bf18cbf7a24c2ac7b5905ee8 Mon Sep 17 00:00:00 2001 From: koniifer Date: Thu, 14 Nov 2024 16:43:23 +0000 Subject: [PATCH] improve & optimise window decoration code --- Cargo.lock | 4 +- sysdata/libraries/sunset_proto/src/lib.hb | 12 ----- sysdata/libraries/sunset_proto/src/server.hb | 51 +++++++++++++------- sysdata/programs/sunset_client/src/main.hb | 13 ++++- sysdata/programs/sunset_server/src/main.hb | 1 + 5 files changed, 48 insertions(+), 33 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc4f6848a..5dc6c1348 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,9 +82,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "shlex", ] diff --git a/sysdata/libraries/sunset_proto/src/lib.hb b/sysdata/libraries/sunset_proto/src/lib.hb index 630d960b7..f5df7b628 100644 --- a/sysdata/libraries/sunset_proto/src/lib.hb +++ b/sysdata/libraries/sunset_proto/src/lib.hb @@ -14,18 +14,6 @@ server := @use("./server.hb") message := @use("./message.hb") permissions := @use("./permissions.hb") -opaque := fn(i: uint): bool { - if i == 0 { - return true - } - return false -} - -sleep := fn(): void { - i := 10000000 - loop if opaque(i) break else i -= 1 -} - $send_message := fn($Expr: type, kind: uint, msg: Expr, buffer_id: uint): void { buffer.write(?Message(Expr), buffer_id, &@as(?Message(Expr), .(.(kind), msg))) } diff --git a/sysdata/libraries/sunset_proto/src/server.hb b/sysdata/libraries/sunset_proto/src/server.hb index 23e250b3b..6737a4061 100644 --- a/sysdata/libraries/sunset_proto/src/server.hb +++ b/sysdata/libraries/sunset_proto/src/server.hb @@ -6,7 +6,7 @@ WindowServer := struct { window_count: uint, channel: Channel, // ! replace this with a collection when we get an allocator - windows: [?WindowData; 10], + windows: [?Window; 10], font: text.Font, } @@ -42,34 +42,51 @@ incoming := fn(): bool { // ! do inspection of requested props here data := WindowData.(props.body, channel, permissions.default) send_message(WindowData, message.ack, data, channel.client) - server.windows[server.window_count] = data + surface := new_window_decorations(data.props.dimensions) + put_filled_rect(surface, .(0, 0), data.props.dimensions + .(DECO_WIDTH, DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM), DECO_COLOUR) + put_filled_rect(surface, .(0, 0), .(data.props.dimensions.x + DECO_WIDTH, DECO_HEIGHT_TOP), DECO_COLOUR) + put_text(surface, server.font, .(2, 1), .(0, 0, 0, 255), data.props.title) + server.windows[server.window_count] = .(data, surface) server.window_count += 1 } return true } -render_clients := fn(screen: Surface): void { - // support one window for test case +$DECO_WIDTH := 2 +$DECO_HEIGHT_TOP := 20 +$DECO_HEIGHT_BOTTOM := 1 +$DECO_COLOUR := Color.(100, 200, 255, 255) + +new_window_decorations := fn(dimensions: math.Vec2(uint)): Surface { + return new_surface(dimensions.x + DECO_WIDTH, dimensions.y + DECO_HEIGHT_TOP + DECO_HEIGHT_BOTTOM) +} + +// ! compositor code. this currently disallows tearing. + +collect_frames := fn(): void { window := server.windows[0] if window == null { return } - header := recv_header(window.channel.server) - if header == null { + header := recv_header(window.data.channel.server) + if header == null | @unwrap(header).kind != message.frame_ready { return } - if header.kind != message.frame_ready { + send_header(message.ack, window.data.channel.client) + ptr := await_message(^Color, window.data.channel.server) + // ! weird compiler error + // if ptr.header.kind != message.ack { + // return + // } + put_surface(window.surface, Surface.(ptr.body, window.data.props.dimensions.x, window.data.props.dimensions.y, window.data.props.dimensions.x * window.data.props.dimensions.y), .(DECO_WIDTH / 2, DECO_HEIGHT_TOP), false) + send_header(message.ack, window.data.channel.client) +} + +render_clients := fn(screen: Surface): void { + window := server.windows[0] + if window == null { 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) + put_surface(screen, window.surface, window.data.props.position, false) 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 8b46a1246..a4cb5f625 100644 --- a/sysdata/programs/sunset_client/src/main.hb +++ b/sysdata/programs/sunset_client/src/main.hb @@ -2,9 +2,18 @@ sunset := @use("../../../libraries/sunset_proto/src/lib.hb") render := @use("../../../libraries/render/src/lib.hb") +bmp := @embed("../../../assets/mini.bmp") + main := fn(): void { sunset.client.find_server() - window := sunset.client.new(.(.(100, 100), .(700, 100), "Hello, World!\0")) + + image := render.image.from(@bitcast(&bmp)) + if image == null { + log.error("got no image\0") + return + } + + window := sunset.client.new(.(.(100, 100), .(480, 200), "sunset windowing demo paddingpaddingpadding\0")) if window == null { log.error("got no window\0") return @@ -12,7 +21,7 @@ main := fn(): void { 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) + render.put_surface(window.surface, image, .(image.width + x % window.data.props.dimensions.x, 20), false) if sunset.client.send_frame(window) == false { log.error("did not send frame\0") } diff --git a/sysdata/programs/sunset_server/src/main.hb b/sysdata/programs/sunset_server/src/main.hb index f11694ec9..96f749e0b 100644 --- a/sysdata/programs/sunset_server/src/main.hb +++ b/sysdata/programs/sunset_server/src/main.hb @@ -5,6 +5,7 @@ main := fn(): void { screen := render.init(true) sunset.server.start() loop if sunset.server.incoming() { + sunset.server.collect_frames() sunset.server.render_clients(screen) } } \ No newline at end of file