ableos/sysdata/libraries/sunset_proto/src/server.hb

92 lines
3.4 KiB
Plaintext
Raw Normal View History

2024-11-10 12:57:48 -06:00
.{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb");
.{Color, Surface, new_surface, put_surface, sync, put_rect, put_filled_rect, text, put_text} := @use("../../render/src/lib.hb");
2024-11-13 11:03:31 -06:00
.{Channel, Window, WindowProps, WindowData, MessageHeader, BUFFER_SERVER, BUFFER_CLIENT, message, permissions, recv_header, recv_message, send_message, send_header, await_message} := @use("./lib.hb")
2024-11-10 12:57:48 -06:00
2024-11-10 19:03:01 -06:00
WindowServer := struct {
window_count: uint,
2024-11-13 11:03:31 -06:00
channel: Channel,
// ! replace this with a collection when we get an allocator
windows: [?Window; 10],
font: text.Font,
2024-11-10 19:03:01 -06:00
}
2024-11-10 12:57:48 -06:00
// ! in the future this should be safely handled
server := @as(WindowServer, idk)
2024-11-10 12:57:48 -06:00
psf := @embed("../../../assets/consolefonts/tamsyn/10x20r.psf")
start := fn(): void {
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))
2024-11-13 11:03:31 -06:00
log.info("server: started server\0")
2024-11-10 12:57:48 -06:00
}
2024-11-13 11:03:31 -06:00
incoming := fn(): bool {
msg := recv_header(server.channel.server)
if msg == null {
2024-11-10 19:03:01 -06:00
return true
}
2024-11-13 11:03:31 -06:00
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, server.channel.client)
2024-11-13 11:03:31 -06:00
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
data := WindowData.(props.body, channel, permissions.default)
send_message(WindowData, message.ack, data, channel.client)
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
2024-11-10 12:57:48 -06:00
}
2024-11-10 19:03:01 -06:00
return true
2024-11-13 11:03:31 -06:00
}
$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.data.channel.server)
if header == null | @unwrap(header).kind != message.frame_ready {
return
}
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
2024-11-13 11:03:31 -06:00
}
put_surface(screen, window.surface, window.data.props.position, false)
2024-11-13 11:03:31 -06:00
sync(screen)
2024-11-10 12:57:48 -06:00
}