use crate::{BAD_HANDLE, Instance, OK, REG, next_id, with};
use kevy_embedded::{Config, Store};
pub const OPEN_CAPTURE_AOF: u32 = 1;
#[unsafe(no_mangle)]
pub extern "C" fn kevy_abi_version() -> u32 {
crate::ABI_VERSION
}
#[unsafe(no_mangle)]
pub extern "C" fn kevy_alloc(len: u32) -> *mut u8 {
let mut buf = Vec::<u8>::with_capacity(len as usize);
let ptr = buf.as_mut_ptr();
std::mem::forget(buf);
ptr
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn kevy_free(ptr: *mut u8, len: u32) {
unsafe { drop(Vec::from_raw_parts(ptr, 0, len as usize)) }
}
#[unsafe(no_mangle)]
pub extern "C" fn kevy_open(flags: u32) -> u32 {
let Ok(store) = Store::open(Config::default().with_ttl_reaper_manual()) else {
return 0;
};
let id = next_id();
REG.lock()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.insert(id, Instance::new(store, flags & OPEN_CAPTURE_AOF != 0));
id
}
#[unsafe(no_mangle)]
pub extern "C" fn kevy_close(h: u32) -> i32 {
match REG.lock().unwrap_or_else(std::sync::PoisonError::into_inner).remove(&h) {
Some(_) => OK,
None => BAD_HANDLE,
}
}
#[unsafe(no_mangle)]
pub extern "C" fn kevy_set_clock(now_ms: f64) {
let ms = if now_ms > 0.0 { now_ms as u64 } else { 0 };
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
{
kevy_embedded::set_clock_ns(ms.saturating_mul(1_000_000));
kevy_embedded::set_wall_clock_ms(ms);
}
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
let _ = ms;
}
#[unsafe(no_mangle)]
pub extern "C" fn kevy_tick(h: u32) -> i32 {
with(h, BAD_HANDLE, |inst| inst.store.tick().expired as i32)
}
#[unsafe(no_mangle)]
pub extern "C" fn kevy_out_ptr(h: u32) -> *const u8 {
with(h, std::ptr::null(), |inst| inst.out.as_ptr())
}
#[unsafe(no_mangle)]
pub extern "C" fn kevy_out_len(h: u32) -> u32 {
with(h, 0, |inst| inst.out.len() as u32)
}