rust-galmon-web/src/models/base.rs

123 lines
2.8 KiB
Rust
Raw Normal View History

2019-09-28 10:16:55 +00:00
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<bool>,
global: Global,
global_waiting: Cell<bool>,
observers: Observers,
observers_waiting: Cell<bool>,
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<Watch>,
_almanac_cbr: CallbackRegistration,
_global_cbr: CallbackRegistration,
_observers_cbr: CallbackRegistration,
}
/// All basic data
#[derive(Clone, Debug)]
pub struct Base(Rc<Inner>);
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
}
}