pub use canary_types::*; #[macro_export] macro_rules! export_abi { ($panel_impl: ident) => { #[no_mangle] pub extern "C" fn bind_panel(panel: u32) -> u32 { ::canary_script::abi::bind_panel::<$panel_impl>(panel) } #[no_mangle] pub extern "C" fn update(dt: f32) { ::canary_script::abi::update(dt) } #[no_mangle] pub extern "C" fn draw() { ::canary_script::abi::draw() } #[no_mangle] pub extern "C" fn on_cursor_event(kind: u32, x: f32, y: f32) { ::canary_script::abi::on_cursor_event(kind, x, y) } }; } pub mod abi { use super::*; use num_traits::FromPrimitive; static mut PANEL_IMPLS: Vec> = Vec::new(); pub fn bind_panel(panel: u32) -> u32 { unsafe { let panel = Panel(panel); let panel_impl = T::bind(panel); let id = PANEL_IMPLS.len() as u32; PANEL_IMPLS.push(panel_impl); id } } pub fn update(dt: f32) { unsafe { for panel in PANEL_IMPLS.iter_mut() { panel.update(dt); } } } pub fn draw() { unsafe { for panel in PANEL_IMPLS.iter_mut() { panel.draw(); } } } pub fn on_cursor_event(kind: u32, x: f32, y: f32) { let panel = unsafe { &mut PANEL_IMPLS[0] }; let at = canary_types::Vec2 { x, y }; let kind = CursorEventKind::from_u32(kind).unwrap(); panel.on_cursor_event(kind, at); } } pub trait BindPanel { fn bind(panel: Panel) -> Box; } pub trait PanelImpl { fn update(&mut self, dt: f32); fn draw(&mut self); fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2); } #[repr(transparent)] #[derive(Copy, Clone)] pub struct Panel(u32); impl Panel { pub unsafe fn bind(id: u32) -> Self { Self(id) } pub fn draw_triangle(&self, v1: Vec2, v2: Vec2, v3: Vec2, color: Color) { unsafe { UiPanel_drawTriangle( self.0, v1.x, v1.y, v2.x, v2.y, v3.x, v3.y, color.r, color.g, color.b, color.a, ) } } } extern "C" { fn UiPanel_drawTriangle( panel: u32, x1: f32, y1: f32, x2: f32, y2: f32, x3: f32, y3: f32, r: f32, g: f32, b: f32, a: f32, ); }