Skip to main content

repame_shell/
quit.rs

1//! Quitting: the one thing a game cannot do the same way on every platform.
2//!
3//! `std::process::exit` is `unreachable` on `wasm32-unknown-unknown`: it traps
4//! the instance and strands every winit `RefCell` guard, so the next event
5//! panics with "RefCell already borrowed". A browser has no window to close
6//! and no exit to call, so a quit there latches instead: the shell keeps
7//! servicing frames while the app stops stepping and paints [`Quit::parked`],
8//! leaving the tab to be closed.
9
10use repose_core::View;
11use repose_core::prelude::Modifier;
12use repose_ui::ZStack;
13
14/// A quit request, latched so a browser shell can park instead of exiting.
15#[derive(Default)]
16pub struct Quit {
17    latched: bool,
18}
19
20impl Quit {
21    /// Ask to quit. Does not return off the web, where the process exits
22    /// here.
23    pub fn request(&mut self) {
24        self.latched = true;
25        #[cfg(not(target_arch = "wasm32"))]
26        std::process::exit(0);
27    }
28
29    /// Whether the quit is latched, and the app is parked.
30    pub fn latched(&self) -> bool {
31        self.latched
32    }
33
34    /// The root a parked shell paints: empty, so nothing is drawn.
35    pub fn parked() -> View {
36        ZStack(Modifier::new().fill_max_size())
37    }
38}