From a9550600f41c0247015c363e8ad33abb72d5417b Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sat, 7 Jan 2023 04:30:16 +0100 Subject: [PATCH] singleton: add flatten() & to_sequence() --- nested/src/core/port.rs | 8 +++ nested/src/singleton/flatten.rs | 88 +++++++++++++++++++++++++++++ nested/src/singleton/mod.rs | 3 +- nested/src/singleton/to_sequence.rs | 77 +++++++++++++++++++++++++ 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 nested/src/singleton/flatten.rs create mode 100644 nested/src/singleton/to_sequence.rs diff --git a/nested/src/core/port.rs b/nested/src/core/port.rs index b20ec50..b148e04 100644 --- a/nested/src/core/port.rs +++ b/nested/src/core/port.rs @@ -221,6 +221,14 @@ where } } +impl Default for OuterViewPort +where V::Msg: Clone +{ + fn default() -> Self { + ViewPort::new().into_outer() + } +} + /* impl OuterViewPort where V::Msg: Clone { diff --git a/nested/src/singleton/flatten.rs b/nested/src/singleton/flatten.rs new file mode 100644 index 0000000..f536416 --- /dev/null +++ b/nested/src/singleton/flatten.rs @@ -0,0 +1,88 @@ +use { + crate::{ + core::{ + port::UpdateTask, InnerViewPort, Observer, ObserverBroadcast, ObserverExt, + OuterViewPort, View, ViewPort, + }, + projection::ProjectionHelper, + singleton::SingletonView, + }, + std::sync::RwLock, + std::{collections::BTreeMap, sync::Arc}, +}; + +impl OuterViewPort>>> +where + Item: 'static + Default, +{ + pub fn flatten(&self) -> OuterViewPort> { + let port = ViewPort::new(); + Flatten::new(self.clone(), port.inner()); + port.into_outer() + } +} + +pub struct Flatten +where + Item: 'static + Default, +{ + outer: Arc>>>, + inner: OuterViewPort>, + cast: Arc>>>, + proj: ProjectionHelper +} + +impl View for Flatten +where + Item: 'static + Default, +{ + type Msg = (); +} + +impl SingletonView for Flatten +where + Item: 'static + Default, +{ + type Item = Item; + + fn get(&self) -> Self::Item { + if let Some(i) = self.inner.get_view() { + i.get() + } else { + Item::default() + } + } +} + +impl Flatten +where + Item: 'static + Default, +{ + pub fn new( + top_port: OuterViewPort< + dyn SingletonView>>, + >, + out_port: InnerViewPort>, + ) -> Arc> { + let mut proj = ProjectionHelper::new(out_port.0.update_hooks.clone()); + + let flat = Arc::new(RwLock::new(Flatten { + outer: proj.new_singleton_arg(0, top_port, |s: &mut Self, _msg| { + s.inner = s.outer.get(); + s.proj.new_singleton_arg(1, s.inner.clone(), |s: &mut Self, _msg| { + s.cast.notify(&()); + }); + //s.inner.0.update(); + }), + inner: OuterViewPort::default(), + cast: out_port.get_broadcast(), + proj, + })); + + flat.write().unwrap().proj.set_proj(&flat); + out_port.set_view(Some(flat.clone())); + flat + } +} + + diff --git a/nested/src/singleton/mod.rs b/nested/src/singleton/mod.rs index 0008f4f..c0b9292 100644 --- a/nested/src/singleton/mod.rs +++ b/nested/src/singleton/mod.rs @@ -1,7 +1,8 @@ pub mod buffer; pub mod map; +pub mod flatten; pub mod to_index; -//pub mod unwrap; +pub mod to_sequence; use { crate::core::View, diff --git a/nested/src/singleton/to_sequence.rs b/nested/src/singleton/to_sequence.rs new file mode 100644 index 0000000..c69c038 --- /dev/null +++ b/nested/src/singleton/to_sequence.rs @@ -0,0 +1,77 @@ +use { + crate::{ + core::{Observer, ObserverBroadcast, OuterViewPort, View, ViewPort}, + sequence::{SequenceView}, + singleton::SingletonView, + }, + std::sync::Arc, + std::sync::RwLock, +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl OuterViewPort> { + pub fn to_sequence(&self) -> OuterViewPort> { + let port = ViewPort::new(); + port.add_update_hook(Arc::new(self.0.clone())); + + let map = Arc::new(RwLock::new(Singleton2Sequence { + src_view: None, + cast: port.inner().get_broadcast(), + })); + + self.add_observer(map.clone()); + port.inner().set_view(Some(map)); + port.into_outer() + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +pub struct Singleton2Sequence +where + SrcView: SingletonView + ?Sized, +{ + src_view: Option>, + cast: Arc>>>, +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl View for Singleton2Sequence +where + SrcView: SingletonView + ?Sized, +{ + type Msg = usize; +} + +impl SequenceView for Singleton2Sequence +where + SrcView: SingletonView + ?Sized, +{ + type Item = SrcView::Item; + + fn get(&self, _idx: &usize) -> Option { + Some(self.src_view.as_ref().unwrap().get()) + } + + fn len(&self) -> Option { + Some(1) + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl Observer for Singleton2Sequence +where + SrcView: SingletonView + ?Sized, +{ + fn reset(&mut self, view: Option>) { + self.src_view = view; + self.cast.notify(&0); + } + + fn notify(&mut self, _: &()) { + self.cast.notify(&0); + } +}