add vec-access to ReprTree and morphism to collect <List Char> to <Vec Char>

This commit is contained in:
Michael Sippel 2024-03-23 20:57:07 +01:00
parent 473dd5f4dc
commit edf088b853
Signed by: senvas
GPG key ID: F96CF119C34B64A6
3 changed files with 145 additions and 13 deletions

View file

@ -41,13 +41,12 @@ async fn main() {
nested::editors::list::init_ctx( ctx.clone() ); nested::editors::list::init_ctx( ctx.clone() );
nested_tty::setup_edittree_hook(&ctx); nested_tty::setup_edittree_hook(&ctx);
/* Create a Representation-Tree of type <List Char> /* Create a Representation-Tree of type <List Char>
*/ */
let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") ); let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") );
/* Setup an Editor for this ReprTree /* Setup an Editor for this ReprTree
* (by adding the representation <List Char>~EditTree to the ReprTree) * (this will add the representation <List Char>~EditTree to the ReprTree)
*/ */
let edittree_list = ctx.read().unwrap() let edittree_list = ctx.read().unwrap()
.setup_edittree( .setup_edittree(
@ -72,7 +71,24 @@ async fn main() {
.get_port::<dyn ListView<char>>() .get_port::<dyn ListView<char>>()
.unwrap(); .unwrap();
/* transform ListView<char> into a TerminalView
/* Lets add another morphism which will store the values
* of the character-list in a `Vec<char>`
*/
ctx.read().unwrap().morphisms.apply_morphism(
rt_string.clone(),
&Context::parse(&ctx, "<List Char>"),
&Context::parse(&ctx, "<List Char>~<Vec Char>")
);
/* Access the Vec<char> object (wrapped behind a VecBuffer<char>)
* from the ReprTree.
*/
let chars_vec = rt_string
.descend(Context::parse(&ctx, "<Vec Char>")).unwrap()
.vec_buffer::<char>();
/* transform `ListView<char>` into a `TerminalView`
*/ */
let string_view_tty = chars_view let string_view_tty = chars_view
.to_sequence() .to_sequence()
@ -122,4 +138,16 @@ async fn main() {
/* write the changes in the view of `term_port` to the terminal /* write the changes in the view of `term_port` to the terminal
*/ */
app.show().await.expect("output error!"); app.show().await.expect("output error!");
/* need to call update because changes are applied lazily
*/
chars_vec.get_port().0.update();
/* Vec<char> to String
*/
let string = chars_vec.data
.read().unwrap()
.iter().collect::<String>();
eprintln!("value of the editor was: {}\n\n", string);
} }

View file

@ -2,7 +2,9 @@ use {
r3vi::{ r3vi::{
view::{ view::{
ViewPort, ViewPort,
OuterViewPort, Observer, singleton::* OuterViewPort, Observer,
singleton::*,
list::*
}, },
buffer::{singleton::*, vec::*} buffer::{singleton::*, vec::*}
}, },
@ -89,5 +91,30 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
} }
} }
); );
let mt = crate::repr_tree::MorphismType {
src_type: Context::parse(&ctx, "<List Char>"),
dst_type: Context::parse(&ctx, "<List Char>~<Vec Char>")
};
ctx.write().unwrap().morphisms.add_morphism(
mt,
{
let ctx = ctx.clone();
move |src_rt, σ| {
let buf = VecBuffer::<char>::new();
let mut leaf = ReprLeaf::from_vec_buffer(buf);
leaf.attach_to(
src_rt.read().unwrap()
.get_port::<dyn ListView<char>>()
.unwrap()
);
src_rt.write().unwrap().insert_leaf(
vec![ Context::parse(&ctx, "<Vec Char>") ].into_iter(),
leaf
);
}
}
);
} }

View file

@ -16,7 +16,9 @@ use {
AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, AnyViewPort, AnyInnerViewPort, AnyOuterViewPort,
port::UpdateTask, port::UpdateTask,
View, View,
singleton::*, sequence::* singleton::*,
sequence::*,
list::*
}, },
buffer::{singleton::*, vec::*} buffer::{singleton::*, vec::*}
}, },
@ -103,6 +105,19 @@ impl ReprLeaf {
} }
} }
pub fn from_vec_buffer<T>( buffer: VecBuffer<T> ) -> Self
where T: Clone + Send + Sync + 'static
{
eprintln!("ReprLeaf from vec buffer (LEN ={})", buffer.len());
let in_port = ViewPort::< dyn ListView<T> >::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<T>(&mut self) -> Option<SingletonBuffer<T>> pub fn as_singleton_buffer<T>(&mut self) -> Option<SingletonBuffer<T>>
where T: Clone + Send + Sync + 'static where T: Clone + Send + Sync + 'static
{ {
@ -136,6 +151,50 @@ impl ReprLeaf {
} }
} }
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() {
eprintln!("downcast existing vec-data");
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 {
eprintln!("ReprLeaf: have Vec-like data-arc");
eprintln!("LEN = {}", data_arc.read().unwrap().len());
self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>);
let buf = VecBuffer {
data: data_arc,
port: 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>> pub fn get_port<V>(&self) -> Option<OuterViewPort<V>>
where V: View + ?Sized + 'static, where V: View + ?Sized + 'static,
V::Msg: Clone V::Msg: Clone
@ -191,6 +250,15 @@ impl ReprTree {
Arc::new(RwLock::new(rt)) Arc::new(RwLock::new(rt))
} }
pub fn from_vec_buffer<T>( type_tag: impl Into<TypeTerm>, buf: VecBuffer<T> ) -> Arc<RwLock<Self>>
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. /// find, and if necessary, create corresponding path in repr-tree.
/// Attach src_port to input of that node /// Attach src_port to input of that node
pub fn attach_leaf_to<V>( pub fn attach_leaf_to<V>(
@ -271,14 +339,24 @@ impl ReprTree {
if let Some(leaf) = self.leaf.as_mut() { if let Some(leaf) = self.leaf.as_mut() {
leaf.as_singleton_buffer::<T>() leaf.as_singleton_buffer::<T>()
} else { } else {
// create new singleton buffer
/*
// default value??
let buf = SingletonBuffer::<T>::default();
self.leaf = Some(ReprLeaf::from_singleton_buffer(buf.clone()));
Some(buf)
*/
None None
} }
} }
/* pub fn vec_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<VecBuffer<T>> {
pub fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> Option<VecBuffer<T>> { if let Some(leaf) = self.leaf.as_mut() {
leaf.as_vec_buffer::<T>()
} else {
None
}
} }
*/
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
@ -336,7 +414,7 @@ pub trait ReprTreeExt {
fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>; fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>;
fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T>; fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T>;
// fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>; fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>;
} }
impl ReprTreeExt for Arc<RwLock<ReprTree>> { impl ReprTreeExt for Arc<RwLock<ReprTree>> {
@ -371,11 +449,10 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T> { fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T> {
self.write().unwrap().singleton_buffer::<T>().expect("") self.write().unwrap().singleton_buffer::<T>().expect("")
} }
/*
fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T> { fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T> {
self.read().unwrap().vec_buffer::<T>().expect("") self.write().unwrap().vec_buffer::<T>().expect("")
} }
*/
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>