1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
use std::sync::Arc; pub use spin::Mutex; pub struct Store<T,A> where T:Default+Reduceable<A>+Sync+Send,A:Sync+Send{ pub state:Arc<Mutex<T>>, watchers:Arc<Mutex<Vec<Box<dyn Fn(Arc<Mutex<T>>)->()+Sync+Send>>>>, phantom: std::marker::PhantomData<A> } impl<T,A> Store<T,A> where T:Default+Reduceable<A>+Sync+Send,A:Sync+Send{ pub fn get() -> &'static Mutex<Self>{ globals::get() } pub fn reduce(&self,a:&A) -> Arc<Mutex<T>>{ let s = T::reduce(self.state.clone(),a); for w in self.watchers.lock().iter() { w(s.clone()) } s } pub fn watch<F>(&mut self, watcher:F) where F:'static+Fn(Arc<Mutex<T>>)->()+Sync+Send{ self.watchers.lock().push(Box::new(watcher)) } } impl<T,A> Default for Store<T,A> where T:Default+Reduceable<A>+Sync+Send,A:Sync+Send{ fn default() -> Self { Store::<T,A>{ state:Arc::new(Mutex::new(T::default())), watchers: Arc::new(Mutex::new(Vec::new())), phantom: std::marker::PhantomData } } } pub trait Reduceable<A> where A:Sync+Send { fn reduce(state:Arc<Mutex<Self>>,action:&A) -> Arc<Mutex<Self>>; }