use canary::ScriptInstance; use eframe::egui; use std::time::Instant; fn main() { let args: Vec = 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, 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 }); } }