use core::sync::atomic::{AtomicBool, Ordering};
static FORBIDDEN: AtomicBool = AtomicBool::new(false);
pub fn forbid_windows() {
FORBIDDEN.store(true, Ordering::SeqCst);
}
pub fn allow_windows() {
FORBIDDEN.store(false, Ordering::SeqCst);
}
pub fn windows_forbidden() -> bool {
FORBIDDEN.load(Ordering::SeqCst)
}
pub fn assert_windows_allowed(backend: &str) {
assert!(
!windows_forbidden(),
"{backend} tried to open a window in a process that forbids them; \
run the world on the headless loop instead"
);
}
#[cfg(test)]
mod tests {
use alloc::string::String;
use super::*;
static LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
#[test]
fn the_default_permits_a_window() {
let _guard = LOCK.lock().unwrap_or_else(|e| e.into_inner());
allow_windows();
assert!(!windows_forbidden());
assert_windows_allowed("a backend");
}
#[test]
fn a_forbidden_process_panics_naming_the_backend() {
let _guard = LOCK.lock().unwrap_or_else(|e| e.into_inner());
forbid_windows();
assert!(windows_forbidden());
let panicked = std::panic::catch_unwind(|| assert_windows_allowed("TestBackend"));
allow_windows();
let payload = panicked.expect_err("a forbidden window creation panics");
let msg = payload
.downcast_ref::<String>()
.expect("the panic carries its message");
assert!(msg.contains("TestBackend"), "{msg}");
assert!(msg.contains("headless"), "{msg}");
}
}