canary-rs/crates/script/src/lib.rs

111 lines
2.5 KiB
Rust

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<Box<dyn PanelImpl>> = Vec::new();
pub fn bind_panel<T: BindPanel>(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<dyn PanelImpl>;
}
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,
);
}