sunset work, stn changes, and fiddling with kernel logging clutter

This commit is contained in:
koniifer 2024-11-11 21:48:43 +00:00
parent e40a22fccd
commit 8ad7542b9c
17 changed files with 202 additions and 241 deletions

18
Cargo.lock generated
View file

@ -13,9 +13,9 @@ dependencies = [
[[package]] [[package]]
name = "allocator-api2" name = "allocator-api2"
version = "0.2.19" version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "611cc2ae7d2e242c457e4be7f97036b8ad9ca152b499f53faf99b1ed8fc2553f" checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9"
[[package]] [[package]]
name = "anyhow" name = "anyhow"
@ -228,12 +228,12 @@ dependencies = [
[[package]] [[package]]
name = "hbbytecode" name = "hbbytecode"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b6274f3455d0545a64f2cc866b39d409e0a73427" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d99672b75179b79249c4b6b91dfccef0b757fa3a"
[[package]] [[package]]
name = "hblang" name = "hblang"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b6274f3455d0545a64f2cc866b39d409e0a73427" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d99672b75179b79249c4b6b91dfccef0b757fa3a"
dependencies = [ dependencies = [
"hashbrown 0.15.1", "hashbrown 0.15.1",
"hbbytecode", "hbbytecode",
@ -245,7 +245,7 @@ dependencies = [
[[package]] [[package]]
name = "hbvm" name = "hbvm"
version = "0.1.0" version = "0.1.0"
source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#b6274f3455d0545a64f2cc866b39d409e0a73427" source = "git+https://git.ablecorp.us/AbleOS/holey-bytes.git#d99672b75179b79249c4b6b91dfccef0b757fa3a"
dependencies = [ dependencies = [
"hbbytecode", "hbbytecode",
] ]
@ -675,18 +675,18 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.214" version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.214" version = "1.0.215"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View file

@ -111,7 +111,7 @@ unsafe extern "C" fn oops() -> ! {
unsafe extern "C" fn start() -> ! { unsafe extern "C" fn start() -> ! {
logging::init(); logging::init();
crate::logger::init().expect("failed to set logger"); crate::logger::init().expect("failed to set logger");
log::info!("Initialising AKern {}", crate::VERSION); log::debug!("Initialising AKern {}", crate::VERSION);
static HDHM_REQ: HhdmRequest = HhdmRequest::new(0); static HDHM_REQ: HhdmRequest = HhdmRequest::new(0);
memory::init_pt(VirtAddr::new( memory::init_pt(VirtAddr::new(
@ -190,7 +190,7 @@ unsafe extern "C" fn start() -> ! {
// TODO: Add in rdseed and rdrand as sources for randomness // TODO: Add in rdseed and rdrand as sources for randomness
let _rand = xml::XMLElement::new("Random"); let _rand = xml::XMLElement::new("Random");
log::trace!("Getting boot modules"); log::debug!("Getting boot modules");
let bm = MOD_REQ.get_response().get(); let bm = MOD_REQ.get_response().get();
let mut bootmodules = alloc::vec::Vec::new(); let mut bootmodules = alloc::vec::Vec::new();
@ -228,7 +228,7 @@ unsafe extern "C" fn start() -> ! {
break; break;
} }
} }
log::info!("Boot module count: {:?}", bootmodules.len()); log::debug!("Boot module count: {:?}", bootmodules.len());
assert_eq!(bm.module_count, bootmodules.len() as u64); assert_eq!(bm.module_count, bootmodules.len() as u64);
} }

View file

@ -69,7 +69,7 @@ pub fn check_device(bus: u8, device: u8) -> Option<PciDeviceInfo> {
} }
let (reg2, addr) = unsafe { pci_config_read_2(bus, device, 0, 0x8) }; let (reg2, addr) = unsafe { pci_config_read_2(bus, device, 0, 0x8) };
log::info!("pci device-({}) addr {} is {}", device, addr, reg2); log::debug!("pci device-({}) addr {} is {}", device, addr, reg2);
let class = ((reg2 >> 16) & 0x0000_FFFF) as u16; let class = ((reg2 >> 16) & 0x0000_FFFF) as u16;
let pci_class = PciFullClass::from_u16(class); let pci_class = PciFullClass::from_u16(class);
let header_type = get_header_type(bus, device, 0); let header_type = get_header_type(bus, device, 0);

View file

@ -58,10 +58,10 @@ pub fn handler(vm: &mut Vm) {
true => IpcBuffer::new(true, length), true => IpcBuffer::new(true, length),
}, },
); );
info!("Buffer ID: {}", buff_id);
vm.registers[1] = hbvm::value::Value(buff_id); vm.registers[1] = hbvm::value::Value(buff_id);
} }
2 => { 2 => {
log::error!("Oops, deleting buffers is not implemented.")
// Delete buffer // Delete buffer
} }
3 => { 3 => {

View file

@ -9,7 +9,20 @@ use log::Record;
pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> { pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
let msg_vec = block_read(mem_addr, length); let msg_vec = block_read(mem_addr, length);
let log_level = msg_vec[0]; use log::Level::*;
let log_level = match msg_vec[0] {
0 | 48 => Error,
1 | 49 => Warn,
2 | 50 => Info,
3 | 51 => Debug,
4 | 52 => Trace,
_ => {
return Err(LogError::InvalidLogFormat);
}
};
if log_level > log::max_level() {
return Ok(());
}
let strptr = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap()); let strptr = u64::from_le_bytes(msg_vec[1..9].try_into().unwrap());
let strlen = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap()) as usize; let strlen = u64::from_le_bytes(msg_vec[9..17].try_into().unwrap()) as usize;
@ -20,18 +33,6 @@ pub fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(),
match core::str::from_utf8(&str) { match core::str::from_utf8(&str) {
Ok(strr) => { Ok(strr) => {
use log::Level::*;
let log_level = match log_level {
0 | 48 => Error,
1 | 49 => Warn,
2 | 50 => Info,
3 | 51 => Debug,
4 | 52 => Trace,
_ => {
return Err(LogError::InvalidLogFormat);
}
};
log::logger().log( log::logger().log(
&Record::builder() &Record::builder()
.args(format_args!("{}", strr)) .args(format_args!("{}", strr))

View file

@ -71,7 +71,18 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
let cmd = module.cmd.trim_matches('"'); let cmd = module.cmd.trim_matches('"');
let cmd_len = cmd.len() as u64; let cmd_len = cmd.len() as u64;
log::info!("Spawning {} with arguments \"{}\"", module.path, cmd); log::info!(
"Starting {}",
module
.path
.split('/')
.last()
.unwrap()
.split('.')
.next()
.unwrap()
);
log::debug!("Spawning {} with arguments \"{}\"", module.path, cmd);
// decode AbleOS Executable format // decode AbleOS Executable format
let header = &module.bytes[0..46]; let header = &module.bytes[0..46];
@ -92,7 +103,7 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
let code_length = u64::from_le_bytes(header[7..15].try_into().unwrap()); let code_length = u64::from_le_bytes(header[7..15].try_into().unwrap());
let data_length = u64::from_le_bytes(header[15..23].try_into().unwrap()); let data_length = u64::from_le_bytes(header[15..23].try_into().unwrap());
let end = (code_length + data_length) as usize; let end = (code_length + data_length) as usize;
log::info!("{code_length} + {data_length} = {end}"); log::debug!("{code_length} + {data_length} = {end}");
let mut thr = ExecThread::new(&module.bytes[offset..end], Address::new(0)); let mut thr = ExecThread::new(&module.bytes[offset..end], Address::new(0));
if cmd_len > 0 { if cmd_len > 0 {

View file

@ -4,15 +4,15 @@ recv := fn($Expr: type, buffer_id: uint, memory_map_location: ^Expr): void {
return @eca(4, buffer_id, memory_map_location, @sizeof(Expr)) return @eca(4, buffer_id, memory_map_location, @sizeof(Expr))
} }
write := fn($Expr: type, msg: ^Expr, buffer_id: uint): void { write := fn($Expr: type, buffer_id: uint, msg: ^Expr): void {
return @eca(3, buffer_id, msg, @sizeof(Expr)) return @eca(3, buffer_id, msg, @sizeof(Expr))
} }
recv_length := fn(buffer_id: uint, memory_map_location: ^u8, length: uint): void { recv_length := fn(length: uint, memory_map_location: ^u8, buffer_id: uint): void {
return @eca(4, buffer_id, memory_map_location, length) return @eca(4, buffer_id, memory_map_location, length)
} }
write_length := fn(msg: ^u8, buffer_id: uint, length: uint): void { write_length := fn(length: uint, msg: ^u8, buffer_id: uint): void {
return @eca(3, buffer_id, msg, length) return @eca(3, buffer_id, msg, length)
} }
@ -22,6 +22,14 @@ create := fn(msg: ^u8): uint {
return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg)) return @eca(3, 0, BufferMsg.(0, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
} }
create_without_name := fn(): uint {
return @eca(1, 0)
}
delete_buffer := fn(buffer_id: uint): void {
return @eca(2, buffer_id)
}
search := fn(msg: ^u8): uint { search := fn(msg: ^u8): uint {
return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg)) return @eca(3, 0, BufferMsg.(3, msg, @inline(string.length, msg)), @sizeof(BufferMsg))
} }

View file

@ -4,118 +4,60 @@ length := fn(ptr: ^u8): uint {
} }
display_int := fn(num: int, p: ^u8, radix: uint): ^u8 { display_int := fn(num: int, p: ^u8, radix: uint): ^u8 {
is_negative := num < 0
if is_negative num = -num
ptr := p ptr := p
negative := num < 0
if negative {
num = -num
}
if radix == 2 {
*ptr = 48
ptr += 1;
*ptr = 98
ptr += 1
} else if radix == 16 {
*ptr = 48
ptr += 1;
*ptr = 120
ptr += 1
} else if radix == 8 {
*ptr = 48
ptr += 1;
*ptr = 111
ptr += 1
}
digits_start := ptr
if num == 0 { if num == 0 {
*ptr = 48 *ptr = 0x30;
ptr += 1 *(ptr + 1) = 0
} else { return p
}
loop if num == 0 break else { loop if num == 0 break else {
digit := num % @bitcast(radix) remainder := num % @bitcast(radix)
if digit < 10 { num /= @bitcast(radix);
*ptr = @intcast(digit) + 48 *ptr = @intcast(remainder + 0x30)
} else { if remainder > 9 {
*ptr = @intcast(digit) + 55 *ptr = @intcast(remainder - 10 + 0x41)
} }
ptr += 1 ptr += 1
num /= @bitcast(radix)
}
} }
if negative { if is_negative {
*ptr = 45 *ptr = 0x2D
ptr += 1 ptr += 1
}; }
// ! it gets broked when you do this ??
*ptr = 0 // *ptr = 0
@inline(reverse, digits_start)
@inline(reverse, p)
return p return p
} }
reverse := fn(s: ^u8): void { reverse := fn(s: ^u8): void {
i := 0 j := s + @inline(length, s) - 1
j := @inline(length, s) - 1
temp := @as(u8, 0) temp := @as(u8, 0)
loop if i >= j break else { loop if s < j {
temp = *(s + i); temp = *s;
*(s + i) = *(s + j); *s = *j;
*(s + j) = temp *j = temp
i += 1 s += 1
j -= 1 j -= 1
} } else return
return
} }
equals := fn(lhs: ^u8, rhs: ^u8): bool { equals := fn(lhs: ^u8, rhs: ^u8): bool {
if lhs == rhs { if lhs == rhs {
return true return true
} }
i := 0 loop if *lhs != *rhs {
loop if *(lhs + i) != *(rhs + i) {
return false return false
} else if *lhs == 0 { } else if *lhs == 0 {
return true return true
} else { } else {
i += 1 lhs += 1
rhs += 1
} }
} }
contains := fn(haystack: ^u8, needle: ^u8): bool {
haystack_len := @inline(length, haystack)
needle_len := @inline(length, needle)
if needle_len == 0 {
return true
}
if haystack_len < needle_len {
return false
}
max_start := haystack_len - needle_len
pos := 0
loop if pos > max_start break else {
is_match := true
offset := 0
loop if offset >= needle_len break else {
if *(haystack + pos + offset) != *(needle + offset) {
is_match = false
}
if is_match == false {
break
}
offset += 1
}
if is_match {
return true
}
pos += 1
}
return false
}

View file

@ -1,79 +1,59 @@
.{math: .{Vec2}, buffer, log, memory} := @use("../../stn/src/lib.hb"); .{math: .{Vec2}, buffer, log, memory} := @use("../../stn/src/lib.hb");
.{Surface, new_surface} := @use("../../render/src/lib.hb"); .{Window, WindowData, WindowProps, MessageHeader, send_message, message, await_buffer, await_message, BUFFER} := @use("./lib.hb")
.{Window, WindowData, WindowProps, MessageHeader, message, BUFFER} := @use("./lib.hb") render := @use("../../render/src/lib.hb")
server_id := @as(?uint, null) server_id := @as(uint, idk)
screen := @as(render.Surface, idk)
init := fn(): void { find_server := fn(): void {
log.info("client: waiting for server\0") // ! to be removed in the future
id := 0 screen = render.init(false)
loop if id != 0 { render.clear(screen, render.black)
server_id = id log.debug("client: waiting for server\0")
log.info("client: done waiting\0") server_id = await_buffer(BUFFER)
return log.debug("client: found server\0")
} else {
id = buffer.search(BUFFER)
} }
}
// wait_for_message := fn($Expr: type, ptr: ^?Expr, buffer_id: uint): bool {
// timer := 0
// loop if timer < 1000 {
// buffer.recv(?Expr, buffer_id, ptr)
// if *ptr != null {
// return true
// }
// timer -= 1
// }
// return false
// }
new := fn(props: WindowProps): ?Window { new := fn(props: WindowProps): ?Window {
if server_id == null { send_message(MessageHeader, .(message.syn, 0), server_id)
init() log.debug("client: sent syn\0")
} response := await_message(MessageHeader, server_id)
buffer.write(?MessageHeader, &@as(?MessageHeader, .(message.syn, @sizeof(WindowProps))), @unwrap(server_id))
log.info("client: sent syn\0")
timer := 0
response := memory.uninit(MessageHeader)
// if wait_for_message(MessageHeader, &response, @unwrap(server_id)) == false {
// return null
// }
loop if timer < 1000 {
buffer.recv(?MessageHeader, @unwrap(server_id), &response)
if response != null {
break
}
timer += 1
} else {
log.error("client: no response in timeout\0")
return null
}
if response.kind != message.ack { if response.kind != message.ack {
log.error("client: refused\0") log.error("client: refused syn\0")
return null return null
} }
log.info("client: received ack\0") log.debug("client: got ack\0")
buffer_id := response.data buffer_id := response.data
buffer.write(?WindowProps, &@as(?WindowProps, props), buffer_id) send_message(WindowProps, props, buffer_id)
log.info("client: sent props\0") log.debug("client: sent props\0")
timer = 0 response2 := await_message(WindowData, buffer_id)
response2 := memory.uninit(WindowData) log.debug("client: got window data\0")
loop if timer < 1000 { surface := render.new_surface(
buffer.recv(?WindowData, buffer_id, &response2)
if response2 != null {
log.info("client: received window data\0")
surface := new_surface(
response2.props.dimensions.x, response2.props.dimensions.x,
response2.props.dimensions.y, response2.props.dimensions.y,
) )
return .(@as(WindowData, response2), surface) return .(@as(WindowData, response2), surface)
} }
timer += 1
// ! client buffers are not being read by the server yet
quit := fn(client: Window): void {
send_message(MessageHeader, .(message.quit, 0), client.data.buffer_id)
} }
return null
shutdown_server := fn(): void {
send_message(MessageHeader, .(message.shutdown, 0), server_id)
}
update_props := fn(client: Window): bool {
log.error("client: update props unimplemented\0")
return false
}
//! temporarily just throw our window at the screen
frame_ready := fn(client: Window): void {
send_message(MessageHeader, .(message.ready, 0), client.data.buffer_id)
log.warn("client: we are blitting to screen from the client\n\r this is temporary behaviour\0")
render.put_surface(screen, client.surface, client.data.props.position, false)
} }

View file

@ -1,4 +1,4 @@
.{math: .{Vec2}} := @use("../../stn/src/lib.hb"); .{math: .{Vec2}, buffer, memory} := @use("../../stn/src/lib.hb");
.{Surface} := @use("../../render/src/lib.hb") .{Surface} := @use("../../render/src/lib.hb")
$BUFFER := "sunset\0" $BUFFER := "sunset\0"
@ -7,6 +7,34 @@ client := @use("./client.hb")
server := @use("./server.hb") server := @use("./server.hb")
message := @use("./message.hb") message := @use("./message.hb")
receive_message := fn($Expr: type, buffer_id: uint): ?Expr {
recv := @as(?Expr, null)
@inline(buffer.recv, ?Expr, buffer_id, &recv)
return recv
}
send_message := fn($Expr: type, msg: Expr, buffer_id: uint): void {
@inline(buffer.write, ?Expr, buffer_id, &@as(?Expr, msg))
}
await_buffer := fn(name: ^u8): uint {
id := 0
loop if id != 0 return id else id = buffer.search(BUFFER)
}
await_message := fn($Expr: type, buffer_id: uint): Expr {
response := @as(?Expr, null)
loop {
@inline(buffer.recv, ?Expr, buffer_id, &response)
if response != null {
i := 0
return @as(Expr, response)
}
}
}
// ! we need a better message format but this will do for now.
// enums would be nice
MessageHeader := packed struct { MessageHeader := packed struct {
kind: uint, kind: uint,
data: uint, data: uint,
@ -15,7 +43,7 @@ MessageHeader := packed struct {
WindowProps := struct { WindowProps := struct {
position: Vec2(uint), position: Vec2(uint),
dimensions: Vec2(uint), dimensions: Vec2(uint),
// replace with owned string type later // ! replace with owned string type later
title: ^u8, title: ^u8,
} }

View file

@ -1,6 +1,8 @@
// ! all values in this file are subject to change.
$syn := 1 $syn := 1
$ack := 2 $ack := 2
$refused := 3 $refused := 3
$quit := 4 $quit := 4
$update_props := 5 $update_props := 5
$shutdown := 6 $shutdown := 6
$ready := 7

View file

@ -1,65 +1,46 @@
.{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb"); .{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb");
.{Surface, new_surface} := @use("../../render/src/lib.hb"); .{Surface, new_surface} := @use("../../render/src/lib.hb");
.{Window, WindowProps, WindowData, MessageHeader, BUFFER, message} := @use("./lib.hb") .{Window, WindowProps, WindowData, MessageHeader, BUFFER, message, receive_message, send_message, await_message} := @use("./lib.hb")
WindowServer := struct { WindowServer := struct {
window_count: uint, window_count: uint,
id: uint, id: uint,
// replace this with an actual collection when we get an allocator // ! replace this with an actual collection when we get an allocator
windows: ^WindowData, windows: ^WindowData,
} }
server := @as(?WindowServer, null) // ! in the future this should be safely handled
server := @as(WindowServer, idk)
init := fn(): void { start := fn(): void {
if server != null {
return
}
log.info("server: starting server\0")
windows := memory.alloc(WindowData, 10) windows := memory.alloc(WindowData, 10)
server = .(0, buffer.create(BUFFER), windows) server = .(0, buffer.create(BUFFER), windows)
log.debug("server: started server\0")
} }
// ! this function will be rewritten to several functions that allow the server mainloop to handle these itself
handle_connections := fn(): bool { handle_connections := fn(): bool {
if server == null { recv := receive_message(MessageHeader, server.id)
return false
}
recv := memory.uninit(MessageHeader)
buffer.recv(?MessageHeader, @unwrap(server).id, &recv)
if recv == null { if recv == null {
return true return true
} else if recv.kind == message.syn { }
buffer_id := buffer.create("asdf\0") if recv.kind == message.syn {
buffer.write(?MessageHeader, &@as(?MessageHeader, .(message.ack, buffer_id)), @unwrap(server).id) buffer_id := buffer.create_without_name()
log.info("server: sent ack\0")
send_message(MessageHeader, .(message.ack, buffer_id), server.id)
log.debug("server: sent ack\0")
resp := await_message(WindowProps, buffer_id)
log.debug("server: received props\0")
timer := 0
resp := memory.uninit(WindowProps)
loop if timer < 1000 {
buffer.recv(?WindowProps, buffer_id, &resp)
if resp != null {
break
}
timer += 1
} else {
log.error("server: no props in timeout\0")
return true
}
log.info("server: received props\0")
surface := new_surface(resp.dimensions.x, resp.dimensions.y)
data := WindowData.(@as(WindowProps, resp), buffer_id) data := WindowData.(@as(WindowProps, resp), buffer_id)
buffer.write(?WindowData, &@as(?WindowData, data), buffer_id) send_message(WindowData, data, buffer_id)
log.info("server: sent window data\0"); log.debug("server: sent window data\0");
*(@unwrap(server).windows + @unwrap(server).window_count) = data *(server.windows + server.window_count) = data
@unwrap(server).window_count += 1 server.window_count += 1
} else if recv.kind == message.quit {
// todo: quit
} else if recv.kind == message.shutdown { } else if recv.kind == message.shutdown {
log.warn("server: shutdown handled without validation\n\r this is temporary behaviour\0")
return false return false
} }
return true return true
} }
should_shutdown := fn(): bool {
return false
}

View file

@ -34,7 +34,7 @@ main := fn(): int {
prev_input = input prev_input = input
kevent := KeyEvent.(false, true, input) kevent := KeyEvent.(false, true, input)
buffer.write(KeyEvent, &kevent, buf) buffer.write(KeyEvent, buf, &kevent)
} }
return 0 return 0
} }

View file

@ -145,7 +145,7 @@ main := fn(): int {
event.x_change = x_change event.x_change = x_change
event.y_change = y_change event.y_change = y_change
buffer.write(MouseEvent, &event, mouse_buffer) buffer.write(MouseEvent, mouse_buffer, &event)
} }
return 0 return 0

View file

@ -12,10 +12,10 @@ example := fn(): void {
loop { loop {
render.clear(screen, color) render.clear(screen, color)
render.sync(screen) render.sync(screen)
if (color.b & 255) == 255 | (color.b & 255) == 0 { if color.b == 255 | color.b == 0 {
n = -n // compiler bug workaround
n = 0 - n
} }
color.b += n color.b += n
} }
return
} }

View file

@ -1,12 +1,20 @@
.{log, string} := @use("../../../libraries/stn/src/lib.hb") .{log, string} := @use("../../../libraries/stn/src/lib.hb")
sunset := @use("../../../libraries/sunset_proto/src/lib.hb") sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
render := @use("../../../libraries/render/src/lib.hb")
main := fn(): void { main := fn(): void {
window := sunset.client.new(.(.(100, 100), .(100, 100), "Hello, World!\0")) sunset.client.find_server()
if window == null { client := sunset.client.new(.(.(100, 100), .(100, 100), "Hello, World!\0"))
log.error("client: window was null\0") if client == null {
log.error("we did not get a window\0")
return return
} }
log.info("client: window title:\0") if sunset.client.update_props(client) == false {
log.info(window.data.props.title) log.error("we did not update props\0")
}
render.put_filled_circle(client.surface, .(50, 50), 20, render.white)
sunset.client.frame_ready(client)
sunset.client.quit(client)
sunset.client.shutdown_server()
} }

View file

@ -1,7 +1,7 @@
sunset := @use("../../../libraries/sunset_proto/src/lib.hb") sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
main := fn(): void { main := fn(): void {
sunset.server.init() sunset.server.start()
loop if sunset.server.handle_connections() { loop if sunset.server.handle_connections() {
} }
} }