1use libloading::{Library, Symbol};
2
3type ScriptInitFn = unsafe extern "C" fn();
4type ScriptUpdateFn = unsafe extern "C" fn(f32);
5type ScriptRenderFn = unsafe extern "C" fn();
6
7pub struct ScriptHost {
8 _lib: Library,
9 init_fn: Symbol<'static, ScriptInitFn>,
10 update_fn: Symbol<'static, ScriptUpdateFn>,
11 render_fn: Symbol<'static, ScriptRenderFn>,
12}
13
14impl ScriptHost {
15 pub fn load(path: &std::path::Path) -> Result<Self, Box<dyn std::error::Error>> {
16 let lib = unsafe { Library::new(path)? };
17
18 unsafe {
19 let init: Symbol<ScriptInitFn> = lib.get(b"script_init\0")?;
20 let update: Symbol<ScriptUpdateFn> = lib.get(b"script_update\0")?;
21 let render: Symbol<ScriptRenderFn> = lib.get(b"script_render\0")?;
22
23 let init_fn = std::mem::transmute::<Symbol<ScriptInitFn>, Symbol<'static, ScriptInitFn>>(init);
25 let update_fn = std::mem::transmute::<Symbol<ScriptUpdateFn>, Symbol<'static, ScriptUpdateFn>>(update);
26 let render_fn = std::mem::transmute::<Symbol<ScriptRenderFn>, Symbol<'static, ScriptRenderFn>>(render);
27
28 Ok(ScriptHost {
29 _lib: lib,
30 init_fn,
31 update_fn,
32 render_fn,
33 })
34 }
35 }
36
37 pub fn call_init(&self) {
38 unsafe {
39 (self.init_fn)();
40 }
41 }
42
43 pub fn call_update(&self, delta: f32) {
44 unsafe {
45 (self.update_fn)(delta);
46 }
47 }
48
49 pub fn call_render(&self) {
50 unsafe {
51 (self.render_fn)();
52 }
53 }
54}