use { crate::core::View, std::{ sync::{Arc, Weak} }, std::sync::RwLock }; /*\ <<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> Observer <<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> \*/ pub trait Observer : Send + Sync { fn reset(&mut self, _view: Option>) {} fn notify(&self, msg: &V::Msg); } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> impl> Observer for Arc> { fn reset(&mut self, view: Option>) { self.write().unwrap().reset(view); } fn notify(&self, msg: &V::Msg) { self.read().unwrap().notify(&msg); } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub trait ObserverExt : Observer { fn notify_each(&self, it: impl IntoIterator); } impl> ObserverExt for T { fn notify_each(&self, it: impl IntoIterator) { for msg in it { self.notify(&msg); } } } /*\ <<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> Broadcast <<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> \*/ pub struct ObserverBroadcast { observers: Vec>>> } impl ObserverBroadcast { pub fn new() -> Self { ObserverBroadcast { observers: Vec::new() } } pub fn add_observer(&mut self, obs: Weak>>) { self.cleanup(); self.observers.push(obs); } fn cleanup(&mut self) { self.observers.retain(|o| o.strong_count() > 0); } fn iter(&self) -> impl Iterator>>> + '_ { self.observers.iter().filter_map(|o| o.upgrade()) } } impl Observer for ObserverBroadcast { fn reset(&mut self, view: Option>) { for o in self.iter() { o.write().unwrap().reset(view.clone()); } } fn notify(&self, msg: &V::Msg) { for o in self.iter() { o.read().unwrap().notify(&msg); } } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub struct NotifyFnObserver where V: View + ?Sized, F: Fn(&V::Msg) + Send + Sync { f: F, _phantom: std::marker::PhantomData } impl NotifyFnObserver where V: View + ?Sized, F: Fn(&V::Msg) + Send + Sync { pub fn new(f: F) -> Self { NotifyFnObserver { f, _phantom: std::marker::PhantomData } } } impl Observer for NotifyFnObserver where V: View + ?Sized, F: Fn(&V::Msg) + Send + Sync { fn notify(&self, msg: &V::Msg) { (self.f)(msg); } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub struct ResetFnObserver where V: View + ?Sized, F: Fn(Option>) + Send + Sync { f: F, _phantom: std::marker::PhantomData } impl ResetFnObserver where V: View + ?Sized, F: Fn(Option>) + Send + Sync { pub fn new(f: F) -> Self { ResetFnObserver { f, _phantom: std::marker::PhantomData } } } impl Observer for ResetFnObserver where V: View + ?Sized, F: Fn(Option>) + Send + Sync { fn notify(&self, _msg: &V::Msg) {} fn reset(&mut self, view: Option>) { (self.f)(view); } }