70 lines
2.5 KiB
Rust
70 lines
2.5 KiB
Rust
use std::pin::Pin;
|
|
use std::sync::Mutex;
|
|
use callbacks::RootRetroCallbacks;
|
|
use once_cell::sync::Lazy;
|
|
|
|
pub mod callbacks;
|
|
pub mod constants;
|
|
#[allow(non_camel_case_types, non_upper_case_globals, non_snake_case, dead_code)]
|
|
pub mod ffi;
|
|
pub mod loading;
|
|
pub mod wrapped_types;
|
|
pub mod wrapper;
|
|
|
|
// TODO: macro this
|
|
|
|
pub const MAX_HANDLERS: usize = 8;
|
|
|
|
mod statics_00 { include!("statics.rs"); }
|
|
mod statics_01 { include!("statics.rs"); }
|
|
mod statics_02 { include!("statics.rs"); }
|
|
mod statics_03 { include!("statics.rs"); }
|
|
mod statics_04 { include!("statics.rs"); }
|
|
mod statics_05 { include!("statics.rs"); }
|
|
mod statics_06 { include!("statics.rs"); }
|
|
mod statics_07 { include!("statics.rs"); }
|
|
|
|
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
|
pub struct RetroHandlerId(usize);
|
|
|
|
static mut CALLBACK_REGISTRY: Lazy<Mutex<[bool; MAX_HANDLERS]>> = Lazy::new(|| Mutex::new([false; MAX_HANDLERS]));
|
|
pub fn set_handler(handler: Pin<&'_ mut (dyn RootRetroCallbacks + '_)>) -> Result<RetroHandlerId, Box<dyn std::error::Error>> {
|
|
let mut lock = unsafe { &mut CALLBACK_REGISTRY }.lock()?;
|
|
for (id, taken) in lock.iter_mut().enumerate() {
|
|
if !*taken {
|
|
match id {
|
|
0 => statics_00::set_handler(handler),
|
|
1 => statics_01::set_handler(handler),
|
|
2 => statics_02::set_handler(handler),
|
|
3 => statics_03::set_handler(handler),
|
|
4 => statics_04::set_handler(handler),
|
|
5 => statics_05::set_handler(handler),
|
|
6 => statics_06::set_handler(handler),
|
|
7 => statics_07::set_handler(handler),
|
|
_ => unreachable!(),
|
|
}
|
|
*taken = true;
|
|
return Ok(RetroHandlerId(id))
|
|
}
|
|
}
|
|
Err(format!("only compiled with support for up to {} callback handlers", MAX_HANDLERS).into())
|
|
}
|
|
|
|
pub fn unset_handler(id: RetroHandlerId) -> Result<(), Box<dyn std::error::Error>> {
|
|
let mut lock = unsafe { &mut CALLBACK_REGISTRY }.lock()?;
|
|
if let Some(taken) = lock.get_mut(id.0) {
|
|
*taken = false;
|
|
}
|
|
match id.0 {
|
|
0 => Ok(statics_00::unset_handler()),
|
|
1 => Ok(statics_01::unset_handler()),
|
|
2 => Ok(statics_02::unset_handler()),
|
|
3 => Ok(statics_03::unset_handler()),
|
|
4 => Ok(statics_04::unset_handler()),
|
|
5 => Ok(statics_05::unset_handler()),
|
|
6 => Ok(statics_06::unset_handler()),
|
|
7 => Ok(statics_07::unset_handler()),
|
|
x => Err(format!("invalid RetroHandlerId provided: {}", x).into())
|
|
}
|
|
}
|