use std::sync::Arc;
use std::sync::Mutex;
use std::sync::OnceLock;
pub trait BackgroundActivity: Send + Sync {
fn set_active(&self, active: bool);
}
pub type BackgroundActivityRef = Arc<dyn BackgroundActivity>;
fn slot() -> &'static Mutex<Option<BackgroundActivityRef>> {
static SLOT: OnceLock<Mutex<Option<BackgroundActivityRef>>> = OnceLock::new();
SLOT.get_or_init(|| Mutex::new(None))
}
pub fn set_platform_background_activity(activity: BackgroundActivityRef) {
if let Ok(mut s) = slot().lock() {
*s = Some(activity);
}
}
pub fn clear_platform_background_activity() {
if let Ok(mut s) = slot().lock() {
*s = None;
}
}
pub fn background_activity() -> Option<BackgroundActivityRef> {
slot().lock().ok().and_then(|s| s.clone())
}
pub fn set_background_active(active: bool) {
if let Some(activity) = background_activity() {
activity.set_active(active);
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::atomic::{AtomicBool, Ordering};
#[test]
fn registration_round_trips() {
clear_platform_background_activity();
set_background_active(true); struct Rec(AtomicBool);
impl BackgroundActivity for Rec {
fn set_active(&self, active: bool) {
self.0.store(active, Ordering::SeqCst);
}
}
let rec = Arc::new(Rec(AtomicBool::new(false)));
set_platform_background_activity(rec.clone());
set_background_active(true);
assert!(rec.0.load(Ordering::SeqCst));
clear_platform_background_activity();
}
}