use std::{io::BufRead, sync::Mutex};
use log::Level;
struct System {
read_line: Mutex<Option<(u32, usize, usize)>>,
pre_queued: Mutex<Option<String>>,
}
impl ardaku::System for System {
fn sleep(
&self,
bytes: &mut [u8],
ready_size: usize,
ready_data: usize,
) -> usize {
log::debug!(target: "demo", "READY DATA: {ready_data:x} ({ready_size})");
log::debug!(target: "demo", "sleep");
let stdin = std::io::stdin();
let mut handle = stdin.lock();
{
let buffer =
if let Some(buf) = self.pre_queued.lock().unwrap().take() {
buf
} else {
let mut buffer = String::with_capacity(1024);
handle.read_line(&mut buffer).unwrap();
if buffer.ends_with('\n') {
buffer.pop();
}
buffer
};
let (ready, text, capptr) = self.read_line.lock().unwrap().unwrap();
let mut reader = ardaku::parse::Reader::new(&bytes[text..]);
let _size = usize::try_from(reader.u32()).unwrap();
let addr = usize::try_from(reader.u32()).unwrap();
let mut reader = ardaku::parse::Reader::new(&bytes[capptr..]);
let capacity = usize::try_from(reader.u32()).unwrap();
if capacity < buffer.len() {
let mut writer =
ardaku::parse::Writer::new(&mut bytes[capptr..]);
let size = buffer.len().try_into().unwrap();
writer.u32(size);
*self.pre_queued.lock().unwrap() = Some(buffer);
} else {
let size = {
let mut writer =
ardaku::parse::Writer::new(&mut bytes[text..]);
let size = buffer.len().min(capacity).try_into().unwrap();
writer.u32(size);
usize::try_from(size).unwrap()
};
log::debug!(target: "demo", "Copying {size} bytes...");
{
let buf = &mut bytes[addr..][..size];
buf.copy_from_slice(buffer.as_bytes());
}
}
log::debug!(target: "demo", "Add to ready list");
{
let ready_list = &mut bytes[ready_data..][..ready_size * 4];
let mut writer = ardaku::parse::Writer::new(ready_list);
writer.u32(ready);
}
1
}
}
fn log(&self, text: &str, level: Level, target: &str) {
log::log!(target: target, level, "{text}")
}
fn read_line(&self, ready: u32, index: usize, length: usize) {
let mut read_line = self.read_line.lock().unwrap();
*read_line = Some((ready, index, length));
}
}
fn main() -> ardaku::engine::Result {
env_logger::init();
let app_path = std::env::args().skip(1).next().expect("Provide wasm file!");
let exe = std::fs::read(app_path).expect("Couldn't find file!");
let system = System {
read_line: Mutex::new(None),
pre_queued: Mutex::new(None),
};
ardaku::run(system, &exe)
}