use { r3vi::{ view::{ ViewPort, OuterViewPort, AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, port::UpdateTask, View, Observer, singleton::*, sequence::*, list::* }, buffer::{singleton::*, vec::*} }, laddertypes::{TypeTerm}, std::{ collections::HashMap, sync::{Arc, RwLock}, any::Any }, }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> #[derive(Clone)] pub struct ReprLeaf { out_port: AnyViewPort, in_port: AnyInnerViewPort, data: Option< Arc<dyn Any + Send + Sync> >, /// keepalive for the observer that updates the buffer from in_port keepalive: Option<Arc<dyn Any + Send + Sync>>, in_keepalive: Option<Arc<dyn Any + Send + Sync>>, } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> impl ReprLeaf { pub fn from_view<V>( src_port: OuterViewPort<V> ) -> Self where V: View + ?Sized + 'static, V::Msg: Clone { let mut in_port = ViewPort::<V>::new(); let in_keepalive = in_port.attach_to(src_port); let mut out_port = ViewPort::<V>::new(); let out_keepalive = out_port.attach_to(in_port.outer()); ReprLeaf { keepalive: Some(out_keepalive), in_keepalive: Some(in_keepalive), in_port: in_port.inner().into(), out_port: out_port.into(), data: None, } } pub fn detach<V>(&mut self) where V: View + ?Sized + 'static, V::Msg: Clone { self.keepalive = None; self.in_keepalive = None; let ip = self.in_port.clone() .downcast::<V>().ok() .unwrap(); ip.0.detach(); if self.data.is_none() { let mut op = self.out_port.clone() .downcast::<V>().ok() .unwrap(); op.detach(); self.keepalive = Some(op.attach_to(ip.0.outer())); } } pub fn detach_vec<Item>(&mut self) where Item: Clone + Send + Sync + 'static { self.keepalive = None; self.in_keepalive = None; let ip = self.in_port.clone() .downcast::<dyn ListView<Item>>().ok() .unwrap(); ip.0.detach(); if let Some(data) = self.data.as_mut() { let mut op = self.out_port.clone() .downcast::<RwLock<Vec<Item>>>().ok() .unwrap(); op.detach(); let data = data.clone().downcast::< RwLock<Vec<Item>> >().ok().unwrap(); let buffer = VecBuffer::with_data_arc_port(data, op.inner()); self.keepalive = Some(buffer.attach_to(ip.0.outer())) } } pub fn attach_to<V>(&mut self, src_port: OuterViewPort<V>) where V: View + ?Sized + 'static, V::Msg: Clone { self.in_keepalive = Some(self.in_port.clone() .downcast::<V>().ok().unwrap() .0.attach_to( src_port )); } pub fn from_singleton_buffer<T>( buffer: SingletonBuffer<T> ) -> Self where T: Clone + Send + Sync + 'static { let in_port = ViewPort::<dyn SingletonView<Item = T>>::new(); ReprLeaf { in_keepalive: None, keepalive: Some(buffer.attach_to(in_port.outer())), in_port: in_port.inner().into(), out_port: buffer.get_port().0.into(), data: Some(buffer.into_inner()) } } pub fn from_vec_buffer<T>( buffer: VecBuffer<T> ) -> Self where T: Clone + Send + Sync + 'static { let in_port = ViewPort::< dyn ListView<T> >::new(); ReprLeaf { in_keepalive: None, keepalive: Some(buffer.attach_to(in_port.outer())), in_port: in_port.inner().into(), out_port: buffer.get_port().0.into(), data: Some(buffer.into_inner()) } } pub fn as_singleton_buffer<T>(&mut self) -> Option<SingletonBuffer<T>> where T: Clone + Send + Sync + 'static { let sgl_port = self.get_port::< dyn SingletonView<Item = T> >().unwrap().0; let data_arc = if let Some(data) = self.data.as_ref() { data.clone().downcast::<RwLock<T>>().ok() } else { sgl_port.update(); let value = sgl_port.outer().get_view().unwrap().get(); eprintln!("make new data ARC from old value"); Some(Arc::new(RwLock::new( value ))) }; if let Some(data_arc) = data_arc { self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>); let buf = SingletonBuffer { value: data_arc, port: sgl_port.inner() }; self.keepalive = Some(buf.attach_to( self.in_port.0.clone() .downcast::<dyn SingletonView<Item = T>>() .ok().unwrap() .outer() )); Some(buf) } else { None } } pub fn as_vec_buffer<T>(&mut self) -> Option<VecBuffer<T>> where T: Clone + Send + Sync + 'static { let vec_port = self.get_port::< RwLock<Vec<T>> >().unwrap().0; let data_arc = if let Some(data) = self.data.as_ref() { data.clone().downcast::<RwLock<Vec<T>>>().ok() } else { vec_port.update(); if let Some(value) = vec_port.outer().get_view() { let value = value.read().unwrap().clone(); eprintln!("make new data ARC from old VECTOR-value"); Some(Arc::new(RwLock::new( value ))) } else { eprintln!("no data vec"); Some(Arc::new(RwLock::new( Vec::new() ))) // None } }; if let Some(data_arc) = data_arc { self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>); let buf = VecBuffer::with_data_arc_port(data_arc, vec_port.inner()); self.keepalive = Some(buf.attach_to( self.in_port.0.clone() .downcast::< dyn ListView<T> >() .ok().unwrap() .outer() )); Some(buf) } else { None } } pub fn get_port<V>(&self) -> Option<OuterViewPort<V>> where V: View + ?Sized + 'static, V::Msg: Clone { self.out_port.clone().downcast::<V>().ok().map(|p| p.outer()) } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>