use libloading::{Library, Symbol};
type ScriptInitFn = unsafe extern "C" fn();
type ScriptUpdateFn = unsafe extern "C" fn(f32);
type ScriptRenderFn = unsafe extern "C" fn();
pub struct ScriptHost {
_lib: Library,
init_fn: Symbol<'static, ScriptInitFn>,
update_fn: Symbol<'static, ScriptUpdateFn>,
render_fn: Symbol<'static, ScriptRenderFn>,
}
impl ScriptHost {
pub fn load(path: &std::path::Path) -> Result<Self, Box<dyn std::error::Error>> {
let lib = unsafe { Library::new(path)? };
unsafe {
let init: Symbol<ScriptInitFn> = lib.get(b"script_init\0")?;
let update: Symbol<ScriptUpdateFn> = lib.get(b"script_update\0")?;
let render: Symbol<ScriptRenderFn> = lib.get(b"script_render\0")?;
let init_fn = std::mem::transmute::<Symbol<ScriptInitFn>, Symbol<'static, ScriptInitFn>>(init);
let update_fn = std::mem::transmute::<Symbol<ScriptUpdateFn>, Symbol<'static, ScriptUpdateFn>>(update);
let render_fn = std::mem::transmute::<Symbol<ScriptRenderFn>, Symbol<'static, ScriptRenderFn>>(render);
Ok(ScriptHost {
_lib: lib,
init_fn,
update_fn,
render_fn,
})
}
}
pub fn call_init(&self) {
unsafe {
(self.init_fn)();
}
}
pub fn call_update(&self, delta: f32) {
unsafe {
(self.update_fn)(delta);
}
}
pub fn call_render(&self) {
unsafe {
(self.render_fn)();
}
}
}