singleton: add flatten() & to_sequence()

This commit is contained in:
Michael Sippel 2023-01-07 04:30:16 +01:00
parent 0edbd748a5
commit a9550600f4
Signed by: senvas
GPG key ID: F96CF119C34B64A6
4 changed files with 175 additions and 1 deletions

View file

@ -221,6 +221,14 @@ where
}
}
impl<V: View + ?Sized> Default for OuterViewPort<V>
where V::Msg: Clone
{
fn default() -> Self {
ViewPort::new().into_outer()
}
}
/*
impl<V: View + ?Sized + 'static> OuterViewPort<V>
where V::Msg: Clone {

View file

@ -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<Item> OuterViewPort<dyn SingletonView<Item = OuterViewPort<dyn SingletonView<Item = Item>>>>
where
Item: 'static + Default,
{
pub fn flatten(&self) -> OuterViewPort<dyn SingletonView<Item = Item>> {
let port = ViewPort::new();
Flatten::new(self.clone(), port.inner());
port.into_outer()
}
}
pub struct Flatten<Item>
where
Item: 'static + Default,
{
outer: Arc<dyn SingletonView<Item = OuterViewPort<dyn SingletonView<Item = Item>>>>,
inner: OuterViewPort<dyn SingletonView<Item = Item>>,
cast: Arc<RwLock<ObserverBroadcast<dyn SingletonView<Item = Item>>>>,
proj: ProjectionHelper<usize, Self>
}
impl<Item> View for Flatten<Item>
where
Item: 'static + Default,
{
type Msg = ();
}
impl<Item> SingletonView for Flatten<Item>
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<Item> Flatten<Item>
where
Item: 'static + Default,
{
pub fn new(
top_port: OuterViewPort<
dyn SingletonView<Item = OuterViewPort<dyn SingletonView<Item = Item>>>,
>,
out_port: InnerViewPort<dyn SingletonView<Item = Item>>,
) -> Arc<RwLock<Self>> {
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
}
}

View file

@ -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,

View file

@ -0,0 +1,77 @@
use {
crate::{
core::{Observer, ObserverBroadcast, OuterViewPort, View, ViewPort},
sequence::{SequenceView},
singleton::SingletonView,
},
std::sync::Arc,
std::sync::RwLock,
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl<Item: 'static> OuterViewPort<dyn SingletonView<Item = Item>> {
pub fn to_sequence(&self) -> OuterViewPort<dyn SequenceView<Item = Item>> {
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<SrcView>
where
SrcView: SingletonView + ?Sized,
{
src_view: Option<Arc<SrcView>>,
cast: Arc<RwLock<ObserverBroadcast<dyn SequenceView<Item = SrcView::Item>>>>,
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl<SrcView> View for Singleton2Sequence<SrcView>
where
SrcView: SingletonView + ?Sized,
{
type Msg = usize;
}
impl<SrcView> SequenceView for Singleton2Sequence<SrcView>
where
SrcView: SingletonView + ?Sized,
{
type Item = SrcView::Item;
fn get(&self, _idx: &usize) -> Option<Self::Item> {
Some(self.src_view.as_ref().unwrap().get())
}
fn len(&self) -> Option<usize> {
Some(1)
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl<SrcView> Observer<SrcView> for Singleton2Sequence<SrcView>
where
SrcView: SingletonView + ?Sized,
{
fn reset(&mut self, view: Option<Arc<SrcView>>) {
self.src_view = view;
self.cast.notify(&0);
}
fn notify(&mut self, _: &()) {
self.cast.notify(&0);
}
}