use crate::app::state::App;
use crate::ecs::StepResult;
pub fn install_ctrlc_handler(app: &App) {
let token = app.shutdown_token();
let installed = ctrlc::set_handler(move || {
tracing::info!("CTRL+C received, cancelling all subsystems");
token.cancel();
});
if let Err(e) = installed {
tracing::warn!("CTRL+C handler not installed: {e}");
}
}
#[cfg(target_os = "macos")]
pub fn activate_app_macos() {
use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy};
let mtm = objc2::MainThreadMarker::new()
.expect("activate_app_macos must be called from the main thread");
let ns_app = NSApplication::sharedApplication(mtm);
ns_app.setActivationPolicy(NSApplicationActivationPolicy::Regular);
ns_app.activate();
}
pub fn run_loop(app: &mut App, pump_events: bool, mut on_tick: impl FnMut(&mut App)) {
let shutdown = app.shutdown_token();
loop {
if shutdown.is_cancelled() {
tracing::info!("Shutdown token cancelled, exiting loop");
return;
}
#[cfg(target_os = "macos")]
if pump_events {
drain_cocoa_events();
}
#[cfg(not(target_os = "macos"))]
let _ = pump_events;
on_tick(app);
match app.world_step() {
StepResult::Continue => {}
StepResult::Stop | StepResult::Done => return,
}
}
}
#[cfg(target_os = "macos")]
pub(crate) fn drain_cocoa_events() {
use core_foundation::runloop::{CFRunLoopRunInMode, kCFRunLoopDefaultMode};
loop {
let result = unsafe { CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.0, true as u8) };
if result != 4 {
break;
}
}
}