forked from AbleOS/ableos
multi-client support and demo
This commit is contained in:
parent
95b4a921dc
commit
907c0d0dd4
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -228,12 +228,12 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "hbbytecode"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d01e31b2034e53098f92dfb07b183a21857ded1e"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#81cf39b602a64242f2bfb22b0d18ef113e578dd8"
|
||||
|
||||
[[package]]
|
||||
name = "hblang"
|
||||
version = "0.1.0"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d01e31b2034e53098f92dfb07b183a21857ded1e"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#81cf39b602a64242f2bfb22b0d18ef113e578dd8"
|
||||
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#d01e31b2034e53098f92dfb07b183a21857ded1e"
|
||||
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#81cf39b602a64242f2bfb22b0d18ef113e578dd8"
|
||||
dependencies = [
|
||||
"hbbytecode",
|
||||
]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#![allow(unused)]
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::format,
|
||||
fs::{read_to_string, File},
|
||||
io::{BufWriter, Write},
|
||||
|
@ -13,6 +14,7 @@ pub struct Package {
|
|||
name: String,
|
||||
binaries: Vec<String>,
|
||||
build_cmd: String,
|
||||
args: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Package {
|
||||
|
@ -46,26 +48,36 @@ impl Package {
|
|||
let mut binaries = vec![];
|
||||
|
||||
for (count, (name, table)) in bin_table.into_iter().enumerate() {
|
||||
// if count != 0 {
|
||||
binaries.push(name.clone());
|
||||
// }
|
||||
}
|
||||
let build_table = data.get("build").unwrap();
|
||||
|
||||
let mut build_cmd: String = build_table.get("command").unwrap().as_str().unwrap().into();
|
||||
build_cmd.remove(0);
|
||||
// build_cmd.pop();
|
||||
let mut args: HashMap<String, String> = match build_table.get("args") {
|
||||
None => HashMap::new(),
|
||||
Some(v) => v
|
||||
.as_table()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.clone(), v.to_string()))
|
||||
.collect::<HashMap<String, String>>(),
|
||||
};
|
||||
|
||||
Self {
|
||||
name,
|
||||
binaries,
|
||||
build_cmd,
|
||||
args,
|
||||
}
|
||||
}
|
||||
pub fn build(&self, out: &mut Vec<u8>) -> std::io::Result<()> {
|
||||
if self.binaries.contains(&"hblang".to_string()) {
|
||||
let file = self.build_cmd.split_ascii_whitespace().last().unwrap();
|
||||
|
||||
let in_house_regalloc = self
|
||||
.args
|
||||
.get("use_new_regalloc")
|
||||
.map_or(false, |str| str.parse().expect("must be a boolean"));
|
||||
let path = format!("sysdata/programs/{}/{}", self.name, file);
|
||||
// compile here
|
||||
|
||||
|
@ -73,6 +85,7 @@ impl Package {
|
|||
&path,
|
||||
Options {
|
||||
fmt: true,
|
||||
in_house_regalloc,
|
||||
..Default::default()
|
||||
},
|
||||
out,
|
||||
|
@ -87,6 +100,7 @@ impl Package {
|
|||
hblang::run_compiler(
|
||||
&path,
|
||||
Options {
|
||||
in_house_regalloc,
|
||||
..Default::default()
|
||||
},
|
||||
out,
|
||||
|
@ -98,6 +112,7 @@ impl Package {
|
|||
&path,
|
||||
Options {
|
||||
dump_asm: true,
|
||||
in_house_regalloc,
|
||||
..Default::default()
|
||||
},
|
||||
out,
|
||||
|
|
|
@ -7,7 +7,7 @@ channel := Channel.(0, 0)
|
|||
|
||||
find_server := fn(): void {
|
||||
log.info("client: locating server\0")
|
||||
channel2 := await_channel(channel)
|
||||
channel2 := await_channel()
|
||||
channel.server = channel2.server
|
||||
channel.client = channel2.client
|
||||
log.info("client: server located\0")
|
||||
|
@ -51,15 +51,13 @@ update_permissions := fn(client: Window): bool {
|
|||
}
|
||||
|
||||
send_frame := fn(client: Window): bool {
|
||||
server_id := client.data.channel.server
|
||||
client_id := client.data.channel.client
|
||||
send_header(message.frame_ready, server_id)
|
||||
response := await_message(uint, client_id)
|
||||
send_header(message.frame_ready, client.data.channel.server)
|
||||
response := await_message(uint, client.data.channel.client)
|
||||
if response.header.kind != message.ack {
|
||||
return false
|
||||
}
|
||||
// ! 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 await_header(client_id).kind == message.ack
|
||||
send_message(^Color, message.ack, client.surface.buf, client.data.channel.server)
|
||||
return true
|
||||
}
|
|
@ -14,11 +14,11 @@ server := @use("./server.hb")
|
|||
message := @use("./message.hb")
|
||||
permissions := @use("./permissions.hb")
|
||||
|
||||
$send_message := fn($Expr: type, kind: uint, msg: Expr, buffer_id: uint): void {
|
||||
$send_message := fn($Expr: type, kind: MessageKind, msg: Expr, buffer_id: uint): void {
|
||||
buffer.write(?Message(Expr), buffer_id, &@as(?Message(Expr), .(.(kind), msg)))
|
||||
}
|
||||
|
||||
$send_header := fn(kind: uint, buffer_id: uint): void {
|
||||
$send_header := fn(kind: MessageKind, buffer_id: uint): void {
|
||||
buffer.write(?MessageHeader, buffer_id, &@as(?MessageHeader, .(kind)))
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,8 @@ $recv_header := fn(buffer_id: uint): ?MessageHeader {
|
|||
return response
|
||||
}
|
||||
|
||||
await_channel := fn(channel: Channel): Channel {
|
||||
await_channel := fn(): Channel {
|
||||
channel := Channel.(0, 0)
|
||||
loop if channel.server != 0 break else {
|
||||
channel.server = buffer.search(BUFFER_SERVER)
|
||||
}
|
||||
|
@ -64,8 +65,10 @@ await_header := fn(buffer_id: uint): MessageHeader {
|
|||
}
|
||||
}
|
||||
|
||||
MessageKind := u8
|
||||
|
||||
MessageHeader := packed struct {
|
||||
kind: uint,
|
||||
kind: MessageKind,
|
||||
}
|
||||
|
||||
Message := fn($Expr: type): type {
|
||||
|
|
|
@ -21,7 +21,12 @@ start := fn(): void {
|
|||
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))
|
||||
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")
|
||||
}
|
||||
|
||||
|
@ -43,9 +48,12 @@ incoming := fn(): bool {
|
|||
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)
|
||||
// decorations
|
||||
{
|
||||
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
|
||||
}
|
||||
|
@ -58,35 +66,61 @@ $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)
|
||||
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
|
||||
i := 0
|
||||
loop if i == 10 break else {
|
||||
window := server.windows[i]
|
||||
if window == null {
|
||||
i += 1
|
||||
continue
|
||||
}
|
||||
header := recv_header(window.data.channel.server)
|
||||
if header == null {
|
||||
i += 1
|
||||
continue
|
||||
}
|
||||
if header.kind != message.frame_ready {
|
||||
i += 1
|
||||
continue
|
||||
}
|
||||
send_header(message.ack, window.data.channel.client)
|
||||
ptr := await_message(^Color, window.data.channel.server)
|
||||
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,
|
||||
)
|
||||
i += 1
|
||||
}
|
||||
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
|
||||
i := 0
|
||||
loop if i == 10 break else {
|
||||
window := server.windows[i]
|
||||
if window == null {
|
||||
i += 1
|
||||
continue
|
||||
}
|
||||
put_surface(screen, window.surface, window.data.props.position, false)
|
||||
i += 1
|
||||
}
|
||||
put_surface(screen, window.surface, window.data.props.position, false)
|
||||
sync(screen)
|
||||
}
|
|
@ -7,24 +7,23 @@ bmp := @embed("../../../assets/mini.bmp")
|
|||
main := fn(): void {
|
||||
sunset.client.find_server()
|
||||
|
||||
image := render.image.from(@bitcast(&bmp))
|
||||
image := render.image.bmp.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"))
|
||||
window := sunset.client.new(.(.(100, 100), .(200, 200), "Hello,\0"))
|
||||
|
||||
if window == null {
|
||||
log.error("got no window\0")
|
||||
return
|
||||
}
|
||||
x := 0
|
||||
loop {
|
||||
render.clear(window.surface, render.cyan)
|
||||
render.clear(window.surface, render.black)
|
||||
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")
|
||||
}
|
||||
_ = sunset.client.send_frame(window)
|
||||
x += 1
|
||||
}
|
||||
}
|
11
sysdata/programs/sunset_client_2/meta.toml
Normal file
11
sysdata/programs/sunset_client_2/meta.toml
Normal file
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "sunset_client_2"
|
||||
authors = ["koniifer"]
|
||||
|
||||
[dependants.libraries]
|
||||
|
||||
[dependants.binaries]
|
||||
hblang.version = "1.0.0"
|
||||
|
||||
[build]
|
||||
command = "hblang src/main.hb"
|
29
sysdata/programs/sunset_client_2/src/main.hb
Normal file
29
sysdata/programs/sunset_client_2/src/main.hb
Normal file
|
@ -0,0 +1,29 @@
|
|||
.{log} := @use("../../../libraries/stn/src/lib.hb")
|
||||
sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
|
||||
render := @use("../../../libraries/render/src/lib.hb")
|
||||
|
||||
bmp := @embed("../../../assets/able.bmp")
|
||||
|
||||
main := fn(): void {
|
||||
sunset.client.find_server()
|
||||
|
||||
image := render.image.bmp.from(@bitcast(&bmp))
|
||||
if image == null {
|
||||
log.error("got no image\0")
|
||||
return
|
||||
}
|
||||
|
||||
window := sunset.client.new(.(.(400, 300), .(400, 240), "Sunset!\0"))
|
||||
|
||||
if window == null {
|
||||
log.error("got no window\0")
|
||||
return
|
||||
}
|
||||
x := 0
|
||||
loop {
|
||||
render.clear(window.surface, render.black)
|
||||
render.put_surface(window.surface, image, .(image.width + x % window.data.props.dimensions.x, 40), false)
|
||||
_ = sunset.client.send_frame(window)
|
||||
x += 1
|
||||
}
|
||||
}
|
|
@ -37,5 +37,8 @@ resolution = "1024x768x24"
|
|||
[boot.limine.ableos.modules.sunset_client]
|
||||
path = "boot:///sunset_client.hbf"
|
||||
|
||||
[boot.limine.ableos.modules.sunset_client_2]
|
||||
path = "boot:///sunset_client_2.hbf"
|
||||
|
||||
[boot.limine.ableos.modules.sunset_server]
|
||||
path = "boot:///sunset_server.hbf"
|
||||
|
|
Loading…
Reference in a new issue