use super::MenuAction;
use std::sync::Mutex;
use std::sync::atomic::{AtomicBool, Ordering};
static PENDING: Mutex<Vec<MenuAction>> = Mutex::new(Vec::new());
static TOGGLE_REQUEST: AtomicBool = AtomicBool::new(false);
pub fn dispatch(action: MenuAction) {
match PENDING.lock() {
Ok(mut pending) => pending.push(action),
Err(poisoned) => poisoned.into_inner().push(action),
}
}
pub fn drain_pending_actions() -> Vec<MenuAction> {
match PENDING.lock() {
Ok(mut pending) => std::mem::take(&mut *pending),
Err(poisoned) => std::mem::take(&mut *poisoned.into_inner()),
}
}
pub fn request_toggle() {
TOGGLE_REQUEST.store(true, Ordering::Relaxed);
}
pub fn take_toggle_request() -> bool {
TOGGLE_REQUEST.swap(false, Ordering::Relaxed)
}
#[cfg(test)]
pub(super) static TEST_LOCK: Mutex<()> = Mutex::new(());
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn queue_and_toggle_round_trip() {
let _guard = TEST_LOCK.lock();
let _ = drain_pending_actions();
let _ = take_toggle_request();
assert!(drain_pending_actions().is_empty());
dispatch(MenuAction::Quit);
dispatch(MenuAction::NewWindow);
assert_eq!(
drain_pending_actions(),
vec![MenuAction::Quit, MenuAction::NewWindow]
);
assert!(drain_pending_actions().is_empty());
assert!(!take_toggle_request());
request_toggle();
assert!(take_toggle_request());
assert!(!take_toggle_request());
}
}