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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
#![no_std] extern crate alloc; use alloc::boxed::Box; use alloc::sync::Arc; use alloc::vec::Vec; 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: core::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: core::marker::PhantomData, } } } pub trait Reduceable<A> where A: Sync + Send, { fn reduce(state: Arc<Mutex<Self>>, action: &A) -> Arc<Mutex<Self>>; }