canary-rs/crates/egui/src/main.rs

119 lines
3.7 KiB
Rust

use canary::ScriptInstance;
use eframe::egui;
use std::time::Instant;
fn main() {
let args: Vec<String> = std::env::args().collect();
let module_path = args
.get(1)
.expect("Please pass a path to a Canary script!")
.to_owned();
let native_options = eframe::NativeOptions {
multisampling: 8,
..Default::default()
};
eframe::run_native(
"Canary egui Harness",
native_options,
Box::new(move |cc| {
cc.egui_ctx.set_visuals(egui::Visuals::dark());
Box::new(App::new(&module_path))
}),
);
}
struct App {
script: canary::WasmtimeScript<canary::SimpleScriptAbi>,
last_update: Instant,
}
impl App {
pub fn new(module_path: &str) -> Self {
let runtime = canary::WasmtimeRuntime::new().unwrap();
let abi = canary::SimpleScriptAbi::default();
let module = std::fs::read(module_path).unwrap();
let script = runtime.load_module(abi, &module).unwrap();
Self {
script,
last_update: Instant::now(),
}
}
}
impl eframe::App for App {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
ctx.request_repaint();
let dt = self.last_update.elapsed().as_secs_f32();
self.last_update = Instant::now();
self.script.update(dt);
egui::Window::new("Panel").show(ctx, |ui| {
let size = egui::vec2(800.0, 800.0);
let sense = egui::Sense {
click: true,
drag: true,
focusable: false,
};
let (rect, response) = ui.allocate_at_least(size, sense);
// TODO input events
/*let input = ui.input();
for event in input.events.iter() {
let event = match event {
egui::Event::PointerMoved(pos) => {
if input.pointer.primary_down() {
Some(())
}
}
_ => None,
};
if let Some((kind, x, y)) = event {
self.script.on_cursor_event(kind, canary::Vec2 { x, y });
}
}*/
let texture = egui::TextureId::Managed(0);
let uv = egui::pos2(0.0, 0.0);
let mut mesh = egui::Mesh::with_texture(texture);
self.script.draw(|commands| {
for command in commands.iter() {
let voff = mesh.vertices.len() as u32;
match command {
canary::DrawCommand::Mesh { vertices, indices } => {
for v in vertices.iter() {
use egui::epaint::Vertex;
let pos = egui::pos2(v.position.x, -v.position.y);
let pos = pos.to_vec2() / 2.0 + egui::vec2(0.5, 0.5);
let pos = rect.left_top() + pos * rect.size();
let (r, g, b, a) = v.color.to_rgba_unmultiplied();
let color = egui::Color32::from_rgba_unmultiplied(r, g, b, a);
let v = Vertex { pos, uv, color };
mesh.vertices.push(v);
}
for i in indices.iter() {
mesh.indices.push(i + voff);
}
}
_ => unimplemented!(),
}
}
});
let painter = ui.painter_at(rect);
let shape = egui::Shape::mesh(mesh);
painter.add(shape);
response
});
}
}