use super::Observer;
pub struct Observable<S> {
state: S,
observers: Vec<Observer<S>>,
}
impl<S> Observable<S>
where
S: Clone,
{
pub fn new(initial_state: S) -> Self {
Observable {
state: initial_state,
observers: vec![],
}
}
pub fn get_state(&self) -> &S {
&self.state
}
pub fn set_state(&mut self, new_state: S) -> () {
self.state = new_state;
self.emit();
}
pub fn update<F>(&mut self, updater: F) -> ()
where
F: Fn(&mut S),
{
updater(&mut self.state);
self.emit();
}
pub fn subscribe<F>(&mut self, subscriber: F) -> usize
where
F: 'static + FnMut(&S),
{
self.observers
.push(Observer::new(self.observers.len(), Box::new(subscriber)));
self.observers.len() - 1
}
pub fn unsubscribe(&mut self, id: usize) -> () {
self.observers.retain(|observer| observer.id != id);
}
fn emit(&mut self) -> () {
for observer in &mut self.observers {
(observer.callback)(&self.state);
}
}
}