use crate::{Context, Game, Graphics};
#[doc(hidden)]
pub mod __internal {
use super::*;
use core::cell::UnsafeCell;
pub use crate::fmt::{format_args_to_buf, FmtBuf, LINE_CAP};
pub struct Slot<G>(UnsafeCell<Option<G>>);
unsafe impl<G> Sync for Slot<G> {}
impl<G> Slot<G>
where
G: Game,
{
pub const fn new() -> Self {
Slot(UnsafeCell::new(None))
}
pub fn init(&self, make: impl FnOnce() -> G) {
#[cfg(feature = "std")]
std::panic::set_hook(std::boxed::Box::new(|info| {
let msg = info.to_string();
unsafe { crate::ffi::panic(msg.as_ptr(), msg.len() as u32) };
}));
*self.get() = Some(make());
}
pub fn fps(&self) -> u32 {
G::FRAME_RATE.fps()
}
pub fn update(&self) {
if let Some(game) = self.get() {
game.update(&mut Context { _private: () });
}
}
pub fn draw(&self) {
if let Some(game) = self.get() {
game.draw(&mut Graphics { _private: () });
}
}
#[allow(clippy::mut_from_ref)]
fn get(&self) -> &mut Option<G> {
unsafe { &mut *self.0.get() }
}
}
impl<G> Default for Slot<G>
where
G: Game,
{
fn default() -> Self {
Self::new()
}
}
}
#[cfg(not(feature = "std"))]
#[panic_handler]
fn handle_panic(info: &core::panic::PanicInfo) -> ! {
use core::fmt::Write;
let mut buf = crate::fmt::FmtBuf::<256>::new();
let _ = write!(buf, "{info}");
let msg = buf.as_str();
unsafe { crate::ffi::panic(msg.as_ptr(), msg.len() as u32) };
#[cfg(target_arch = "wasm32")]
core::arch::wasm32::unreachable();
#[cfg(not(target_arch = "wasm32"))]
loop {}
}