diff --git a/examples/tty-02-node/src/main.rs b/examples/tty-02-node/src/main.rs index b44d2bf..7e40c63 100644 --- a/examples/tty-02-node/src/main.rs +++ b/examples/tty-02-node/src/main.rs @@ -8,17 +8,19 @@ use { cgmath::Vector2, nested::{ editors::ObjCommander, - repr_tree::{Context, ReprTree}, + repr_tree::{Context, ReprTree, ReprTreeExt}, edit_tree::{EditTree} }, nested_tty::{ DisplaySegment, TTYApplication, TerminalCompositor, TerminalStyle, TerminalView, - TerminalAtom + TerminalAtom, TerminalEvent }, r3vi::{ buffer::{singleton::*, vec::*}, + view::{port::UpdateTask} }, +// termion::{}, std::sync::{Arc, RwLock}, }; @@ -48,8 +50,8 @@ async fn main() { // It provides the necessary bridge to the rendering- & input-backend. ctx.write().unwrap().set_edittree_hook( Arc::new( - move |et: Arc>, t: laddertypes::TypeTerm| { - let mut et = et.write().unwrap(); + move |et: &mut EditTree, t: laddertypes::TypeTerm| { +// let mut et = et.write().unwrap(); if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) { *et = nested_tty::editors::edittree_make_char_view(et.clone()); @@ -95,31 +97,49 @@ async fn main() { * / | \ * TTY PixelBuf SDF */ - let rt_digit = ReprTree::new_arc( Context::parse(&ctx, "") ); + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "") ); /* add initial representation * ~ Char */ - rt_digit.write().unwrap() - .insert_leaf( - vec![ Context::parse(&ctx, "Char") ].into_iter(), - SingletonBuffer::new('4').get_port().into() - ); + rt_digit.insert_leaf( + Context::parse(&ctx, "Char"), + nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) + ); + + /* furthermore, setup projections to and from u8 value, + * this synchronizes the buffers + */ + ctx.read().unwrap().morphisms.apply_morphism( + rt_digit.clone(), + &Context::parse(&ctx, "~Char"), + &Context::parse(&ctx, "~ℤ_256~machine::UInt8") + ); /* setup TTY-Display for DigitEditor + * + * `setup_edittree` will setup the projection + * Char -> Char~EditTree + * and call the hook defined above with `set_edittree_hook()` + * */ let edittree_digit = ctx.read().unwrap() .setup_edittree( - rt_digit - .read().unwrap() - .descend( Context::parse(&ctx, "Char") ).unwrap() - .clone(), - r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); + rt_digit.clone(), + r3vi::buffer::singleton::SingletonBuffer::new(0).get_port() + ); + + let mut digit_u8_buffer = rt_digit + .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() + .singleton_buffer::(); //--- - let rt_string = ReprTree::new_arc( Context::parse(&ctx, ">") ); - let edittree = ctx.read().unwrap() - .setup_edittree(rt_string.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); + let rt_string = ReprTree::new_arc( Context::parse(&ctx, "") ); + + let edittree_list = ctx.read().unwrap() + .setup_edittree( + rt_string.clone(), + r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()); /* setup terminal */ @@ -127,9 +147,22 @@ async fn main() { /* event handler */ let ctx = ctx.clone(); - let et1 = edittree.clone(); + let mut editors = Vec::new(); + editors.push(edittree_digit.clone()); + editors.push(edittree_list.clone()); + + let edit_select = Arc::new(RwLock::new(0)); move |ev| { - et1.write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx)); + match ev { + TerminalEvent::Input(termion::event::Event::Key(termion::event::Key::Char('\t'))) => { + let mut i = edit_select.write().unwrap(); + *i = (*i + 1) % editors.len(); + } + _ => { + let i = edit_select.read().unwrap(); + editors[*i].get().send_cmd_obj(ev.to_repr_tree(&ctx)); + } + } } }); @@ -150,25 +183,37 @@ async fn main() { ); comp.push( - edittree_digit.read().unwrap().display_view() - .offset(Vector2::new(0,2)) + edittree_digit.get().display_view() + .offset(Vector2::new(2,2)) ); let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type()); comp.push( nested_tty::make_label(&label_str) + .map_item(|_pt,atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) .offset(Vector2::new(0, 1)) ); comp.push( - edittree.read().unwrap().display_view() - .offset(Vector2::new(0,4)) + digit_u8_buffer.get_port().map( + |d| nested_tty::make_label(&format!("Digit={}", d)) + ) + .to_grid() + .flatten() + .offset(Vector2::new(2,3)) + ); + + + comp.push( + edittree_list.get().display_view() + .offset(Vector2::new(2,6)) ); let label_str = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type()); comp.push( nested_tty::make_label(&label_str) - .offset(Vector2::new(0, 3)) + .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) + .offset(Vector2::new(0, 5)) ); } diff --git a/lib-nested-core/src/editors/char/mod.rs b/lib-nested-core/src/editors/char/mod.rs index d6a4d07..8b587ad 100644 --- a/lib-nested-core/src/editors/char/mod.rs +++ b/lib-nested-core/src/editors/char/mod.rs @@ -3,12 +3,13 @@ use { view::{ OuterViewPort, singleton::*, + port::UpdateTask }, buffer::singleton::* }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context, ReprTree}, + repr_tree::{Context, ReprTree, ReprTreeExt}, edit_tree::{EditTree, TreeNavResult}, editors::ObjCommander, }, @@ -17,7 +18,6 @@ use { }; pub fn init_ctx( ctx: Arc> ) { - let morphtype = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, "Char"), @@ -37,19 +37,25 @@ pub fn init_ctx( ctx: Arc> ) { /* Create EditTree object */ - let mut edittree_char = CharEditor::new_edit_tree( + rt.view_char().0.update(); + + let char_buf = rt.write().unwrap().singleton_buffer::().unwrap(); + + eprintln!("make edittree: char val = {}", char_buf.get()); + let mut edittree = CharEditor::new_edit_tree( ctx.clone(), - SingletonBuffer::new('>'), + char_buf, r3vi::buffer::singleton::SingletonBuffer::::new(0).get_port() ); - /* Insert EditTree into ReprTree - */ - let mut rt = rt.write().unwrap(); - rt.insert_leaf( - vec![ Context::parse(&ctx, "EditTree") ].into_iter(), - SingletonBuffer::new( Arc::new(RwLock::new( edittree_char )) ).get_port().into() - ); + eprintln!("insert Char~EditTree"); + rt.write().unwrap() + .insert_branch( + ReprTree::from_singleton_buffer( + Context::parse(&ctx, "EditTree"), + SingletonBuffer::new(edittree) + ) + ); } } ); @@ -105,7 +111,7 @@ impl CharEditor { data: SingletonBuffer, depth: OuterViewPort> ) -> EditTree { - let data = SingletonBuffer::new('\0'); + //let data = SingletonBuffer::new('\0'); let ctx = ctx0.clone(); let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() })); diff --git a/lib-nested-core/src/editors/digit/cmd.rs b/lib-nested-core/src/editors/digit/cmd.rs new file mode 100644 index 0000000..ae56f9f --- /dev/null +++ b/lib-nested-core/src/editors/digit/cmd.rs @@ -0,0 +1,52 @@ + +use { + r3vi::view::singleton::SingletonView, + crate::{ + repr_tree::{ReprTree, Context}, + edit_tree::{TreeNav, TreeNavResult}, + editors::{ObjCommander, digit::DigitEditor} + }, + + std::sync::{Arc, RwLock} +}; + +impl ObjCommander for DigitEditor { + fn send_cmd_obj(&mut self, cmd_obj: Arc>) -> TreeNavResult { + let cmd_obj = cmd_obj.read().unwrap(); + let cmd_type = cmd_obj.get_type().clone(); + + if cmd_type == Context::parse(&self.ctx, "Char") { + if let Some(cmd_view) = cmd_obj.get_view::>() { + let c = cmd_view.get(); + + self.msg.clear(); + + if self.ctx.read().unwrap().meta_chars.contains(&c) { + return TreeNavResult::Exit; + + } else if c.to_digit(self.radix).is_none() { + /* in case the character c is not in the range of digit-chars, + add a message to the diagnostics view + */ +/* + let message = IndexBuffer::from_iter(vec![ + (Point2::new(1, 0), make_label("invalid digit '")), + (Point2::new(2, 0), make_label(&format!("{}", c)) + .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((140,140,250))))), + (Point2::new(3, 0), make_label("'")) + ]); + + self.msg.push(crate::diagnostics::make_error(message.get_port().flatten())); +*/ + + self.data.set(c); + } else { + self.data.set(c); + } + } + } + + TreeNavResult::Continue + } +} + diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs new file mode 100644 index 0000000..bb022a7 --- /dev/null +++ b/lib-nested-core/src/editors/digit/ctx.rs @@ -0,0 +1,149 @@ + +use { + laddertypes::TypeTerm, + r3vi::{ + buffer::singleton::SingletonBuffer, + view::{ + AnyOuterViewPort, + singleton::* + } + }, + crate::{ + repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, + editors::digit::DigitEditor, + }, + std::sync::{Arc, RwLock} +}; + +pub fn init_ctx( ctx: Arc> ) { + + // todo: proper scoping of Radix variable + ctx.write().unwrap().add_varname("Radix"); + + let morphtype = + crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, ""), + dst_type: Context::parse(&ctx, "~EditTree") + }; + + ctx.write().unwrap() + .morphisms + .add_morphism( + morphtype, + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let radix = + match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { + Some(TypeTerm::Num(n)) => *n as u32, + _ => 0 + }; + + /* Create EditTree object + */ + let mut edittree = DigitEditor::new( + ctx.clone(), + radix, + src_rt.descend( + Context::parse(&ctx, "Char") + ).unwrap() + .singleton_buffer::() + ).into_node( + r3vi::buffer::singleton::SingletonBuffer::::new(0).get_port() + ); + + src_rt.write().unwrap() + .insert_branch( + ReprTree::from_singleton_buffer( + Context::parse(&ctx, "EditTree"), + SingletonBuffer::new(edittree) + ) + ); + } + } + ); + + let morphtype = + crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "~Char"), + dst_type: Context::parse(&ctx, "~ℤ_256~machine::UInt8") + }; + + ctx.write().unwrap() + .morphisms + .add_morphism( + morphtype, + { + let ctx = ctx.clone(); + move |rt: &mut Arc>, σ: &std::collections::HashMap| { + /* infer radix from type + */ + let radix = + match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { + Some(TypeTerm::Num(n)) => (*n) as u32, + _ => 0 + }; + + if radix <= 256 { + + if let Some(src_rt) = rt.descend(Context::parse(&ctx, "Char")) { + /* insert projected view into ReprTree + */ + let u8_view = + src_rt.view_char() + .map(move |c| c.to_digit(radix).unwrap_or(0) as u8); + + rt.write().unwrap().attach_leaf_to::>( + Context::parse(&ctx, "ℤ_256~machine::UInt8").get_lnf_vec().into_iter(), + u8_view + ); + } else { + eprintln!("could not find required source representation: ~Char", radix); + } + } else { + eprintln!("radix too large ({})", radix); + } + } + } + ); + + + let morphtype = + crate::repr_tree::MorphismType { + src_type: Context::parse(&ctx, "~ℤ_256~machine::UInt8"), + dst_type: Context::parse(&ctx, "~Char") + }; + + ctx.write().unwrap().morphisms + .add_morphism(morphtype, { + let ctx = ctx.clone(); + move |rt: &mut Arc>, σ: &std::collections::HashMap| { + /* infer radix from type + */ + let radix = + match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) { + Some(TypeTerm::Num(n)) => (*n) as u32, + _ => 0 + }; + + if radix <= 256 { + /* insert projected view into ReprTree + */ + let char_view = + rt.descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")) + .unwrap() + .view_u8() + .map(move |digit| char::from_digit(digit as u32, radix).unwrap_or('?')); + + rt.write().unwrap().attach_leaf_to::>( + Context::parse(&ctx, "Char").get_lnf_vec().into_iter(), + char_view + ); + } else { + eprintln!("radix too large ({})", radix); + } + } + }); +} + + diff --git a/lib-nested-core/src/editors/digit/editor.rs b/lib-nested-core/src/editors/digit/editor.rs new file mode 100644 index 0000000..a73733b --- /dev/null +++ b/lib-nested-core/src/editors/digit/editor.rs @@ -0,0 +1,89 @@ + +use { + laddertypes::TypeTerm, + r3vi::{ + view::{OuterViewPort,singleton::*}, + buffer::{singleton::*, vec::*} + }, + crate::{ + repr_tree::{ReprTree, Context}, + edit_tree::{ + EditTree, + diagnostics::Message + } + }, + + std::sync::{Arc, RwLock} +}; + + +pub struct DigitEditor { + pub(super) ctx: Arc>, + pub(super) radix: u32, + pub(super) data: SingletonBuffer, + pub(super) msg: VecBuffer, +} + + +impl DigitEditor { + pub fn new(ctx: Arc>, radix: u32, data: SingletonBuffer) -> Self { + DigitEditor { + ctx, + radix, + data, + msg: VecBuffer::new(), + } + } + + pub fn into_node(self, depth: OuterViewPort>) -> EditTree { + // let data = self.get_data(); + let editor = Arc::new(RwLock::new(self)); + let ed = editor.write().unwrap(); + let r = ed.radix; + + EditTree::new(ed.ctx.clone(), depth) + .set_editor(editor.clone()) + .set_cmd(editor.clone()) + .set_diag( + ed.msg.get_port().to_sequence() + ) + } + + pub fn attach_to(&mut self, source: OuterViewPort>) { + /* + source.add_observer( + Arc::new(NotifyFnObserver::new(|_msg| { + self.data.set( source.get() ) + })) + ); + */ + } + + pub fn get_data_port(&self) -> OuterViewPort>> { + let radix = self.radix; + self.data.get_port().map(move |c| + if let Some(d) = c.to_digit(radix) { + Ok(d) + } else { + Err(c) + } + ) + } + + pub fn get_type(&self) -> TypeTerm { + TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("Digit").unwrap()) + } +/* + pub fn get_data(&self) -> Arc> { + ReprTree::ascend( + &ReprTree::from_view( + self.ctx.read().unwrap().type_term_from_str("").unwrap(), + self.get_data_port() + ), + self.get_type() + ) + } + */ +} + + diff --git a/lib-nested-core/src/editors/digit/mod.rs b/lib-nested-core/src/editors/digit/mod.rs new file mode 100644 index 0000000..980db26 --- /dev/null +++ b/lib-nested-core/src/editors/digit/mod.rs @@ -0,0 +1,8 @@ + +pub mod ctx; +pub mod cmd; +pub mod editor; + +pub use editor::DigitEditor; +pub use ctx::init_ctx; + diff --git a/lib-nested-core/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs index 4c37ae0..bbdd19c 100644 --- a/lib-nested-core/src/editors/list/cmd.rs +++ b/lib-nested-core/src/editors/list/cmd.rs @@ -24,10 +24,9 @@ pub enum ListCmd { impl ListCmd { // note: cant use Into becaue of ctx (maybe global typedict?) pub fn into_repr_tree(self, ctx: &Arc>) -> Arc> { - let buf = r3vi::buffer::singleton::SingletonBuffer::new(self); - ReprTree::new_leaf( - Context::parse(ctx, "ListCmd"), - buf.get_port().into() + ReprTree::from_singleton_buffer( + Context::parse(ctx, "ListCmd"), + r3vi::buffer::singleton::SingletonBuffer::new(self) ) } } diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 0ef2180..3c3ae8f 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -2,7 +2,7 @@ use { r3vi::{view::{OuterViewPort, singleton::*}, buffer::singleton::*}, laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context}, + repr_tree::{Context, ReprTree}, editors::list::{ListEditor}//, PTYListController, PTYListStyle} }, std::sync::{Arc, RwLock} @@ -13,6 +13,7 @@ use { pub fn init_ctx(ctx: Arc>) { ctx.write().unwrap().add_list_typename("List".into()); ctx.write().unwrap().add_varname("Item"); + let mt = crate::repr_tree::MorphismType { src_type: Context::parse(&ctx, ""), dst_type: Context::parse(&ctx, "~EditTree") @@ -21,9 +22,10 @@ pub fn init_ctx(ctx: Arc>) { mt, { let ctx = ctx.clone(); - move |rt, σ| { + move |src_rt, σ| { let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() ); if let Some( item_type ) = σ.get( &item_id ) { + let mut edittree_list = ListEditor::new( ctx.clone(), item_type.clone() @@ -31,10 +33,11 @@ pub fn init_ctx(ctx: Arc>) { r3vi::buffer::singleton::SingletonBuffer::::new(0).get_port() ); - let mut rt = rt.write().unwrap(); - rt.insert_leaf( - vec![ Context::parse(&ctx, "EditTree") ].into_iter(), - SingletonBuffer::new( Arc::new(RwLock::new( edittree_list )) ).get_port().into() + src_rt.write().unwrap().insert_branch( + ReprTree::from_singleton_buffer( + Context::parse(&ctx, "EditTree"), + SingletonBuffer::new(edittree_list) + ) ); } else { eprintln!("no item type"); diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index f0e7cb7..00020e7 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -101,7 +101,6 @@ impl ListEditor { } pub fn into_node(mut self, depth: OuterViewPort>) -> EditTree { - let data = self.get_data(); let ctx = self.ctx.clone(); self.depth = depth.clone(); @@ -155,7 +154,7 @@ impl ListEditor { |x| x.read().unwrap().clone() ) } - +/* pub fn get_data(&self) -> Arc> { let data_view = self.get_data_port(); ReprTree::new_leaf( @@ -163,7 +162,7 @@ impl ListEditor { data_view.into() ) } - +*/ pub fn get_item(&self) -> Option { if let Some(idx) = self.cursor.get().idx { let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; @@ -309,22 +308,23 @@ impl ListEditor { let mut b = item.ctrl.spillbuf.write().unwrap(); let rt = ReprTree::new_arc(self.typ.clone()); - let new_edittree = self.ctx.read().unwrap() + let edittree = self.ctx.read().unwrap() .setup_edittree( rt, self.depth.map(|d| d+1) ); - let mut tail_node = new_edittree.write().unwrap(); + + let mut tail_node = edittree.get_mut(); tail_node.goto(TreeCursor::home()); for node in b.iter() { tail_node .send_cmd_obj( - ReprTree::new_leaf( - Context::parse(&self.ctx, "NestedNode"), + ReprTree::from_singleton_buffer( + Context::parse(&self.ctx, "EditTree"), SingletonBuffer::::new( node.read().unwrap().clone() - ).get_port().into() + ) ) ); } @@ -340,7 +340,7 @@ impl ListEditor { drop(tail_node); self.insert( - new_edittree + edittree.value.clone() ); } else { @@ -376,11 +376,11 @@ impl ListEditor { let data = cur_editor.ctrl.spillbuf.read().unwrap(); for x in data.iter() { pxv_editor.send_cmd_obj( - ReprTree::new_leaf( - Context::parse(&self.ctx, "NestedNode"), + ReprTree::from_singleton_buffer( + Context::parse(&self.ctx, "EditTree"), SingletonBuffer::::new( x.read().unwrap().clone() - ).get_port().into() + ) ) ); } @@ -435,11 +435,11 @@ impl ListEditor { for x in data.iter() { cur_editor.send_cmd_obj( - ReprTree::new_leaf( - Context::parse(&self.ctx, "NestedNode"), + ReprTree::from_singleton_buffer( + Context::parse(&self.ctx, "EditTree"), SingletonBuffer::::new( x.read().unwrap().clone() - ).get_port().into() + ) ) ); } diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index ef07efe..abd23ff 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -2,7 +2,7 @@ use { r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}}, laddertypes::{TypeDict, TypeTerm, TypeID}, crate::{ - repr_tree::{ReprTree, MorphismType, GenericReprTreeMorphism, MorphismBase}, + repr_tree::{ReprTree, ReprTreeExt, MorphismType, GenericReprTreeMorphism, MorphismBase}, edit_tree::EditTree }, std::{ @@ -29,7 +29,7 @@ pub struct Context { pub list_types: Vec< TypeID >, pub meta_chars: Vec< char >, - edittree_hook: Arc< dyn Fn(Arc>, TypeTerm) + Send +Sync +'static >, + edittree_hook: Arc< dyn Fn(&mut EditTree, TypeTerm) + Send +Sync +'static >, /// recursion parent: Option>>, @@ -64,7 +64,7 @@ impl Context { Context::with_parent(None) } - pub fn set_edittree_hook(&mut self, hook: Arc< dyn Fn(Arc>, TypeTerm) + Send +Sync +'static >) { + pub fn set_edittree_hook(&mut self, hook: Arc< dyn Fn(&mut EditTree, TypeTerm) + Send +Sync +'static >) { self.edittree_hook = hook; } @@ -78,7 +78,7 @@ impl Context { pub fn make_repr(ctx: &Arc>, t: &TypeTerm) -> Arc> { let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() ))); - ctx.read().unwrap().morphisms.morph( rt.clone(), t ); + ctx.read().unwrap().morphisms.apply_morphism( rt.clone(), &TypeTerm::unit(), t ); rt } @@ -180,30 +180,32 @@ impl Context { &self, rt: Arc>, depth: OuterViewPort> - ) -> Arc> { + ) -> SingletonBuffer { let ladder = TypeTerm::Ladder(vec![ rt.read().unwrap().get_type().clone(), self.type_term_from_str("EditTree").expect("") ]); - - self.morphisms.morph( + + eprintln!("setp_edittree: apply morphism T -> T~EditTree"); + self.morphisms.apply_morphism( rt.clone(), + &rt.get_type(), &ladder ); - let new_edittree = rt - .read().unwrap() - .descend( - self.type_term_from_str("EditTree").expect("") - ).unwrap() - .read().unwrap() - .get_view::> >>() - .unwrap() - .get(); - - (*self.edittree_hook)( new_edittree.clone(), rt.read().unwrap().get_type().clone() ); - - new_edittree + eprintln!("get repr-node of editTree"); + if let Some(new_edittree) = + rt.descend(self.type_term_from_str("EditTree").unwrap()) + { + let buf = new_edittree.singleton_buffer::(); + (*self.edittree_hook)( + &mut *buf.get_mut(), + rt.read().unwrap().get_type().clone() + ); + buf + } else { + unreachable!(); + } } } diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index 4ce5391..816f6b7 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -1,27 +1,50 @@ pub mod context; pub mod morphism; +#[cfg(test)] +mod tests; + pub use { context::{Context}, morphism::{MorphismType, GenericReprTreeMorphism, MorphismBase} }; use { - r3vi::view::{AnyOuterViewPort, OuterViewPort, View, singleton::*}, + r3vi::{ + view::{ + ViewPort, OuterViewPort, + AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, + port::UpdateTask, + View, + singleton::*, sequence::* + }, + buffer::{singleton::*, vec::*} + }, laddertypes::{TypeTerm}, std::{ collections::HashMap, sync::{Arc, RwLock}, + any::Any }, }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> #[derive(Clone)] -pub struct ReprTree { +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>, +} + +#[derive(Clone)] +pub struct ReprTree { type_tag: TypeTerm, - port: Option, branches: HashMap>>, + leaf: Option< ReprLeaf > } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -38,18 +61,282 @@ impl std::fmt::Debug for ReprTree { } } +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl ReprLeaf { + pub fn from_view( src_port: OuterViewPort ) -> Self + where V: View + ?Sized + 'static, + V::Msg: Clone + { + let mut in_port = ViewPort::::new(); + in_port.attach_to(src_port); + + let mut buf_port = ViewPort::::new(); + buf_port.attach_to(in_port.outer()); + + ReprLeaf { + keepalive: None, + in_port: in_port.inner().into(), + out_port: buf_port.into(), + data: None, + } + } + + pub fn attach_to(&mut self, src_port: OuterViewPort) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + self.in_port.clone() + .downcast::().ok().unwrap() + .0.attach_to( src_port ); + } + + pub fn from_singleton_buffer( buffer: SingletonBuffer ) -> Self + where T: Clone + Send + Sync + 'static + { + let in_port = ViewPort::>::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 + { + let sgl_port = self.get_port::< dyn SingletonView >().unwrap().0; + + let data_arc = + if let Some(data) = self.data.as_ref() { + data.clone().downcast::>().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); + let buf = SingletonBuffer { + value: data_arc, + port: sgl_port.inner() + }; + self.keepalive = Some(buf.attach_to( + self.in_port.0.clone() + .downcast::>() + .ok().unwrap() + .outer() + )); + Some(buf) + } else { + None + } + } + + pub fn get_port(&self) -> Option> + where V: View + ?Sized + 'static, + V::Msg: Clone + { + self.out_port.clone().downcast::().ok().map(|p| p.outer()) + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl ReprTree { + pub fn new(type_tag: impl Into) -> Self { + ReprTree { + type_tag: type_tag.into(), + branches: HashMap::new(), + leaf: None + } + } + + pub fn new_arc(type_tag: impl Into) -> Arc> { + Arc::new(RwLock::new(Self::new(type_tag))) + } + + pub fn get_type(&self) -> &TypeTerm { + &self.type_tag + } + + pub fn insert_branch(&mut self, repr: Arc>) { + self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone()); + } + + pub fn from_char(ctx: &Arc>, c: char ) -> Arc> { + ReprTree::from_singleton_buffer( + Context::parse(ctx, "Char"), + SingletonBuffer::new(c) + ) + } + + pub fn from_view( type_tag: impl Into, view: OuterViewPort ) -> Arc> + where V: View + ?Sized + 'static, + V::Msg: Clone + { + let mut rt = ReprTree::new(type_tag); + rt.leaf = Some(ReprLeaf::from_view(view)); + Arc::new(RwLock::new(rt)) + } + + pub fn from_singleton_buffer( type_tag: impl Into, buf: SingletonBuffer ) -> Arc> + where T: Clone + Send + Sync + 'static + { + let mut rt = ReprTree::new(type_tag); + rt.leaf = Some(ReprLeaf::from_singleton_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( + &mut self, + mut type_ladder: impl Iterator, + src_port: OuterViewPort + ) + where V: View + ?Sized + 'static, + V::Msg: Clone + { + if let Some(rung_type) = type_ladder.next() { + if let Some(next_repr) = self.branches.get(&rung_type) { + next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); + } else { + let mut next_repr = ReprTree::new(rung_type.clone()); + next_repr.attach_leaf_to(type_ladder, src_port); + self.insert_branch(Arc::new(RwLock::new(next_repr))); + } + } else { + if let Some(leaf) = self.leaf.as_mut() { + leaf.attach_to(src_port); + } else { + self.leaf = Some(ReprLeaf::from_view(src_port)); + } + } + } + + pub fn insert_leaf( + &mut self, + mut type_ladder: impl Iterator, + leaf: ReprLeaf + ) { + if let Some(type_term) = type_ladder.next() { + if let Some(next_repr) = self.branches.get(&type_term) { + next_repr.write().unwrap().insert_leaf(type_ladder, leaf); + } else { + let mut next_repr = ReprTree::new(type_term.clone()); + next_repr.insert_leaf(type_ladder, leaf); + self.insert_branch(Arc::new(RwLock::new(next_repr))); + } + } else { + self.leaf = Some(leaf) + } + } + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn descend_one(&self, dst_type: impl Into) -> Option>> { + let dst_type = dst_type.into(); + assert!( dst_type.is_flat() ); + self.branches.get(&dst_type).cloned() + } + + pub fn descend_ladder(rt: &Arc>, mut repr_ladder: impl Iterator) -> Option>> { + if let Some(first) = repr_ladder.next() { + let rt = rt.read().unwrap(); + repr_ladder.fold( + rt.descend_one(first), + |s, t| s?.descend(t)) + } else { + Some(rt.clone()) + } + } + + pub fn descend(rt: &Arc>, dst_type: impl Into) -> Option>> { + ReprTree::descend_ladder(rt, dst_type.into().get_lnf_vec().into_iter()) + } + + pub fn ascend(rt: &Arc>, type_term: impl Into) -> Arc> { + let mut n = Self::new(type_term); + n.insert_branch(rt.clone()); + Arc::new(RwLock::new(n)) + } + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn singleton_buffer(&mut self) -> Option> { + if let Some(leaf) = self.leaf.as_mut() { + leaf.as_singleton_buffer::() + } else { + None + } + } + +/* + pub fn vec_buffer(&self) -> Option> { + } +*/ + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn get_port(&self) -> Option> + where + V::Msg: Clone, + { + if let Some(leaf) = self.leaf.as_ref() { + leaf.get_port::() + } else { + None + } + } + + pub fn get_view(&self) -> Option> + where + V::Msg: Clone, + { + self.get_port::()? + .get_view() + } + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + pub fn view_seq(&self) -> OuterViewPort> { + self.get_port::>().expect("no sequence-view available") + } + + pub fn view_char(&self) -> OuterViewPort> { + self.get_port::>().expect("no char-view available") + } + + pub fn view_u8(&self) -> OuterViewPort> { + self.get_port::>().expect("no u8-view available") + } + + pub fn view_u64(&self) -> OuterViewPort> { + self.get_port::>().expect("no u64-view available") + } +} + + + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + pub trait ReprTreeExt { fn get_type(&self) -> TypeTerm; - fn insert_leaf(&mut self, type_ladder: impl Iterator, port: AnyOuterViewPort); + fn insert_leaf(&mut self, type_ladder: impl Into, leaf: ReprLeaf); fn insert_branch(&mut self, repr: Arc>); - fn descend(&self, target_type: impl Into) -> Option>>; - fn descend_ladder(&self, ladder: impl Iterator) -> Option>>; fn view_char(&self) -> OuterViewPort>; fn view_u8(&self) -> OuterViewPort>; fn view_u64(&self) -> OuterViewPort>; + + fn singleton_buffer(&self) -> SingletonBuffer; +// fn vec_buffer(&self) -> VecBuffer; } impl ReprTreeExt for Arc> { @@ -57,8 +344,8 @@ impl ReprTreeExt for Arc> { self.read().unwrap().get_type().clone() } - fn insert_leaf(&mut self, type_ladder: impl Iterator, port: AnyOuterViewPort) { - self.write().unwrap().insert_leaf(type_ladder, port) + fn insert_leaf(&mut self, type_ladder: impl Into, leaf: ReprLeaf) { + self.write().unwrap().insert_leaf(type_ladder.into().get_lnf_vec().into_iter(), leaf) } fn insert_branch(&mut self, repr: Arc>) { @@ -66,11 +353,7 @@ impl ReprTreeExt for Arc> { } fn descend(&self, target_type: impl Into) -> Option>> { - self.read().unwrap().descend(target_type) - } - - fn descend_ladder(&self, ladder: impl Iterator) -> Option>> { - ReprTree::descend_ladder(self, ladder) + ReprTree::descend( self, target_type ) } fn view_char(&self) -> OuterViewPort> { @@ -84,125 +367,16 @@ impl ReprTreeExt for Arc> { fn view_u64(&self) -> OuterViewPort> { self.read().unwrap().view_u64() } + + fn singleton_buffer(&self) -> SingletonBuffer { + self.write().unwrap().singleton_buffer::().expect("") + } +/* + fn vec_buffer(&self) -> VecBuffer { + self.read().unwrap().vec_buffer::().expect("") + } + */ } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -impl ReprTree { - pub fn new(type_tag: impl Into) -> Self { - ReprTree { - type_tag: type_tag.into(), - port: None, - branches: HashMap::new(), - } - } - - pub fn new_arc(type_tag: impl Into) -> Arc> { - Arc::new(RwLock::new(Self::new(type_tag))) - } - - pub fn get_type(&self) -> &TypeTerm { - &self.type_tag - } - - pub fn from_char(ctx: &Arc>, c: char) -> Arc> { - let buf = r3vi::buffer::singleton::SingletonBuffer::::new(c); - ReprTree::new_leaf( - Context::parse(ctx, "Char"), - buf.get_port().into() - ) - } - - pub fn from_u64(ctx: &Arc>, v: u64) -> Arc> { - let buf = r3vi::buffer::singleton::SingletonBuffer::::new(v); - ReprTree::new_leaf( - Context::parse(ctx, ""), - buf.get_port().into() - ) - } - - pub fn new_leaf(type_tag: impl Into, port: AnyOuterViewPort) -> Arc> { - let mut tree = ReprTree::new(type_tag.into()); - tree.insert_leaf(vec![].into_iter(), port); - Arc::new(RwLock::new(tree)) - } - - pub fn insert_branch(&mut self, repr: Arc>) { - self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone()); - } - - pub fn insert_leaf( - &mut self, - mut type_ladder: impl Iterator, - port: AnyOuterViewPort, - ) { - if let Some(type_term) = type_ladder.next() { - if let Some(next_repr) = self.branches.get(&type_term) { - next_repr.write().unwrap().insert_leaf(type_ladder, port); - } else { - let mut next_repr = ReprTree::new(type_term.clone()); - next_repr.insert_leaf(type_ladder, port); - self.insert_branch(Arc::new(RwLock::new(next_repr))); - } - } else { - self.port = Some(port); - } - } - - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - - - pub fn view_char(&self) -> OuterViewPort> { - self.get_port::>().expect("no char-view available") - } - - pub fn view_u8(&self) -> OuterViewPort> { - self.get_port::>().expect("no u8-view available") - } - - pub fn view_u64(&self) -> OuterViewPort> { - self.get_port::>().expect("no u64-view available") - } - - pub fn get_port(&self) -> Option> - where - V::Msg: Clone, - { - Some( - self.port - .clone()? - .downcast::() - .ok()? - ) - } - - pub fn get_view(&self) -> Option> - where - V::Msg: Clone, - { - self.get_port::()? - .get_view() - } - - pub fn descend(&self, dst_type: impl Into) -> Option>> { - self.branches.get(&dst_type.into()).cloned() - } - - pub fn descend_ladder(rt: &Arc>, mut repr_ladder: impl Iterator) -> Option>> { - if let Some(first) = repr_ladder.next() { - let rt = rt.read().unwrap(); - repr_ladder.fold( - rt.descend(first), - |s, t| s?.read().unwrap().descend(t)) - } else { - Some(rt.clone()) - } - } - - pub fn ascend(rt: &Arc>, type_term: impl Into) -> Arc> { - let mut n = Self::new(type_term); - n.insert_branch(rt.clone()); - Arc::new(RwLock::new(n)) - } -} - diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index 689cffc..64ea186 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -1,7 +1,8 @@ use { laddertypes::{TypeTerm, TypeID}, + r3vi::view::AnyOuterViewPort, crate::{ - repr_tree::{ReprTree}, + repr_tree::{ReprTree, ReprTreeExt, ReprLeaf}, }, std::{ sync::{Arc, RwLock}, @@ -20,8 +21,9 @@ pub struct MorphismType { #[derive(Clone)] pub struct GenericReprTreeMorphism { morph_type: MorphismType, - repr_tree_op: Arc< - dyn Fn( Arc>, &HashMap ) + setup_projection: Arc< + dyn Fn( &mut Arc>, &HashMap ) +// -> Result< ReprLeaf, () > + Send + Sync > } @@ -43,12 +45,15 @@ impl MorphismBase { pub fn add_morphism( &mut self, morph_type: MorphismType, - repr_tree_op: impl Fn( Arc>, &HashMap ) + Send + Sync + 'static + setup_projection: + impl Fn( &mut Arc>, &HashMap ) +// -> Result< ReprLeaf, () /* TODO: error */ > + + Send + Sync + 'static ) { self.morphisms.push( GenericReprTreeMorphism { morph_type, - repr_tree_op: Arc::new(repr_tree_op) + setup_projection: Arc::new(setup_projection) } ); } @@ -75,14 +80,15 @@ impl MorphismBase { None } - pub fn morph( + pub fn apply_morphism( &self, - repr_tree: Arc>, - target_type: &TypeTerm + mut repr_tree: Arc>, + src_type: &TypeTerm, + dst_type: &TypeTerm ) { - let t = repr_tree.read().unwrap().get_type().clone(); - if let Some((m, σ)) = self.find_morphism( &t, target_type ) { - (m.repr_tree_op)( repr_tree.clone(), &σ ); +// let t = repr_tree.read().unwrap().get_type().clone(); + if let Some((m, σ)) = self.find_morphism( &src_type, dst_type ) { + (m.setup_projection)( &mut repr_tree, &σ ); } else { eprintln!("could not find morphism"); } diff --git a/lib-nested-core/src/repr_tree/tests.rs b/lib-nested-core/src/repr_tree/tests.rs new file mode 100644 index 0000000..19fa23c --- /dev/null +++ b/lib-nested-core/src/repr_tree/tests.rs @@ -0,0 +1,168 @@ + +use { + r3vi::{ + buffer::singleton::{ + SingletonBuffer + }, + view::port::UpdateTask + }, + crate::{ + repr_tree::{Context, ReprTreeExt, ReprTree, ReprLeaf} + }, + std::sync::{Arc, RwLock} +}; + +#[test] +fn char_view() { + let ctx = Arc::new(RwLock::new(Context::new())); + crate::editors::digit::init_ctx( ctx.clone() ); + + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "") ); + rt_digit.insert_leaf( + Context::parse(&ctx, "Char"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) + ); + + //<><><><> + let mut digit_char_buffer = rt_digit + .descend( Context::parse(&ctx, "Char") ).unwrap() + .singleton_buffer::(); + + assert_eq!( digit_char_buffer.get(), '5' ); + //<><><><> + + let digit_char_view = rt_digit + .descend(Context::parse(&ctx, "Char")).unwrap() + .view_char(); + + assert_eq!( digit_char_view.get_view().unwrap().get(), '5' ); + + + //<><><><> + // `Char-view` is correctly coupled to `char-buffer` + digit_char_buffer.set('2'); + assert_eq!( digit_char_view.get_view().unwrap().get(), '2' ); +} + +#[test] +fn digit_projection_char_to_u8() { + let ctx = Arc::new(RwLock::new(Context::new())); + crate::editors::digit::init_ctx( ctx.clone() ); + + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "") ); + + rt_digit.insert_leaf( + Context::parse(&ctx, "Char"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) + ); + + //<><><><> + // add another representation + + ctx.read().unwrap().morphisms.apply_morphism( + rt_digit.clone(), + &Context::parse(&ctx, "~Char"), + &Context::parse(&ctx, "~ℤ_256~machine::UInt8") + ); + + let digit_u8_view = rt_digit + .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() + .view_u8(); + + assert_eq!( digit_u8_view.get_view().unwrap().get(), 5 as u8 ); + + + // projection behaves accordingly , when buffer is changed + + let mut digit_char_buffer = rt_digit + .descend( Context::parse(&ctx, "Char") ).unwrap() + .singleton_buffer::(); + + digit_char_buffer.set('2'); + assert_eq!( digit_u8_view.get_view().unwrap().get(), 2 as u8 ); +} + +#[test] +fn digit_projection_u8_to_char() { + let ctx = Arc::new(RwLock::new(Context::new())); + crate::editors::digit::init_ctx( ctx.clone() ); + + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "") ); + + rt_digit.insert_leaf( + Context::parse(&ctx, "ℤ_256~machine::UInt8"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new(5 as u8) ) + ); + + //<><><><> + // add another representation + + ctx.read().unwrap().morphisms.apply_morphism( + rt_digit.clone(), + &Context::parse(&ctx, "~ℤ_256~machine::UInt8"), + &Context::parse(&ctx, "~Char") + ); + + let digit_u8_view = rt_digit + .descend(Context::parse(&ctx, "Char")).unwrap() + .view_char(); + + assert_eq!( digit_u8_view.get_view().unwrap().get(), '5' ); +} + + +#[test] +fn char_buffered_projection() { + let ctx = Arc::new(RwLock::new(Context::new())); + crate::editors::digit::init_ctx( ctx.clone() ); + + let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "") ); + + rt_digit.insert_leaf( + Context::parse(&ctx, "ℤ_256~machine::UInt8"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new(8 as u8) ) + ); + + let mut digit_u8_buffer = rt_digit + .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap() + .singleton_buffer::(); + + assert_eq!( digit_u8_buffer.get(), 8 ); + + rt_digit.insert_leaf( + Context::parse(&ctx, "Char"), + ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) + ); + + let digit_char_buf = rt_digit + .descend(Context::parse(&ctx, "Char")).unwrap() + .singleton_buffer::(); + let digit_char_view = rt_digit + .descend(Context::parse(&ctx, "Char")).unwrap() + .view_char(); + + // before setting up the morphism, char-view remains as initialized + assert_eq!( digit_char_buf.get(), '5' ); + assert_eq!( digit_char_view.get_view().unwrap().get(), '5' ); + + // now we attach the char-repr to the u8-repr + ctx.read().unwrap().morphisms.apply_morphism( + rt_digit.clone(), + &Context::parse(&ctx, "~ℤ_256~machine::UInt8"), + &Context::parse(&ctx, "~Char") + ); + + // char buffer and view should now follow the u8-buffer + assert_eq!( digit_char_view.get_view().unwrap().get(), '8' ); + assert_eq!( digit_char_buf.get(), '8' ); + + // now u8-buffer changes, and char-buffer should change accordingly + digit_u8_buffer.set(3); + assert_eq!( digit_u8_buffer.get(), 3 ); + + // char buffer should follow + digit_char_view.0.update(); + assert_eq!( digit_char_buf.get(), '3' ); + assert_eq!( digit_char_view.get_view().unwrap().get(), '3' ); +} + diff --git a/lib-nested-tty/src/edit_tree/keymap.rs b/lib-nested-tty/src/edit_tree/keymap.rs index 1afc123..09a3609 100644 --- a/lib-nested-tty/src/edit_tree/keymap.rs +++ b/lib-nested-tty/src/edit_tree/keymap.rs @@ -68,20 +68,20 @@ impl TerminalEvent { match self { TerminalEvent::Input(Event::Key(key)) => { if let Some(tree_nav_cmd) = neo2_treenav_keymap(key) { - ReprTree::new_leaf( + ReprTree::from_singleton_buffer( Context::parse(&ctx, "TreeNavCmd"), - SingletonBuffer::new(tree_nav_cmd).get_port().into() + SingletonBuffer::new(tree_nav_cmd) ) } else if let Some(tree_nav_cmd) = universal_treenav_keymap(key) { - ReprTree::new_leaf( + ReprTree::from_singleton_buffer( Context::parse(&ctx, "TreeNavCmd"), - SingletonBuffer::new(tree_nav_cmd).get_port().into() + SingletonBuffer::new(tree_nav_cmd) ) } else { if let Some(list_cmd) = tty_list_keymap(key) { - ReprTree::new_leaf( + ReprTree::from_singleton_buffer( Context::parse(&ctx, "ListCmd"), - SingletonBuffer::new(list_cmd).get_port().into() + SingletonBuffer::new(list_cmd) ) } else { match key { @@ -89,9 +89,9 @@ impl TerminalEvent { ReprTree::from_char(&ctx, *c) } _ => { - ReprTree::new_leaf( + ReprTree::from_singleton_buffer( Context::parse(&ctx, "TerminalEvent"), - SingletonBuffer::new(self.clone()).get_port().into() + SingletonBuffer::new(self.clone()) ) } } @@ -99,9 +99,9 @@ impl TerminalEvent { } } _ => { - ReprTree::new_leaf( + ReprTree::from_singleton_buffer( Context::parse(&ctx, "TerminalEvent"), - SingletonBuffer::new(self.clone()).get_port().into() + SingletonBuffer::new(self.clone()) ) } } diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index 3affc68..b3ce8a9 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -94,12 +94,12 @@ impl PTYListStyle { pub fn for_node(node: &mut EditTree, style: (&str, &str, &str)) { node.disp.view .write().unwrap() - .insert_branch(ReprTree::new_leaf( + .insert_branch(ReprTree::from_view( Context::parse(&node.ctx, "TerminalView"), Self::new(style) .pty_view( &node.get_edit::().unwrap().read().unwrap() - ).into() + ) )); } } @@ -225,6 +225,7 @@ impl PTYListController { rt, self.depth.map(|d| d+1) ); + /* let mut ne = new_edittree.write().unwrap(); match ne.send_cmd_obj(cmd_obj.clone()) { TreeNavResult::Continue => { @@ -233,9 +234,12 @@ impl PTYListController { TreeNavResult::Continue } TreeNavResult::Exit => { + */ TreeNavResult::Exit + /* } } + */ }, ListCursorMode::Select => { if let Some(item) = e.get_item_mut() { diff --git a/lib-nested-tty/src/editors/mod.rs b/lib-nested-tty/src/editors/mod.rs index 8194268..4ce366e 100644 --- a/lib-nested-tty/src/editors/mod.rs +++ b/lib-nested-tty/src/editors/mod.rs @@ -17,12 +17,14 @@ use { } }; + pub fn edittree_make_char_view( node: EditTree ) -> EditTree { + eprintln!("nested-tty: EditTree make char-view"); node.disp.view .write().unwrap() - .insert_branch(ReprTree::new_leaf( + .insert_branch(ReprTree::from_view( Context::parse(&node.ctx, "TerminalView"), node.get_edit::< nested::editors::char::CharEditor >() .unwrap() @@ -31,7 +33,6 @@ pub fn edittree_make_char_view( .get_port() .map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) .to_grid() - .into(), )); node @@ -42,7 +43,7 @@ pub fn edittree_make_digit_view( ) -> EditTree { node.disp.view .write().unwrap() - .insert_branch(ReprTree::new_leaf( + .insert_branch(ReprTree::from_view( Context::parse(&node.ctx, "TerminalView"), node.get_edit::< nested::editors::digit::DigitEditor >() .unwrap() @@ -56,7 +57,6 @@ pub fn edittree_make_digit_view( } ) .to_grid() - .into(), )); node diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index f5631af..0da7946 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -39,13 +39,12 @@ pub trait DisplaySegment { } -use nested::repr_tree::Context; +use nested::repr_tree::{Context, ReprTreeExt}; use std::sync::{Arc, RwLock}; impl DisplaySegment for nested::edit_tree::EditTree { fn display_view(&self) -> OuterViewPort { if let Some( tv_repr ) = self.disp.view - .read().unwrap() .descend( Context::parse(&self.ctx, "TerminalView") ) { if let Some(port) =