use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use super::AppContext;
type Injection = Box<dyn FnOnce(&mut AppContext<'_>) + Send + 'static>;
#[derive(Default)]
pub(super) struct AppShared {
pub(super) redraw_requested: AtomicBool,
pub(super) quit_requested: AtomicBool,
pub(super) inject_queue: Mutex<Vec<Injection>>,
}
impl AppShared {
pub(super) fn new() -> Arc<Self> {
Arc::new(Self::default())
}
pub(super) fn drain_injections(&self) -> Vec<Injection> {
let mut q = self.inject_queue.lock().unwrap_or_else(|e| e.into_inner());
std::mem::take(&mut *q)
}
}
#[derive(Clone)]
pub struct AppHandle {
pub(super) shared: Arc<AppShared>,
}
impl AppHandle {
pub(super) fn from_shared(shared: Arc<AppShared>) -> Self {
Self { shared }
}
pub fn request_redraw(&self) {
self.shared.redraw_requested.store(true, Ordering::Relaxed);
}
pub fn quit(&self) {
self.shared.quit_requested.store(true, Ordering::Relaxed);
}
pub fn inject<F>(&self, f: F)
where
F: FnOnce(&mut AppContext<'_>) + Send + 'static,
{
let mut q = self
.shared
.inject_queue
.lock()
.unwrap_or_else(|e| e.into_inner());
q.push(Box::new(f));
}
}
const _: fn() = || {
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
assert_send::<AppHandle>();
assert_sync::<AppHandle>();
};