use crate::config::Config; use crate::models::almanac::Almanac; use crate::models::global::Global; use crate::models::helper::{Callbacks, CallbackRegistration, ModelBase}; use crate::models::observers::Observers; use std::cell::Cell; use std::rc::Rc; #[derive(Debug)] struct Watch { almanac: Almanac, almanac_waiting: Cell, global: Global, global_waiting: Cell, observers: Observers, observers_waiting: Cell, callbacks: Callbacks, } impl Watch { fn on_almanac_update(&self) { self.almanac_waiting.set(false); self.on_generic_update(); } fn on_global_update(&self) { self.global_waiting.set(false); self.on_generic_update(); } fn on_observers_update(&self) { self.observers_waiting.set(false); self.on_generic_update(); } fn on_generic_update(&self) { if !self.almanac_waiting.get() && !self.global_waiting.get() && !self.observers_waiting.get() { self.callbacks.emit(); } } } #[derive(Debug)] pub struct Inner { watch: Rc, _almanac_cbr: CallbackRegistration, _global_cbr: CallbackRegistration, _observers_cbr: CallbackRegistration, } /// All basic data #[derive(Clone, Debug)] pub struct Base(Rc); impl Base { pub fn new(config: Config) -> Self { let base = ModelBase::from(()); let watch = Rc::new(Watch { almanac: Almanac::new_shared(config.clone(), base.clone()), almanac_waiting: Cell::new(true), global: Global::new_shared(config.clone(), base.clone()), global_waiting: Cell::new(true), observers: Observers::new_shared(config, base), observers_waiting: Cell::new(true), callbacks: Callbacks::new(), }); let _almanac_cbr = watch.almanac.register(yew::Callback::from({ let watch = watch.clone(); move |()| watch.on_almanac_update() })); let _global_cbr = watch.global.register(yew::Callback::from({ let watch = watch.clone(); move |()| watch.on_global_update() })); let _observers_cbr = watch.observers.register(yew::Callback::from({ let watch = watch.clone(); move |()| watch.on_observers_update() })); let inner = Rc::new(Inner { watch, _almanac_cbr, _global_cbr, _observers_cbr, }); Self(inner) } pub fn register(&self, callback: yew::Callback<()>) -> CallbackRegistration { self.0.watch.callbacks.register(callback) } pub fn refresh(&self) { self.0.watch.almanac_waiting.set(true); self.0.watch.global_waiting.set(true); self.0.watch.observers_waiting.set(true); self.0.watch.almanac.refresh(); self.0.watch.global.refresh(); self.0.watch.observers.refresh(); } pub fn is_pending(&self) -> bool { self.0.watch.almanac.is_pending() || self.0.watch.global.is_pending() || self.0.watch.observers.is_pending() } pub fn almanac(&self) -> &Almanac { &self.0.watch.almanac } pub fn global(&self) -> &Global { &self.0.watch.global } pub fn observers(&self) -> &Observers { &self.0.watch.observers } }