.{math: .{Vec2}, buffer, log, memory} := @use("../../stn/src/lib.hb"); .{Surface, new_surface} := @use("../../render/src/lib.hb"); .{Window, WindowData, WindowProps, MessageHeader, message, BUFFER} := @use("./lib.hb") server_id := @as(?uint, null) init := fn(): void { log.info("client: waiting for server\0") id := 0 loop if id != 0 { server_id = id log.info("client: done waiting\0") return } 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 { if server_id == null { init() } 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 { log.error("client: refused\0") return null } log.info("client: received ack\0") buffer_id := response.data buffer.write(?WindowProps, &@as(?WindowProps, props), buffer_id) log.info("client: sent props\0") timer = 0 response2 := memory.uninit(WindowData) loop if timer < 1000 { 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.y, ) return .(@as(WindowData, response2), surface) } timer += 1 } return null }