diff --git a/src/projection/mod.rs b/src/projection/mod.rs index 899ca12..f43f610 100644 --- a/src/projection/mod.rs +++ b/src/projection/mod.rs @@ -3,6 +3,7 @@ pub mod projection_helper; pub mod sgl2idx; pub mod sgl2seq; +pub mod vec2sgl; pub mod vec2seq; pub mod vec2bin; pub mod vec2json; diff --git a/src/projection/vec2sgl.rs b/src/projection/vec2sgl.rs new file mode 100644 index 0000000..1447630 --- /dev/null +++ b/src/projection/vec2sgl.rs @@ -0,0 +1,85 @@ +use { + crate::{ + view::{ + InnerViewPort, Observer, ObserverBroadcast, ObserverExt, OuterViewPort, View, ViewPort, + sequence::SequenceView, + singleton::SingletonView + }, + buffer::vec::VecDiff, + }, + std::sync::Arc, + std::sync::RwLock, +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +/// Adapter View implementing `Singleton` for `Vec` +pub struct VecSingleton<T> +where + T: Clone + Send + Sync + 'static, +{ + data: Option<Arc<RwLock<Vec<T>>>>, + cast: Arc<RwLock<ObserverBroadcast<dyn SingletonView<Item = Vec<T>>>>>, +} + +impl<T> VecSingleton<T> +where + T: Clone + Send + Sync + 'static, +{ + pub fn new(port: InnerViewPort<dyn SingletonView<Item = Vec<T>>>) -> Arc<RwLock<Self>> { + let sgl = Arc::new(RwLock::new(VecSingleton { + data: None, + cast: port.get_broadcast(), + })); + port.set_view(Some(sgl.clone())); + sgl + } +} + +impl<T> Observer<RwLock<Vec<T>>> for VecSingleton<T> +where + T: Clone + Send + Sync + 'static, +{ + fn reset(&mut self, view: Option<Arc<RwLock<Vec<T>>>>) { + self.data = view; + self.cast.notify(&()); + } + + fn notify(&mut self, _diff: &VecDiff<T>) { + self.cast.notify(&()); + } +} + +impl<T> View for VecSingleton<T> +where + T: Clone + Send + Sync + 'static, +{ + type Msg = (); +} + +impl<T> SingletonView for VecSingleton<T> +where + T: Clone + Send + Sync + 'static, +{ + type Item = Vec<T>; + + fn get(&self) -> Vec<T> { + self.data.as_ref().unwrap().read().unwrap().clone() + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl<T> OuterViewPort<RwLock<Vec<T>>> +where + T: Clone + Send + Sync + 'static, +{ + pub fn to_singleton(&self) -> OuterViewPort<dyn SingletonView<Item = Vec<T>>> { + let port = ViewPort::new(); + port.add_update_hook(Arc::new(self.0.clone())); + + let vec_sgl = VecSingleton::new(port.inner()); + self.add_observer(vec_sgl.clone()); + port.into_outer() + } +}