use crate::schema::DesignSystem;
use std::cell::{Cell, RefCell};
use std::sync::Arc;
struct Subscriber {
id: u64,
notify: Arc<dyn Fn() + Send + Sync>,
}
thread_local! {
static CURRENT: Cell<DesignSystem> = const { Cell::new(DesignSystem::Material3) };
static SUBSCRIBERS: RefCell<Vec<Subscriber>> = const { RefCell::new(Vec::new()) };
static NEXT_SUBSCRIBER_ID: Cell<u64> = const { Cell::new(1) };
}
pub fn design_system() -> DesignSystem {
CURRENT.with(Cell::get)
}
pub(crate) fn publish(system: DesignSystem) -> bool {
if CURRENT.with(Cell::get) == system {
return false;
}
CURRENT.with(|current| current.set(system));
SUBSCRIBERS.with_borrow(|subscribers| {
for subscriber in subscribers {
(subscriber.notify)();
}
!subscribers.is_empty()
})
}
#[doc(hidden)]
pub fn reset_design_system() {
CURRENT.with(|current| current.set(DesignSystem::Material3));
SUBSCRIBERS.with_borrow_mut(Vec::clear);
}
pub struct DesignSystemSubscription {
id: u64,
}
pub fn subscribe(notify: Arc<dyn Fn() + Send + Sync>) -> DesignSystemSubscription {
let id = NEXT_SUBSCRIBER_ID.with(|next| {
let id = next.get();
next.set(id + 1);
id
});
SUBSCRIBERS.with_borrow_mut(|subscribers| subscribers.push(Subscriber { id, notify }));
DesignSystemSubscription { id }
}
impl Drop for DesignSystemSubscription {
fn drop(&mut self) {
SUBSCRIBERS.with_borrow_mut(|subscribers| {
subscribers.retain(|subscriber| subscriber.id != self.id);
});
}
}