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}