wormhole/
script_host.rs

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            // Extract function pointers - these are valid as long as the library is loaded
24            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}