#[cfg(target_os = "emscripten")]
pub mod emscripten {
use std::cell::RefCell;
use std::os::raw::c_int;
use super::super::MainLoopEvent;
#[allow(non_camel_case_types)]
type em_callback_func = unsafe extern "C" fn();
extern "C" {
pub fn emscripten_set_main_loop(
func: em_callback_func,
fps: c_int,
simulate_infinite_loop: c_int,
);
pub fn emscripten_cancel_main_loop();
}
thread_local! {
static MAIN_LOOP_CLOSURE: RefCell<Option<Box<dyn FnMut() -> MainLoopEvent>>> = RefCell::new(None);
}
pub fn set_main_loop_callback<F: 'static>(callback: F)
where
F: FnMut() -> MainLoopEvent,
{
MAIN_LOOP_CLOSURE.with(|d| {
*d.borrow_mut() = Some(Box::new(callback));
});
unsafe extern "C" fn wrapper<F>()
where
F: FnMut() -> MainLoopEvent,
{
let mut loop_result = MainLoopEvent::Continue;
MAIN_LOOP_CLOSURE.with(|z| {
if let Some(closure) = &mut *z.borrow_mut() {
loop_result = (*closure)();
}
});
if let MainLoopEvent::Terminate = loop_result {
cancel_main_loop();
}
}
unsafe {
emscripten_set_main_loop(wrapper::<F>, 0, 1);
}
}
pub fn cancel_main_loop() {
unsafe {
emscripten_cancel_main_loop();
}
MAIN_LOOP_CLOSURE.with(|d| {
*d.borrow_mut() = None;
});
}
}