use std::ffi::c_void;
use std::ptr;
struct Runtime {
ch: crate::base::Chan,
out: Vec<u8>,
}
impl Runtime {
pub fn update(&mut self, dt: f32, raw: &[u8]) -> &[u8] {
self.out.clear();
self.ch.update(dt, raw, &mut self.out);
&self.out
}
}
#[unsafe(no_mangle)]
pub extern "C" fn silo_alloc() -> *mut c_void {
let runtime = Box::new(Runtime {
ch: crate::base::RUNTIME.chan(),
out: Vec::new(),
});
Box::into_raw(runtime) as *mut c_void
}
#[unsafe(no_mangle)]
pub extern "C" fn silo_update(
runtime_ptr: *mut c_void,
dt: f32,
raw: *const u8,
raw_len: usize,
out_size: *mut usize,
) -> *const u8 {
if runtime_ptr.is_null() {
if !out_size.is_null() {
unsafe { *out_size = 0 };
}
return ptr::null();
}
let runtime = unsafe { &mut *(runtime_ptr as *mut Runtime) };
let raw_slice = if raw.is_null() || raw_len == 0 {
&[]
} else {
unsafe { std::slice::from_raw_parts(raw, raw_len) }
};
let result = runtime.update(dt, raw_slice);
if !out_size.is_null() {
unsafe { *out_size = result.len() };
}
result.as_ptr()
}
#[unsafe(no_mangle)]
pub extern "C" fn silo_dealloc(runtime_ptr: *mut c_void) {
if !runtime_ptr.is_null() {
let runtime = unsafe { &mut *(runtime_ptr as *mut Runtime) };
runtime.ch.close();
unsafe {
let _ = Box::from_raw(runtime_ptr as *mut Runtime);
}
}
}