diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs index d0ad31a..0d8f670 100644 --- a/examples/tty-03-string/src/main.rs +++ b/examples/tty-03-string/src/main.rs @@ -41,13 +41,12 @@ async fn main() { nested::editors::list::init_ctx( ctx.clone() ); nested_tty::setup_edittree_hook(&ctx); - /* Create a Representation-Tree of type */ let rt_string = ReprTree::new_arc( Context::parse(&ctx, "") ); /* Setup an Editor for this ReprTree - * (by adding the representation ~EditTree to the ReprTree) + * (this will add the representation ~EditTree to the ReprTree) */ let edittree_list = ctx.read().unwrap() .setup_edittree( @@ -72,7 +71,24 @@ async fn main() { .get_port::>() .unwrap(); - /* transform ListView into a TerminalView + + /* Lets add another morphism which will store the values + * of the character-list in a `Vec` + */ + ctx.read().unwrap().morphisms.apply_morphism( + rt_string.clone(), + &Context::parse(&ctx, ""), + &Context::parse(&ctx, "~") + ); + + /* Access the Vec object (wrapped behind a VecBuffer) + * from the ReprTree. + */ + let chars_vec = rt_string + .descend(Context::parse(&ctx, "")).unwrap() + .vec_buffer::(); + + /* transform `ListView` into a `TerminalView` */ let string_view_tty = chars_view .to_sequence() @@ -122,4 +138,16 @@ async fn main() { /* write the changes in the view of `term_port` to the terminal */ app.show().await.expect("output error!"); + + /* need to call update because changes are applied lazily + */ + chars_vec.get_port().0.update(); + + /* Vec to String + */ + let string = chars_vec.data + .read().unwrap() + .iter().collect::(); + + eprintln!("value of the editor was: {}\n\n", string); } diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 0f97c3c..79943db 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -2,7 +2,9 @@ use { r3vi::{ view::{ ViewPort, - OuterViewPort, Observer, singleton::* + OuterViewPort, Observer, + singleton::*, + list::* }, buffer::{singleton::*, vec::*} }, @@ -89,5 +91,30 @@ pub fn init_ctx(ctx: Arc>) { } } ); + + + let mt = crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, ""), + dst_type: Context::parse(&ctx, "~") + }; + ctx.write().unwrap().morphisms.add_morphism( + mt, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let buf = VecBuffer::::new(); + let mut leaf = ReprLeaf::from_vec_buffer(buf); + leaf.attach_to( + src_rt.read().unwrap() + .get_port::>() + .unwrap() + ); + src_rt.write().unwrap().insert_leaf( + vec![ Context::parse(&ctx, "") ].into_iter(), + leaf + ); + } + } + ); } diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 816f6b7..3b58eb8 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -16,7 +16,9 @@ use { AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, port::UpdateTask, View, - singleton::*, sequence::* + singleton::*, + sequence::*, + list::* }, buffer::{singleton::*, vec::*} }, @@ -35,7 +37,7 @@ pub struct ReprLeaf { out_port: AnyViewPort, in_port: AnyInnerViewPort, data: Option< Arc >, - + /// keepalive for the observer that updates the buffer from in_port keepalive: Option>, } @@ -103,6 +105,19 @@ impl ReprLeaf { } } + pub fn from_vec_buffer( buffer: VecBuffer ) -> Self + where T: Clone + Send + Sync + 'static + { + eprintln!("ReprLeaf from vec buffer (LEN ={})", buffer.len()); + let in_port = ViewPort::< dyn ListView >::new(); + ReprLeaf { + 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(&mut self) -> Option> where T: Clone + Send + Sync + 'static { @@ -136,6 +151,50 @@ impl ReprLeaf { } } + pub fn as_vec_buffer(&mut self) -> Option> + where T: Clone + Send + Sync + 'static + { + let vec_port = self.get_port::< RwLock> >().unwrap().0; + + let data_arc = + if let Some(data) = self.data.as_ref() { + eprintln!("downcast existing vec-data"); + data.clone().downcast::>>().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 { + eprintln!("ReprLeaf: have Vec-like data-arc"); + eprintln!("LEN = {}", data_arc.read().unwrap().len()); + + self.data = Some(data_arc.clone() as Arc); + let buf = VecBuffer { + data: data_arc, + port: vec_port.inner() + }; + self.keepalive = Some(buf.attach_to( + self.in_port.0.clone() + .downcast::< dyn ListView >() + .ok().unwrap() + .outer() + )); + Some(buf) + } else { + None + } + } + + pub fn get_port(&self) -> Option> where V: View + ?Sized + 'static, V::Msg: Clone @@ -191,6 +250,15 @@ impl ReprTree { Arc::new(RwLock::new(rt)) } + + pub fn from_vec_buffer( type_tag: impl Into, buf: VecBuffer ) -> Arc> + where T: Clone + Send + Sync + 'static + { + let mut rt = ReprTree::new(type_tag); + rt.leaf = Some(ReprLeaf::from_vec_buffer(buf)); + Arc::new(RwLock::new(rt)) + } + /// find, and if necessary, create corresponding path in repr-tree. /// Attach src_port to input of that node pub fn attach_leaf_to( @@ -271,14 +339,24 @@ impl ReprTree { if let Some(leaf) = self.leaf.as_mut() { leaf.as_singleton_buffer::() } else { + // create new singleton buffer + /* + // default value?? + let buf = SingletonBuffer::::default(); + self.leaf = Some(ReprLeaf::from_singleton_buffer(buf.clone())); + Some(buf) + */ None } } -/* - pub fn vec_buffer(&self) -> Option> { + pub fn vec_buffer(&mut self) -> Option> { + if let Some(leaf) = self.leaf.as_mut() { + leaf.as_vec_buffer::() + } else { + None + } } -*/ //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -336,7 +414,7 @@ pub trait ReprTreeExt { fn view_u64(&self) -> OuterViewPort>; fn singleton_buffer(&self) -> SingletonBuffer; -// fn vec_buffer(&self) -> VecBuffer; + fn vec_buffer(&self) -> VecBuffer; } impl ReprTreeExt for Arc> { @@ -371,11 +449,10 @@ impl ReprTreeExt for Arc> { fn singleton_buffer(&self) -> SingletonBuffer { self.write().unwrap().singleton_buffer::().expect("") } -/* + fn vec_buffer(&self) -> VecBuffer { - self.read().unwrap().vec_buffer::().expect("") + self.write().unwrap().vec_buffer::().expect("") } - */ } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>