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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
#![no_std] extern crate alloc; use alloc::boxed::Box; use alloc::sync::Arc; use alloc::vec::Vec; pub use spin::Mutex; pub struct State<S> { state:Arc<Mutex<S>> } impl<S> State<S> { pub fn new(s:S) -> Self{ State { state:Arc::new(Mutex::new(s)) } } pub fn lock(&self) -> spin::MutexGuard<S> { self.state.lock() } } impl<T> Clone for State<T> { fn clone(&self) -> Self { Self { state:self.state.clone() } } } pub struct Store<T, A> where T: Default + Reduceable<A> + Sync + Send, A: Sync + Send, { pub state: State<T>, watchers: Arc<Mutex<Vec<Box<dyn Fn(State<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 dispatch(&mut self, a: &A) -> State<T> { let s = T::reduce(self.state.clone(), a); self.state = s.clone(); for w in self.watchers.lock().iter() { w(self.state.clone()) } s } pub fn watch<F>(&mut self, watcher: F) where F: 'static + Fn(State<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: State::new(T::default()), watchers: Arc::new(Mutex::new(Vec::new())), phantom: core::marker::PhantomData, } } } pub trait Reduceable<A> where A: Sync + Send,Self:Sized { fn reduce(state: State<Self>, action: &A) -> State<Self>; }