diff --git a/examples/tty-02-digit/src/main.rs b/examples/tty-02-digit/src/main.rs index 9279cc5..93a1b8e 100644 --- a/examples/tty-02-digit/src/main.rs +++ b/examples/tty-02-digit/src/main.rs @@ -11,7 +11,7 @@ use { cgmath::Vector2, nested::{ editors::ObjCommander, - repr_tree::{Context, ReprTree, ReprTreeExt}, + repr_tree::{Context, ReprTree, ReprTreeExt, ReprTreeBuilder}, edit_tree::{EditTree} }, nested_tty::{ @@ -39,50 +39,23 @@ async fn main() { nested_tty::setup_edittree_hook(&ctx); - /* structure of Repr-Tree - * - * === Repr-Tree === - * - * - * / | \ - * / | \ - * / | \ - * u64 EditTree Char - * - Editor \ - * - Display EditTree - * / | \ - Editor - * / | \ - Display - * TTY PixelBuf SDF / | \ - * / | \ - * TTY PixelBuf SDF - */ - let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "") ); + let digit_builder = ReprTreeBuilder::new( ctx.clone() ) + .require(Context::parse(&ctx, " ~ ℤ_2^64 ~ machine.UInt64")) + .require(Context::parse(&ctx, " ~ EditTree")) + ; /* add initial representation * ~ Char */ - rt_digit.insert_leaf( + let mut rt_digit = ReprTree::from_singleton_buffer( Context::parse(&ctx, "Char"), - nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) + SingletonBuffer::new('5') ); - - /* furthermore, setup projections to and from u8 value, - * this synchronizes the buffers - */ - ctx.read().unwrap().apply_morphism( - &rt_digit, - &laddertypes::MorphismType { - src_type: Context::parse(&ctx, "~Char"), - dst_type: Context::parse(&ctx, "~ℤ_2^64~machine.UInt64") - } - ); - ctx.read().unwrap().apply_morphism( - &rt_digit, - &laddertypes::MorphismType { - src_type: Context::parse(&ctx, "~Char"), - dst_type: Context::parse(&ctx, "~EditTree") - } + rt_digit.write().unwrap().set_halo( + Context::parse(&ctx, "") ); + rt_digit = digit_builder.build_from(rt_digit) + .expect("failed to build repr tree"); /* setup terminal */ diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs index d5f8ff9..c3fa53e 100644 --- a/examples/tty-03-string/src/main.rs +++ b/examples/tty-03-string/src/main.rs @@ -15,7 +15,7 @@ use { cgmath::Vector2, nested::{ editors::ObjCommander, - repr_tree::{Context, ReprTree, ReprTreeExt}, + repr_tree::{Context, ReprTree, ReprTreeExt, ReprTreeBuilder}, edit_tree::{EditTree} }, nested_tty::{ @@ -43,35 +43,45 @@ async fn main() { /* Create a Representation-Tree of type */ - let mut rt_string = ReprTree::from_str( - Context::parse(&ctx, "~"), - "hello world" + let mut ldata = VecBuffer::new(); + for c in "Hello World!".chars() { + let rt = ReprTree::from_singleton_buffer( + Context::parse(&ctx, "Char"), + SingletonBuffer::new(c)); + + ldata.push(rt); + } + + let mut ldata_rt = ReprTree::from_vec_buffer( + Context::parse(&ctx, ""), + ldata.clone() ); - /* create EditTree - */ - ctx.read().unwrap().apply_morphism( - &rt_string, - &laddertypes::MorphismType { - src_type: Context::parse(&ctx, ""), - dst_type: Context::parse(&ctx, " ~ EditTree") - } + ldata_rt.write().unwrap().set_halo( + Context::parse(&ctx, "~") ); - // .. avoid cycle of projections.. - rt_string.write().unwrap().detach(&ctx); - - /* In order to get access to the values that are modified by the Editor, - * we apply a morphism that, given the List of Edit-Trees, extracts - * the value from each EditTree and shows them in a ListView. - */ - ctx.read().unwrap().apply_morphism( - &rt_string, - &laddertypes::MorphismType { - src_type: Context::parse(&ctx, "~EditTree"), - dst_type: Context::parse(&ctx, "") - } + let mut ledit = nested::editors::list::ListEditor::with_data( + ctx.clone(), + Context::parse(&ctx, "Char"), + ldata ); + ledit.update_item_reprtrees(&Context::parse(&ctx, "Char")); + ledit.update_item_reprtrees(&Context::parse(&ctx, "Char~EditTree")); + let mut ledit = ledit.into_node(SingletonBuffer::new(0).get_port()); + + nested_tty::editors::list::PTYListStyle::for_node(&mut ledit, ("<", "", ">")); + nested_tty::editors::list::PTYListController::for_node(&mut ledit, None, None); + let ledittree = SingletonBuffer::new(Arc::new(RwLock::new(ledit))); + + let rt_string_builder = ReprTreeBuilder::new( ctx.clone() ) + .require(Context::parse(&ctx, "~")) + .require(Context::parse(&ctx, "")) + .require(Context::parse(&ctx, "~EditTree")) + ; + + let rt_string = rt_string_builder.build_from(ldata_rt).expect("could not build rt_string"); + eprintln!("rt_string = \n{}", rt_string.read().unwrap().fmt(&ctx, 0)); /* Now, get the ListView that serves our char-values. * This view is a projection created by the morphism that was called above. @@ -81,17 +91,6 @@ async fn main() { .get_port::>() .unwrap(); - /* Lets add another morphism which will store the values - * of the character-list in a `Vec` - */ - ctx.read().unwrap().apply_morphism( - &rt_string, - &laddertypes::MorphismType { - src_type: Context::parse(&ctx, ""), - dst_type: Context::parse(&ctx, "~") - } - ); - /* Access the Vec object (wrapped behind a VecBuffer) * from the ReprTree. */ @@ -109,7 +108,7 @@ async fn main() { /* setup terminal */ let app = TTYApplication::new({ - let edittree_list = rt_string.edittree(&ctx).clone(); + let edittree_list = ledittree.clone();//rt_string.edittree(&ctx).clone(); /* event handler */ @@ -137,7 +136,8 @@ async fn main() { .offset(Vector2::new(1,1))); comp.push( - rt_string.edittree(&ctx).get() + //rt_string.edittree(&ctx).get() + ledittree.get() .read().unwrap() .display_view() .offset(Vector2::new(3,2))); @@ -145,6 +145,7 @@ async fn main() { comp.push( string_view_tty .offset(Vector2::new(5,3))); + } /* write the changes in the view of `term_port` to the terminal diff --git a/examples/tty-04-posint/src/main.rs b/examples/tty-04-posint/src/main.rs index 4c91ee5..7ffbc87 100644 --- a/examples/tty-04-posint/src/main.rs +++ b/examples/tty-04-posint/src/main.rs @@ -16,7 +16,7 @@ use { editors::{ ObjCommander }, - repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, + repr_tree::{Context, ReprTreeBuilder, ReprTree, ReprTreeExt, ReprLeaf}, edit_tree::{EditTree, TreeNav, TreeCursor} }, nested_tty::{ @@ -46,76 +46,49 @@ async fn main() { /* Create a Representation-Tree of type `ℕ` * with a specific representation-path (big-endian hexadecimal string) */ - let mut rt_int = nested::repr_tree::ReprTree::from_str( - /* TYPE */ + let int_builder = ReprTreeBuilder::new( ctx.clone() ) + .require(Context::parse(&ctx, + "ℕ ~ ~ ~Char> ~ EditTree")) + /* + .require(Context::parse(&ctx, + "ℕ ~ ~ > ~ EditTree")) + .require(Context::parse(&ctx, + "ℕ ~ ~ EditTree")) + .require(Context::parse(&ctx, + "ℕ ~ ~ EditTree")) + .require(Context::parse(&ctx, + "ℕ ~ ~ EditTree")) + */ + ; + + let mut rt_int = nested::repr_tree::ReprTree::from_str("cff"); + rt_int.write().unwrap().set_halo( + /* HALO TYPE */ Context::parse(&ctx, " ℕ ~ ~ > ~ > ~ - ~ - "), - - /* VALUE */ - "cff" + ") ); - /* initially copy values from Vec to EditTree... - */ - ctx.read().unwrap().build_repr_tree( - &rt_int, - Context::parse(&ctx, "ℕ ~ ~ ~Char> ~ "), - vec![ - Context::parse(&ctx, "ℕ ~ ~ > ~ EditTree"), - Context::parse(&ctx, "ℕ ~ ~ > ~ EditTree"), - ]); + eprintln!("rt_int = \n{}\n", rt_int.read().unwrap().fmt(&ctx, 0)); - fn set_master( - ctx: &Arc>, - rt: &Arc>, - mut leaves: Vec< laddertypes::TypeTerm >, - master_idx: usize - ) { - eprintln!("set master to {}", master_idx); - if master_idx < leaves.len() { - let master = leaves.remove( master_idx ); - rt.write().unwrap().detach( &ctx ); - ctx.read().unwrap().build_repr_tree( - rt, - master, - leaves - ); - } - } + rt_int = int_builder.build_from( rt_int ).expect("cant build initial repr tree"); - let editor_types = vec![ - Context::parse(&ctx, - "ℕ ~ ~ > ~ EditTree"), - Context::parse(&ctx, - "ℕ ~ ~ > ~ EditTree"), - Context::parse(&ctx, - "ℕ ~ ~ EditTree"), - Context::parse(&ctx, - "ℕ ~ ~ EditTree"), - Context::parse(&ctx, - "ℕ ~ ~ EditTree"), - ]; + eprintln!("rt_int = \n{}\n", rt_int.read().unwrap().fmt(&ctx, 0)); - set_master(&ctx, &rt_int, editor_types.clone(), 0); + return; /* list of editors */ let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "")); // add all desired editors to the list - for leaf in editor_types.iter() { - let et = - rt_int - .descend(leaf.clone()).unwrap() - .edittree(&ctx).get(); - et.write().unwrap().goto(TreeCursor::none()); - list_editor.data.push(et); + for edit_leaf in int_builder.required_leaves { + let leaf_rt = rt_int.descend(edit_leaf.clone()).unwrap(); + list_editor.data.push(leaf_rt); } let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port()); @@ -128,7 +101,7 @@ async fn main() { tree_addr: vec![0,0] }); let edittree = Arc::new(RwLock::new(edittree)); - + /* setup terminal */ let app = TTYApplication::new({ @@ -137,7 +110,6 @@ async fn main() { let ctx = ctx.clone(); let rt_int = rt_int.clone(); let last_idx = RwLock::new(0); - let editor_types = editor_types.clone(); move |ev| { let cur = edittree.read().unwrap().get_cursor(); if cur.tree_addr.len() > 0 { @@ -145,6 +117,7 @@ async fn main() { let ci = cur.tree_addr[0]; if *li != ci { + /* eprintln!("----------------------------------"); set_master( &ctx, @@ -152,6 +125,8 @@ async fn main() { editor_types.clone(), ci as usize ); + */ + int_builder.update( &rt_int, int_builder.required_leaves[ci as usize].clone() ); *li = ci; } } @@ -177,7 +152,7 @@ async fn main() { let halo_type = rt_edittree.read().unwrap().get_halo_type().clone(); let edittree = rt_edittree.edittree( &ctx ); - comp.push( nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) + comp.push( nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) .offset(Vector2::new(1,y))); @@ -186,7 +161,7 @@ async fn main() { } let mut y = 1; - for t in editor_types.iter() { + for t in int_builder.required_leaves.iter() { show_edit_tree(&ctx, &mut comp, &rt_int.descend(t.clone()).expect(""), y); y += 3; } @@ -196,4 +171,3 @@ async fn main() { */ app.show().await.expect("output error!"); } - diff --git a/examples/tty-05-dictionary/src/main.rs b/examples/tty-05-dictionary/src/main.rs index d6daefc..f5b4478 100644 --- a/examples/tty-05-dictionary/src/main.rs +++ b/examples/tty-05-dictionary/src/main.rs @@ -10,7 +10,7 @@ use { editors::{ ObjCommander }, - repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, + repr_tree::{Context, ReprTreeBuilder, ReprTree, ReprTreeExt, ReprLeaf}, edit_tree::{EditTree, TreeNav, TreeCursor} }, laddertypes::{ @@ -160,62 +160,24 @@ async fn main() { ctx.write().unwrap().morphisms.add_morphism( symbol_morph_u64_to_str ); ctx.write().unwrap().morphisms.add_morphism( symbol_morph_str_to_u64 ); - let mut symbol_rt = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, " - Instruction ~ Mnemonic ~ - "), - "Call" - ); + let mut symbol_rt = nested::repr_tree::ReprTree::from_str("Call"); + symbol_rt.write().unwrap().set_halo(Context::parse(&ctx, " + Instruction ~ Mnemonic ~ + ")); - // this is required to initialize the representation, - // and to take the value from - ctx.read().unwrap().build_repr_tree( - &symbol_rt, - Context::parse(&ctx, "Instruction ~ Mnemonic ~ "), - vec![ - Context::parse(&ctx, "Instruction ~ Opcode ~ ℕ ~ ~ EditTree"), - Context::parse(&ctx, "Instruction ~ Mnemonic ~ ~ EditTree"), - ]); + let symbol_builder = ReprTreeBuilder::new( ctx.clone() ) + //.require(Context::parse(&ctx, "Instruction ~ Opcode ~ ℕ ~ ~ EditTree")) + .require(Context::parse(&ctx, "Instruction ~ Mnemonic ~ ~ EditTree")) + ; - symbol_rt.write().unwrap().detach( &ctx ); + symbol_rt = symbol_builder.build_from(symbol_rt).expect("failed to build symbol repr-tree"); - fn set_master( - ctx: &Arc>, - rt: &Arc>, - mut leaves: Vec< laddertypes::TypeTerm >, - master_idx: usize - ) { - eprintln!("set master to {}", master_idx); - if master_idx < leaves.len() { - let master = leaves.remove( master_idx ); - rt.write().unwrap().detach( &ctx ); - ctx.read().unwrap().build_repr_tree( - rt, - master, - leaves - ); - } - } - - let editor_types = vec![ - Context::parse(&ctx, - "Instruction ~ Mnemonic ~ ~ EditTree"), - Context::parse(&ctx, - "Instruction ~ Opcode ~ ℕ ~ ~ EditTree"), - Context::parse(&ctx, - "Instruction ~ Opcode ~ ℕ ~ ~ EditTree"), - ]; - - set_master(&ctx, &symbol_rt, editor_types.clone(), 0); let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "")); // add all desired editors to the list - for leaf in editor_types.iter() { - let et = - symbol_rt - .descend(leaf.clone()).unwrap() - .edittree(&ctx).get(); - et.write().unwrap().goto(TreeCursor::none()); - list_editor.data.push(et); + for edit_leaf in symbol_builder.required_leaves { + let leaf_rt = symbol_rt.descend(edit_leaf.clone()).unwrap(); + list_editor.data.push(leaf_rt); } let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port()); @@ -233,7 +195,6 @@ async fn main() { let ctx = ctx.clone(); let symbol_rt = symbol_rt.clone(); let last_idx = RwLock::new(0); - let editor_types = editor_types.clone(); move |ev| { let cur = edittree.read().unwrap().get_cursor(); if cur.tree_addr.len() > 0 { @@ -241,13 +202,7 @@ async fn main() { let ci = cur.tree_addr[0]; if *li != ci { - eprintln!("----------------------------------"); - set_master( - &ctx, - &symbol_rt, - editor_types.clone(), - ci as usize - ); + // symbol_builder.update() *li = ci; } } diff --git a/examples/tty-06-lines/src/main.rs b/examples/tty-06-lines/src/main.rs index 701c26c..33a956e 100644 --- a/examples/tty-06-lines/src/main.rs +++ b/examples/tty-06-lines/src/main.rs @@ -32,16 +32,20 @@ struct LineDiagnostic { msg: String } +struct LineEditor { + num_buf: SingletonBuffer< u64 >, + diag_buf: VecBuffer< LineDiagnostic >, + chars_edit: Arc>, + out_port: ViewPort< dyn TerminalView >, + view: Arc>, + cast: Arc>>, +} + struct LineView { line_num: Arc< dyn SingletonView >, segments: Arc< dyn SequenceView >, diagnostics: Arc< dyn SequenceView >, - - diag_buf: VecBuffer< LineDiagnostic >, - - cast: Arc>>, - out_port: OuterViewPort, - proj_helper: ProjectionHelper + proj_helper: ProjectionHelper } impl View for LineView { @@ -121,10 +125,9 @@ impl IndexView> for LineView { while n > 0 { n_digits += 1; n /= 10; } let diag_len = self.diagnostics.iter().map(|d| d.msg.chars().count() as i16).max().unwrap_or(0); IndexArea::Range( - Point2::new( xoff -1-n_digits , 0) ..= + Point2::new( xoff - n_digits - 1 , 0) ..= Point2::new( - xoff+ - i16::max( + xoff + i16::max( self.segments.len().unwrap_or(i16::MAX as usize) as i16, diag_len ), @@ -134,57 +137,72 @@ impl IndexView> for LineView { } } -impl LineView { +impl LineEditor { pub fn new( + ctx: &Arc>, n: u64, - le: &ListEditor, ) -> Arc> { - let line_num_buf = SingletonBuffer::new(n); + let num_buf = SingletonBuffer::new(n); let diag_buf = VecBuffer::new(); - let seg_seq = ListSegmentSequence::new(le.get_cursor_port(), le.get_data_port()) + let chars_edit = ListEditor::new( + ctx.clone(), + Context::parse(&ctx, "") + ); + let chars_seg_seq = ListSegmentSequence::new(chars_edit.get_cursor_port(), chars_edit.get_data_port()) .read().unwrap().get_view(); let out_port = ViewPort::new(); - let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone()); - let lv = Arc::new(RwLock::new(LineView{ - line_num: proj_helper.new_singleton_arg(0, line_num_buf.get_port(), - |s: &mut LineView, _msg|{ - s.cast.write().unwrap() + let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone()); + let line_view = Arc::new(RwLock::new(LineView { + line_num: proj_helper.new_singleton_arg(0, num_buf.get_port(), + |e: &mut LineEditor, _msg|{ + e.cast.write().unwrap() .notify(&IndexArea::Range( (Point2::new(-100, 0) ..= Point2::new(0, 0)) )); }), - segments: proj_helper.new_sequence_arg(1, seg_seq, - |s: &mut LineView, idx| { - s.cast.write().unwrap() + segments: proj_helper.new_sequence_arg(1, chars_seg_seq, + |e: &mut LineEditor, idx| { + e.cast.write().unwrap() .notify(&IndexArea::Range( - (Point2::new(0, *idx as i16 - 1) ..= Point2::new(100, *idx as i16)) + (Point2::new(*idx as i16, 0) ..= Point2::new(*idx as i16, 0)) )); }), diagnostics: proj_helper.new_sequence_arg(2, diag_buf.get_port().to_sequence(), - |s: &mut LineView, idx| { - s.cast.write().unwrap() + |e: &mut LineEditor, idx| { + e.cast.write().unwrap() .notify(&IndexArea::Range( (Point2::new(-100, 1+*idx as i16) ..= Point2::new(100, 1+*idx as i16)) )); }), - diag_buf, - - cast: out_port.inner().get_broadcast(), proj_helper, - out_port: out_port.outer() })); - lv.write().unwrap().proj_helper.set_proj(&lv); - out_port.inner().set_view(Some(lv.clone())); + let line_edit = Arc::new(RwLock::new(LineEditor { + num_buf, + diag_buf, + chars_edit: Arc::new(RwLock::new(chars_edit)), + cast: out_port.inner().get_broadcast(), + view: line_view.clone(), + out_port, + })); - lv + line_view.write().unwrap().proj_helper.set_proj(&line_edit); + line_edit + } + + pub fn set_linum(&mut self, n: u64) { + self.num_buf.set(n); + } + + pub fn add_diag(&mut self, diag: LineDiagnostic) { + self.diag_buf.push(diag); } pub fn get_port(&self) -> OuterViewPort { - self.out_port.clone() + self.out_port.outer() } } @@ -205,6 +223,11 @@ impl LinesEditor { Context::parse(&ctx, "Line ~ EditTree"), |rt, σ| { eprintln!("LINE EDITOR CONSTRUCT"); +/* + rt.insert_branch( + Context::parse(&ctx, "EditTree"), + + )*/ } ); ctx.write().unwrap().morphisms.add_morphism( line_to_edittree ); @@ -238,12 +261,11 @@ impl LinesEditor { let mut list_edit = list_edit.into_node( depth_port ); nested_tty::editors::list::PTYListController::for_node( &mut list_edit, Some('\n'), None ); - list_edit.disp.view - .write().unwrap() - .insert_branch(ReprTree::from_view( - Context::parse(&ctx, "TerminalView"), - lines_view - )); + list_edit.disp.view.write().unwrap() + .insert_branch(ReprTree::from_view( + Context::parse(&ctx, "TerminalView"), + lines_view + )); LinesEditor { // lines, @@ -258,26 +280,34 @@ impl LinesEditor { .read().unwrap() .data.len() as u64; - let line = - self.make_line(line_value) - .descend(Context::parse(&self.ctx, "EditTree")).unwrap() - .edittree(&self.ctx).get(); + let depth = SingletonBuffer::new(0).get_port(); - let le = line.read().unwrap().get_edit::().unwrap(); - le.write().unwrap().goto(TreeCursor::none()); + let chars_rt = self.make_line(line_value); + let chars_edittree = chars_rt + .descend(Context::parse(&self.ctx, "EditTree")).unwrap() + .edittree(&self.ctx).get() + .read().unwrap().clone(); - let lvport = LineView::new( n, &*le.read().unwrap() ).read().unwrap().get_port(); - line.write().unwrap().disp.view + let line = LineEditor::new(&self.ctx, n); + line.write().unwrap().chars_edit = chars_edittree.get_edit::().unwrap(); + let line_port = line.read().unwrap().get_port(); + + let mut line_edittree = EditTree::new(self.ctx.clone(), depth) + .set_nav( line.read().unwrap().chars_edit.clone() ) + .set_cmd( line.read().unwrap().chars_edit.clone() ) + .set_editor( line.clone() ); + + line_edittree.disp.view .insert_leaf( Context::parse(&self.ctx, "TerminalView"), - ReprLeaf::from_view( lvport ) + ReprLeaf::from_view( line_port ) ); self.edit.write().unwrap() .get_edit::< ListEditor >().unwrap() .write().unwrap() .data - .push(line); + .push( Arc::new(RwLock::new(line_edittree)) ); } pub fn make_line(&self, line_value: &str) -> Arc> { @@ -287,6 +317,7 @@ impl LinesEditor { line_value ); + // create Editor & transfer data to Editor ctx.read().unwrap().apply_morphism( &rt_line, &laddertypes::MorphismType { diff --git a/examples/tty-07-color/Cargo.toml b/examples/tty-07-color/Cargo.toml new file mode 100644 index 0000000..53db651 --- /dev/null +++ b/examples/tty-07-color/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "tty-06-color" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +laddertypes = { path = "../../../lib-laddertypes" } +r3vi = { path = "../../../lib-r3vi" } +nested = { path = "../../lib-nested-core" } +nested-tty = { path = "../../lib-nested-tty" } +termion = "*" +cgmath = "*" + +[dependencies.async-std] +version = "1.9.0" +features = ["unstable", "attributes"] + diff --git a/examples/tty-07-color/src/main.rs b/examples/tty-07-color/src/main.rs new file mode 100644 index 0000000..e02ae87 --- /dev/null +++ b/examples/tty-07-color/src/main.rs @@ -0,0 +1,232 @@ +extern crate cgmath; +extern crate nested; +extern crate nested_tty; +extern crate r3vi; +extern crate termion; + +use { + cgmath::Vector2, + nested::{ + editors::{ + ObjCommander + }, + repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, + edit_tree::{EditTree, TreeNav, TreeCursor} + }, + nested_tty::{ + DisplaySegment, TTYApplication, + TerminalCompositor, TerminalStyle, TerminalView, + TerminalAtom, TerminalEvent + }, + r3vi::{ + buffer::{singleton::*, vec::*}, + view::{port::UpdateTask, singleton::*, list::*, sequence::*}, + projection::* + }, + std::sync::{Arc, RwLock}, +}; + +#[async_std::main] +async fn main() { + + /* setup context + */ + let ctx = Arc::new(RwLock::new(Context::new())); + nested::editors::char::init_ctx( ctx.clone() ); + nested::editors::digit::init_ctx( ctx.clone() ); + nested::editors::integer::init_ctx( ctx.clone() ); + nested::editors::list::init_ctx( ctx.clone() ); + nested_tty::setup_edittree_hook(&ctx); + + eprintln!( + "Char = {:?}\nu64 = {:?}\nEditTree = {:?}, = {:?}", + Context::parse(&ctx, "Char"), + Context::parse(&ctx, "machine.UInt64"), + Context::parse(&ctx, "EditTree"), + Context::parse(&ctx, "") + ); + + let mut red = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, " + ℕ ~ ~ > ~ ~ Char> ~ + "), + "221" + ); + ctx.read().unwrap().apply_morphism( &red, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ ~ ~ Char > ~ "), + dst_type: Context::parse(&ctx, "ℕ ~ ~ ~ Char > ~ EditTree") + }); + let red_edit = ctx.read().unwrap().setup_edittree( + red.descend(Context::parse(&ctx, " + ℕ ~ ~ ~Char> + ")).unwrap(), + SingletonBuffer::new(0).get_port() + ).unwrap(); + + let mut green = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, " + ℕ ~ ~ > ~ ~ Char> ~ + "), + "220" + ); + ctx.read().unwrap().apply_morphism( &green, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ ~ ~ Char > ~ "), + dst_type: Context::parse(&ctx, "ℕ ~ ~ ~ Char > ~ EditTree") + }); + let green_edit = ctx.read().unwrap().setup_edittree(green.descend(Context::parse(&ctx, " + ℕ ~ ~ ~Char> + ")).unwrap(), + SingletonBuffer::new(0).get_port() + ).unwrap(); + + + let mut blue = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, " + ℕ ~ ~ > ~ ~ Char> ~ + "), + "5" + ); + ctx.read().unwrap().apply_morphism( &blue, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, "ℕ ~ ~ ~ Char > ~ "), + dst_type: Context::parse(&ctx, "ℕ ~ ~ ~ Char > ~ EditTree") + }); + let blue_edit = ctx.read().unwrap().setup_edittree( + blue.descend(Context::parse(&ctx, " + ℕ ~ ~ ~Char> + ")).unwrap(), + SingletonBuffer::new(0).get_port() + ).unwrap(); + + + eprintln!("======\n M A K E L I S T E D I T O R\n======\n"); + + let mut color = nested::repr_tree::ReprTree::new_arc( + Context::parse(&ctx, "") + ); + + color.insert_leaf( + Context::parse(&ctx, " + + ~ > + ~ + ~ Char > + > + ~ + ~ + "), + + ReprLeaf::from_vec_buffer(VecBuffer::< + Arc> + >::with_data(vec![ + red_edit.get(), + green_edit.get(), + blue_edit.get() + ])) + ); + ctx.read().unwrap().apply_morphism( + &color, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, " ~ ~ Char > ~ EditTree > ~ "), + dst_type: Context::parse(&ctx, " ~ ~ Char > > ~ EditTree") + }); + let edit = ctx.read().unwrap().setup_edittree( + color.descend(Context::parse(&ctx, " + + ~ < Seq~List + ~ Char > + > + ")).unwrap(), + SingletonBuffer::new(0).get_port() + ).unwrap(); + + + +eprintln!(" edittree => list list char "); + ctx.read().unwrap().apply_morphism( + &color, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, " ~ ~ Char > > ~ EditTree"), + dst_type: Context::parse(&ctx, " ~ ~ Char > >") + }); + +eprintln!("list char ==> list u64"); + ctx.read().unwrap().apply_morphism( + &color, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, " ~ ~ Char>>"), + dst_type: Context::parse(&ctx, " ~ ~ ℤ_2^64 ~ machine.UInt64>>") + }); +return; + + ctx.read().unwrap().apply_morphism( + &color, + &laddertypes::MorphismType { + src_type: Context::parse(&ctx, " ~ ~ ℤ_2^64 ~ machine.UInt64 > >"), + dst_type: Context::parse(&ctx, " ~ ~ Char > >") + }); + /* + let edit2 = ctx.read().unwrap().setup_edittree( + color.descend(Context::parse(&ctx, " + + ~ < Seq~List + ~ Char > + > + ")).unwrap(), + SingletonBuffer::new(0).get_port() + ).unwrap(); +*/ + + return; + + /* setup terminal + */ + let app = TTYApplication::new({ + /* event handler + */ + let ctx = ctx.clone(); + let edit = edit.get().clone(); + + edit.write().unwrap().goto(TreeCursor::home()); + + move |ev| { + edit.write().unwrap().send_cmd_obj( ev.to_repr_tree(&ctx) ); + } + }); + + /* Setup the compositor to serve as root-view + * by routing it to the `app.port` Viewport, + * so it will be displayed on TTY-output. + */ + let compositor = TerminalCompositor::new(app.port.inner()); + + /* Now add some views to our compositor + */ + { + let mut comp = compositor.write().unwrap(); + + fn show_edit_tree( ctx: &Arc>, comp: &mut TerminalCompositor, rt: &Arc>, y: i16 ) + { + let rt_edittree = rt.descend(Context::parse(&ctx, "EditTree")).expect("descend"); + let halo_type = rt_edittree.read().unwrap().get_halo_type().clone(); + let edittree = rt_edittree.read().unwrap().get_view::>>>().unwrap().get().read().unwrap().clone(); + + comp.push( nested_tty::make_label( &ctx.read().unwrap().type_term_to_str(&halo_type) ) + .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90)))) + .offset(Vector2::new(1,y))); + + comp.push( edittree.display_view() + .offset(Vector2::new(1,y+1))); + } + + show_edit_tree( &ctx, &mut comp, &color.descend(Context::parse(&ctx, " ~ ~Char>>")).unwrap(), 1 ); + show_edit_tree( &ctx, &mut comp, &color.descend(Context::parse(&ctx, " ~ ~Char>>")).unwrap(), 3 ); + } + + /* write the changes in the view of `term_port` to the terminal + */ + app.show().await.expect("output error!"); +} + diff --git a/lib-nested-core/src/edit_tree/node.rs b/lib-nested-core/src/edit_tree/node.rs index 8b5a8a6..53d1c4b 100644 --- a/lib-nested-core/src/edit_tree/node.rs +++ b/lib-nested-core/src/edit_tree/node.rs @@ -7,7 +7,7 @@ use { }, laddertypes::{TypeTerm}, crate::{ - repr_tree::{ReprTree, Context}, + repr_tree::{ReprTree, ReprTreeArc, Context}, edit_tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}}, editors::{list::{ListCursorMode}, ObjCommander} } @@ -32,9 +32,7 @@ pub struct EdittreeControl { Option< Arc > >, - pub spillbuf: Arc> > - >>, + pub spillbuf: Arc >>, /// commander & navigation pub cmd: SingletonBuffer< @@ -46,7 +44,7 @@ pub struct EdittreeControl { // could be replaced by cmd when TreeNav -CmdObjects are used pub tree_nav: SingletonBuffer< Option< Arc> > - >, + >, } #[derive(Clone)] @@ -153,7 +151,7 @@ impl TreeNav for EditTree { tn.read().unwrap().get_mode_view() } else { OuterViewPort::default() - } + } } fn get_cursor_warp(&self) -> TreeCursor { @@ -225,4 +223,3 @@ impl Diagnostics for EditTree { self.get_diag() } } - diff --git a/lib-nested-core/src/editors/list/cmd.rs b/lib-nested-core/src/editors/list/cmd.rs index bbdd19c..03b3e96 100644 --- a/lib-nested-core/src/editors/list/cmd.rs +++ b/lib-nested-core/src/editors/list/cmd.rs @@ -25,7 +25,7 @@ impl ListCmd { // note: cant use Into becaue of ctx (maybe global typedict?) pub fn into_repr_tree(self, ctx: &Arc>) -> Arc> { ReprTree::from_singleton_buffer( - Context::parse(ctx, "ListCmd"), + Context::parse(ctx, "ListCmd"), r3vi::buffer::singleton::SingletonBuffer::new(self) ) } @@ -35,28 +35,7 @@ impl ObjCommander for ListEditor { fn send_cmd_obj(&mut self, cmd_obj: Arc>) -> TreeNavResult { let cmd_repr = cmd_obj.read().unwrap(); - if let Some(view) = cmd_repr.get_view::>() { - let node = view.get(); - let cur = self.cursor.get(); - - if let Some(idx) = cur.idx { - match cur.mode { - ListCursorMode::Select => { - *self.data.get_mut(idx as usize) = Arc::new(RwLock::new(node)); - TreeNavResult::Exit - } - ListCursorMode::Insert => { - self.insert(Arc::new(RwLock::new(node))); - self.cursor.set(ListCursor{ idx: Some(idx+1), mode: ListCursorMode::Insert }); - TreeNavResult::Continue - } - } - } else { - TreeNavResult::Exit - } - } - - else if let Some(cmd) = cmd_repr.get_view::>() { + if let Some(cmd) = cmd_repr.get_view::>() { let cur = self.cursor.get(); drop(cmd_repr); @@ -69,10 +48,11 @@ impl ObjCommander for ListEditor { _ => { if let Some(idx) = cur.idx { match cur.mode { - ListCursorMode::Select => { - if let Some(mut item) = self.get_item().clone() { + ListCursorMode::Select => { + if let Some(mut item) = self.get_cur_edittree() { + let mut item = item.write().unwrap(); let item_cur = item.get_cursor(); - + match cmd.get() { ListCmd::DeletePxev => { if idx > 0 @@ -151,14 +131,30 @@ impl ObjCommander for ListEditor { } } else { - if let Some(cur_item) = self.get_item_mut() { - drop(cmd_repr); - cur_item.write().unwrap().send_cmd_obj(cmd_obj); - TreeNavResult::Continue + let cur = self.cursor.get(); + + if let Some(idx) = cur.idx { + match cur.mode { + ListCursorMode::Select => { + // what ?? + //*self.data.get_mut(idx as usize) = Arc::new(RwLock::new(node)); + + + + TreeNavResult::Exit + } + ListCursorMode::Insert => { + self.insert( cmd_obj.clone() ); + + // todo: setup edittree + + self.cursor.set(ListCursor{ idx: Some(idx+1), mode: ListCursorMode::Insert }); + TreeNavResult::Continue + } + } } else { TreeNavResult::Exit } } } } - diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs index 0107124..fd9656b 100644 --- a/lib-nested-core/src/editors/list/ctx.rs +++ b/lib-nested-core/src/editors/list/ctx.rs @@ -1,23 +1,14 @@ use { - r3vi::{ - view::{ - ViewPort, port::UpdateTask, - OuterViewPort, Observer, - singleton::*, - list::* - }, - buffer::{singleton::*, vec::*} - }, - laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt, GenericReprTreeMorphism}, - edit_tree::{EditTree}, - editors::{ - char::{CharEditor}, - list::{ListEditor} + edit_tree::EditTree, editors::{ + char::CharEditor, + list::ListEditor + }, repr_tree::{context::TYPEID_char, Context, GenericReprTreeMorphism, ReprLeaf, ReprTree, ReprTreeArc, ReprTreeExt} + }, laddertypes::TypeTerm, r3vi::{ + buffer::{singleton::*, vec::*}, view::{ + list::*, port::UpdateTask, singleton::*, Observer, OuterViewPort, ViewPort } - }, - std::sync::{Arc, RwLock} + }, std::sync::{Arc, RwLock} }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -26,21 +17,21 @@ pub fn init_ctx(ctx: Arc>) { ctx.write().unwrap().add_varname("Item"); let list_morph_editsetup1 = GenericReprTreeMorphism::new( - Context::parse(&ctx, "~~"), + Context::parse(&ctx, "~~"), Context::parse(&ctx, "~EditTree"), { let ctx = ctx.clone(); move |src_rt, σ| { - let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() ); + let item_id = laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Item").unwrap()); if let Some( item_type ) = σ.get( &item_id ) { let mut item_vec_rt = src_rt .descend( - Context::parse(&ctx, "~") + Context::parse(&ctx, "~") .apply_substitution(&|id| σ.get(id).cloned()).clone() ) .expect("cant descend src repr"); - let item_vec_buffer = item_vec_rt.vec_buffer::< Arc> >(); + let item_vec_buffer = item_vec_rt.vec_buffer::< ReprTreeArc >(); let mut list_editor = ListEditor::with_data(ctx.clone(), item_type.clone(), item_vec_buffer); let edittree_list = list_editor.into_node( @@ -62,7 +53,7 @@ pub fn init_ctx(ctx: Arc>) { } } ); - +/* let list_morph_editsetup3 = GenericReprTreeMorphism::new( Context::parse(&ctx, " ~ EditTree"), Context::parse(&ctx, " ~ "), @@ -83,6 +74,46 @@ pub fn init_ctx(ctx: Arc>) { } } ); +*/ + + let list_morph_rt_to_char = GenericReprTreeMorphism::new( + Context::parse(&ctx, " ~ "), + Context::parse(&ctx, ""), + { + let ctx = ctx.clone(); + move |src_rt, σ| { + src_rt.attach_leaf_to( + Context::parse(&ctx, ""), + src_rt.descend(Context::parse(&ctx, "")).expect("cant descend") + .view_list::() + .map(|rt| { + rt.view_singleton::().get_view().get() + }) + ); + } + } + ); + + let list_morph_rt_from_char = GenericReprTreeMorphism::new( + Context::parse(&ctx, ""), + Context::parse(&ctx, " ~ "), + { + let ctx = ctx.clone(); + move |src_rt, σ| { + src_rt.attach_leaf_to( + Context::parse(&ctx, "~"), + src_rt.view_list::() + .map({|c| { + ReprTree::from_singleton_buffer( + TypeTerm::TypeID(TYPEID_char), + SingletonBuffer::::new( *c ) + ) + }}) + ); + } + } + ); + let seq_morph_to_list_char = GenericReprTreeMorphism::new( Context::parse(&ctx, ""), @@ -154,6 +185,22 @@ pub fn init_ctx(ctx: Arc>) { } ); + let list_morph_from_vec_rt = GenericReprTreeMorphism::new( + Context::parse(&ctx, "~"), + Context::parse(&ctx, ""), + { + let ctx = ctx.clone(); + move |src_rt, σ| { + let src_port = src_rt.descend(Context::parse(&ctx, "~")).expect("descend") + .get_port::>>().unwrap(); + + src_rt.attach_leaf_to( Context::parse(&ctx, ""), src_port.to_list() ); + } + } + ); + + + let list_morph_to_vec_edittree = GenericReprTreeMorphism::new( Context::parse(&ctx, ""), @@ -169,12 +216,13 @@ pub fn init_ctx(ctx: Arc>) { ); ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup1 ); - ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup3 ); + ctx.write().unwrap().morphisms.add_morphism( list_morph_rt_to_char ); + ctx.write().unwrap().morphisms.add_morphism( list_morph_rt_from_char ); ctx.write().unwrap().morphisms.add_morphism( list_morph_from_vec_char ); + ctx.write().unwrap().morphisms.add_morphism( list_morph_from_vec_rt ); ctx.write().unwrap().morphisms.add_morphism( seq_morph_to_list_char ); ctx.write().unwrap().morphisms.add_morphism( seq_morph_to_list_u64 ); ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_char ); ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_u64 ); ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_edittree ); } - diff --git a/lib-nested-core/src/editors/list/editor.rs b/lib-nested-core/src/editors/list/editor.rs index 6773891..1afa517 100644 --- a/lib-nested-core/src/editors/list/editor.rs +++ b/lib-nested-core/src/editors/list/editor.rs @@ -1,14 +1,14 @@ use { - r3vi::{ - view::{OuterViewPort, singleton::*, sequence::*}, - buffer::{singleton::*, vec::*}, - projection::* - }, - laddertypes::{TypeTerm}, crate::{ - repr_tree::{Context, ReprTree}, - edit_tree::{EditTree, TreeNav, TreeCursor, diagnostics::Diagnostics}, - editors::{list::{ListCursor, ListCursorMode, ListCmd}, ObjCommander}, + edit_tree::{diagnostics::Diagnostics, EditTree, TreeCursor, TreeNav}, + editors::{list::{ListCmd, ListCursor, ListCursorMode}, ObjCommander}, + repr_tree::{ReprTreeBuilder, context::TYPEID_edittree, node::ReprTreeArc, Context, ReprTree, ReprTreeExt} + }, + laddertypes::TypeTerm, + r3vi::{ + buffer::{singleton::*, vec::*}, + projection::*, + view::{list::*, sequence::*, singleton::*, OuterViewPort} }, std::sync::{Arc, RwLock} }; @@ -17,17 +17,15 @@ use { pub struct ListEditor { pub cursor: SingletonBuffer, - - // todo: (?) remove RwLock<..> around NestedNode ?? - pub data: VecBuffer< Arc> >, - - pub spillbuf: Arc>>>>, + pub data: VecBuffer< ReprTreeArc >, + pub spillbuf: Arc >>, pub(super) addr_port: OuterViewPort>, pub(super) mode_port: OuterViewPort>, depth: OuterViewPort>, + pub item_builder: ReprTreeBuilder, pub ctx: Arc>, /// item type @@ -37,7 +35,7 @@ pub struct ListEditor { impl ListEditor { pub fn new( ctx: Arc>, - typ: TypeTerm + typ: TypeTerm ) -> Self { Self::with_data( ctx, @@ -49,7 +47,7 @@ impl ListEditor { pub fn with_data( ctx: Arc>, typ: TypeTerm, - data: VecBuffer>> + data: VecBuffer< ReprTreeArc > ) -> Self { let cursor = SingletonBuffer::new(ListCursor::default()); @@ -58,6 +56,7 @@ impl ListEditor { .get_port() .map({ let data = data.clone(); + let ctx = ctx.clone(); move |c| { let ip = SingletonBuffer::new(c.mode).get_port(); match c.mode { @@ -65,7 +64,10 @@ impl ListEditor { ListCursorMode::Select => { if let Some(idx) = c.idx { if idx >= 0 && idx < data.len() as isize { - data.get(idx as usize).read().unwrap().get_mode_view() + data.get(idx as usize) + .edittree(&ctx).get() + .read().unwrap() + .get_mode_view() } else { ip } @@ -86,11 +88,15 @@ impl ListEditor { cursor.get_port() .map({ let data = data.clone(); + let ctx = ctx.clone(); move |cur| { if cur.mode == ListCursorMode::Select { if let Some(idx) = cur.idx { if idx >= 0 && idx < data.len() as isize { - return data.get(idx as usize).read().unwrap().get_addr_view(); + return data.get(idx as usize) + .edittree(&ctx).get() + .read().unwrap() + .get_addr_view(); } } } @@ -98,7 +104,7 @@ impl ListEditor { } }) .to_sequence() - .flatten() + .flatten() ]) .get_port() .to_sequence() @@ -106,8 +112,15 @@ impl ListEditor { cursor, data, spillbuf: Arc::new(RwLock::new(Vec::new())), - ctx, + item_builder: ReprTreeBuilder::new(ctx.clone()) + .require( typ.clone() ) + .require( TypeTerm::Ladder(vec![ + typ.clone(), + TypeTerm::TypeID(TYPEID_edittree) + ])) + .clone(), typ, + ctx, depth: SingletonBuffer::new(0).get_port() } } @@ -124,7 +137,7 @@ impl ListEditor { .set_editor(editor.clone()) .set_nav(editor.clone()) .set_cmd(editor.clone()) - .set_diag(e.get_data_port() + .set_diag(e.get_edittree_seq() .enumerate() .map(|(idx, item_editor)| { let idx = *idx; @@ -141,11 +154,17 @@ impl ListEditor { node } + pub fn update_item_reprtrees(&self, master_repr: &TypeTerm) { + for i in 0..self.data.len() { + self.item_builder.update( &self.data.get(i), master_repr.clone() ); + } + } + pub fn get_item_type(&self) -> TypeTerm { self.typ.clone() } - pub fn get_seq_type(&self) -> TypeTerm { + pub fn get_list_type(&self) -> TypeTerm { TypeTerm::App(vec![ TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("List").unwrap()), self.get_item_type().into() @@ -156,10 +175,21 @@ impl ListEditor { self.cursor.get_port() } - pub fn get_data_port(&self) -> OuterViewPort> { - self.data.get_port().to_list().map( - |x| x.read().unwrap().clone() - ).to_sequence() + pub fn get_reprtree_list(&self) -> OuterViewPort> { + self.data.get_port().to_list() + } + + pub fn get_edittree_list(&self) -> OuterViewPort> { + self.get_reprtree_list().map({ + let ctx = self.ctx.clone(); + move|rt| { + rt.edittree(&ctx).get().read().unwrap().clone() + } + }) + } + + pub fn get_edittree_seq(&self) -> OuterViewPort> { + self.get_edittree_list().to_sequence() } /* pub fn get_data(&self) -> Arc> { @@ -170,11 +200,11 @@ impl ListEditor { ) } */ - pub fn get_item(&self) -> Option { + pub fn get_item(&self) -> Option< ReprTreeArc > { if let Some(idx) = self.cursor.get().idx { let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; if idx < self.data.len() { - Some(self.data.get(idx).read().unwrap().clone()) + Some( self.data.get(idx).clone() ) } else { None } @@ -183,7 +213,7 @@ impl ListEditor { } } - pub fn get_item_mut(&mut self) -> Option>>> { + pub fn get_item_mut(&mut 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; if idx < self.data.len() { @@ -196,6 +226,23 @@ impl ListEditor { } } + pub fn get_edittree(&self, idx: usize) -> Arc> { + self.data.get(idx).edittree(&self.ctx).get() + } + + pub fn get_cur_edittree(&self) -> Option< Arc> > { + if let Some(idx) = self.cursor.get().idx { + let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; + if idx < self.data.len() { + Some(self.get_edittree(idx)) + } else { + None + } + } else { + None + } + } + /// is the element-type also a list-like editor (i.e. impls TreeNav) pub fn is_listlist(&self) -> bool { self.ctx.read().unwrap().is_list_type(&self.typ) @@ -207,7 +254,7 @@ impl ListEditor { for i in 0..self.data.len() { b.push( self.data.get(i) ); } - + self.data.clear(); self.cursor.set(ListCursor::home()); } @@ -234,8 +281,9 @@ impl ListEditor { } /// insert a new element - pub fn insert(&mut self, item: Arc>) { - item.read().unwrap().disp.depth.0.set_view( + pub fn insert(&mut self, item: ReprTreeArc) { + let item_edit = item.edittree(&self.ctx).get(); + item_edit.read().unwrap().disp.depth.0.set_view( self.depth.map(|d| d+1).get_view() ); @@ -247,13 +295,13 @@ impl ListEditor { if self.is_listlist() { cur.mode = ListCursorMode::Select; } else { - item.write().unwrap().goto(TreeCursor::none()); + item_edit.write().unwrap().goto(TreeCursor::none()); cur.idx = Some(idx + 1); } } ListCursorMode::Select => { - self.data.insert(1 + idx as usize, item.clone()); + self.data.insert(1 + idx as usize, item.clone()); if self.is_listlist() { cur.idx = Some(idx + 1); } @@ -304,51 +352,41 @@ impl ListEditor { let cur = self.get_cursor(); if let Some(mut item) = self.get_item().clone() { - item.send_cmd_obj(ListCmd::Split.into_repr_tree(&self.ctx)); + let item_edit = item.edittree(&self.ctx).get(); + let mut ie = item_edit.write().unwrap(); + ie.send_cmd_obj(ListCmd::Split.into_repr_tree(&self.ctx)); if cur.tree_addr.len() < 3 { - item.goto(TreeCursor::none()); + ie.goto(TreeCursor::none()); self.set_leaf_mode(ListCursorMode::Insert); self.nexd(); - let mut b = item.ctrl.spillbuf.write().unwrap(); + let mut b = ie.ctrl.spillbuf.write().unwrap(); let rt = ReprTree::new_arc(self.typ.clone()); let mut et = self.ctx.read().unwrap().setup_edittree(&rt); if let Some(edittree) = et.as_mut(){ + let mut tail_node = edittree.get(); + let mut tail_node = tail_node.write().unwrap(); + tail_node.goto(TreeCursor::home()); - let mut tail_node = edittree.get(); - let mut tail_node = tail_node.write().unwrap(); - tail_node.goto(TreeCursor::home()); + for n in b.iter() { + tail_node.send_cmd_obj(n.clone()); + } - for node in b.iter() { - tail_node - .send_cmd_obj( - ReprTree::from_singleton_buffer( - Context::parse(&self.ctx, "EditTree"), - SingletonBuffer::::new( - node.read().unwrap().clone() - ) - ) - ); - } + b.clear(); + drop(b); + drop(item); - b.clear(); - drop(b); - drop(item); - - tail_node.goto(TreeCursor::home()); - if cur.tree_addr.len() > 1 { - tail_node.dn(); - } - drop(tail_node); - - self.insert( - edittree.value.read().unwrap().clone() - ); + tail_node.goto(TreeCursor::home()); + if cur.tree_addr.len() > 1 { + tail_node.dn(); + } + drop(tail_node); + self.insert(rt); } } else { @@ -361,8 +399,8 @@ impl ListEditor { pub fn listlist_join_pxev(&mut self, idx: isize) { { - let cur_editor = self.data.get(idx as usize); - let pxv_editor = self.data.get(idx as usize-1); + let cur_editor = self.data.get(idx as usize).edittree(&self.ctx).get(); + let pxv_editor = self.data.get(idx as usize-1).edittree(&self.ctx).get(); let mut cur_editor = cur_editor.write().unwrap(); let mut pxv_editor = pxv_editor.write().unwrap(); @@ -373,7 +411,7 @@ impl ListEditor { cur_editor.send_cmd_obj( ListCmd::Clear.into_repr_tree( &self.ctx ) ); - + pxv_editor.goto(TreeCursor { tree_addr: vec![-1], leaf_mode: ListCursorMode::Insert @@ -383,14 +421,7 @@ impl ListEditor { let data = cur_editor.ctrl.spillbuf.read().unwrap(); for x in data.iter() { - pxv_editor.send_cmd_obj( - ReprTree::from_singleton_buffer( - Context::parse(&self.ctx, "EditTree"), - SingletonBuffer::::new( - x.read().unwrap().clone() - ) - ) - ); + pxv_editor.send_cmd_obj(x.clone()); } @@ -398,13 +429,13 @@ impl ListEditor { if oc0.tree_addr.len() > 1 { pxv_editor.goto(TreeCursor { tree_addr: vec![ old_cur.tree_addr[0], 0 ], - leaf_mode: ListCursorMode::Insert + leaf_mode: ListCursorMode::Insert }); pxv_editor.send_cmd_obj(ListCmd::DeletePxev.into_repr_tree( &self.ctx )); } else if oc0.tree_addr.len() > 0 { pxv_editor.goto(TreeCursor { tree_addr: vec![ old_cur.tree_addr[0] ], - leaf_mode: ListCursorMode::Insert + leaf_mode: ListCursorMode::Insert }); } } @@ -420,8 +451,8 @@ impl ListEditor { pub fn listlist_join_nexd(&mut self, idx: usize) { { - let cur_editor = self.data.get(idx); - let nxd_editor = self.data.get(idx + 1); + let cur_editor = self.data.get(idx).edittree(&self.ctx).get(); + let nxd_editor = self.data.get(idx + 1).edittree(&self.ctx).get(); let mut cur_editor = cur_editor.write().unwrap(); let mut nxd_editor = nxd_editor.write().unwrap(); @@ -438,25 +469,18 @@ impl ListEditor { tree_addr: vec![-1], leaf_mode: ListCursorMode::Insert }); - + let data = nxd_editor.ctrl.spillbuf.read().unwrap(); for x in data.iter() { - cur_editor.send_cmd_obj( - ReprTree::from_singleton_buffer( - Context::parse(&self.ctx, "EditTree"), - SingletonBuffer::::new( - x.read().unwrap().clone() - ) - ) - ); + cur_editor.send_cmd_obj(x.clone()); } // fixme: is it oc0 or old_cur ?? if oc0.tree_addr.len() > 1 { cur_editor.goto(TreeCursor { tree_addr: vec![ old_cur.tree_addr[0], -1 ], - leaf_mode: ListCursorMode::Insert + leaf_mode: ListCursorMode::Insert }); cur_editor.send_cmd_obj(ListCmd::DeleteNexd.into_repr_tree( &self.ctx )); } else if oc0.tree_addr.len() > 0 { @@ -485,7 +509,7 @@ impl TreeType for ListEditor { let idx = crate::utils::modulo::modulo(addr.0[0] as isize, self.data.len() as isize) as usize; let mut addr = addr.clone(); - + if self.data.len() > 0 { addr.0.remove(0); self.data.get(idx).get_type(addr) @@ -495,5 +519,3 @@ impl TreeType for ListEditor { } } */ - - diff --git a/lib-nested-core/src/editors/list/nav.rs b/lib-nested-core/src/editors/list/nav.rs index b92cc8f..bbef859 100644 --- a/lib-nested-core/src/editors/list/nav.rs +++ b/lib-nested-core/src/editors/list/nav.rs @@ -11,6 +11,7 @@ use { ListCursor, ListCursorMode, editor::ListEditor }, + repr_tree::{ReprTreeExt}, edit_tree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp} }, cgmath::Vector2 @@ -26,7 +27,7 @@ impl TreeNav for ListEditor { fn get_mode_view(&self) -> OuterViewPort> { self.mode_port.clone() } - + fn get_height(&self, op: &TreeHeightOp) -> usize { match op { TreeHeightOp::P | TreeHeightOp::Q => { @@ -35,7 +36,10 @@ impl TreeNav for ListEditor { TreeHeightOp::P => 0, TreeHeightOp::Q => self.data.len() - 1, _ => 0 - }).read().unwrap().get_height(op) + }) + .edittree(&self.ctx).get() + .read().unwrap() + .get_height(op) } else { 1 } @@ -43,7 +47,9 @@ impl TreeNav for ListEditor { TreeHeightOp::Max => { 1 + (0..self.data.len() as usize) .map(|i| self.data - .get(i).read().unwrap() + .get(i) + .edittree(&self.ctx).get() + .read().unwrap() .get_height(&TreeHeightOp::Max) ) .max() @@ -68,7 +74,9 @@ impl TreeNav for ListEditor { ListCursorMode::Select => { if let Some(i) = cur.idx { if i < self.data.len() as isize { - let mut sub_cur = self.data.get(i as usize).read().unwrap().get_cursor_warp(); + let mut sub_cur = self.get_edittree(i as usize) + .read().unwrap() + .get_cursor_warp(); sub_cur.tree_addr.insert(0, i as isize - self.data.len() as isize); return sub_cur; } else { @@ -100,11 +108,11 @@ impl TreeNav for ListEditor { ListCursorMode::Select => { if let Some(i) = cur.idx { if i < self.data.len() as isize { - let mut sub_cur = self.data.get(i as usize).read().unwrap().get_cursor(); + let mut sub_cur = self.get_edittree(i as usize).read().unwrap().get_cursor(); if sub_cur.tree_addr.len() > 0 { sub_cur.tree_addr.insert(0, i as isize); return sub_cur; - } else { + } else { return TreeCursor { leaf_mode: ListCursorMode::Select, tree_addr: vec![ i ], @@ -124,7 +132,7 @@ impl TreeNav for ListEditor { let old_cur = self.cursor.get(); if let Some(i) = old_cur.idx { if i < self.data.len() as isize { - self.data.get_mut(i as usize).write().unwrap().goto(TreeCursor::none()); + self.get_edittree(i as usize).write().unwrap().goto(TreeCursor::none()); } } @@ -145,8 +153,7 @@ impl TreeNav for ListEditor { }); if new_cur.leaf_mode == ListCursorMode::Select && self.data.len() > 0 { - self.data - .get_mut(idx as usize) + self.get_edittree(idx as usize) .write().unwrap() .goto(TreeCursor { leaf_mode: ListCursorMode::Select, @@ -165,8 +172,7 @@ impl TreeNav for ListEditor { idx: Some(idx), }); - self.data - .get_mut(idx as usize) + self.get_edittree(idx as usize) .write().unwrap() .goto(TreeCursor { leaf_mode: new_cur.leaf_mode, @@ -176,7 +182,7 @@ impl TreeNav for ListEditor { self.cursor.set(ListCursor::home()); } - TreeNavResult::Continue + TreeNavResult::Continue } } } @@ -212,8 +218,7 @@ impl TreeNav for ListEditor { // dn if cur.tree_addr[0] < self.data.len() as isize { - if self.data - .get_mut(cur.tree_addr[0] as usize) + if self.get_edittree(cur.tree_addr[0] as usize) .write().unwrap() .goby(Vector2::new(direction.x, direction.y)) == TreeNavResult::Continue { @@ -247,11 +252,10 @@ impl TreeNav for ListEditor { match cur.leaf_mode { ListCursorMode::Select => { - let cur_item = self.data.get(cur.tree_addr[0] as usize); + let cur_item = self.get_edittree(cur.tree_addr[0] as usize); let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::Max); - let new_item = self.data - .get_mut(idx as usize); + let new_item = self.get_edittree(idx as usize); let height = new_item.read().unwrap().get_height( if direction.x < 0 { @@ -277,28 +281,28 @@ impl TreeNav for ListEditor { if direction.x > 0 { if (cur.tree_addr[0] as usize) < self.data.len() { - let cur_item = self.data.get(cur.tree_addr[0] as usize); + let cur_item = self.get_edittree(cur.tree_addr[0] as usize); let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::P); if gravity && cur_height > 1 { new_addr.push( cur.tree_addr[0] ); new_addr.push(0); } else { - new_addr.push( idx ); + new_addr.push( idx ); } } } else { if (idx as usize) < self.data.len() { - let pxv_item = self.data.get(idx as usize); + let pxv_item = self.get_edittree(idx as usize); let pxv_height = pxv_item.read().unwrap().get_height(&TreeHeightOp::P); if gravity && pxv_height > 1 { new_addr.push( idx ); new_addr.push( -1 ); } else { - new_addr.push( idx ); + new_addr.push( idx ); } - } + } } } } @@ -324,10 +328,7 @@ impl TreeNav for ListEditor { // nested if cur.tree_addr[0] < self.data.len() as isize { - - let cur_item = self.data - .get_mut(cur.tree_addr[0] as usize); - + let cur_item = self.get_edittree(cur.tree_addr[0] as usize); let result = cur_item.write().unwrap().goby(direction); match result @@ -353,8 +354,7 @@ impl TreeNav for ListEditor { let mut new_addr = Vec::new(); if direction.x < 0 { - let pxv_item = self.data - .get_mut(cur.tree_addr[0] as usize - 1); + let pxv_item = self.get_edittree(cur.tree_addr[0] as usize - 1); let pxv_height = pxv_item.read().unwrap().get_height(&TreeHeightOp::Q) as isize; let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::P) as isize; @@ -370,10 +370,9 @@ impl TreeNav for ListEditor { for _i in 0..n_steps_down { new_addr.push( -1 ); } - + } else { - let nxd_item = self.data - .get_mut(cur.tree_addr[0] as usize + 1); + let nxd_item = self.get_edittree(cur.tree_addr[0] as usize + 1); let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::Q) as isize; let nxd_height = nxd_item.read().unwrap().get_height(&TreeHeightOp::P) as isize; @@ -422,4 +421,3 @@ impl TreeNav for ListEditor { } } } - diff --git a/lib-nested-core/src/repr_tree/builder.rs b/lib-nested-core/src/repr_tree/builder.rs new file mode 100644 index 0000000..af76b31 --- /dev/null +++ b/lib-nested-core/src/repr_tree/builder.rs @@ -0,0 +1,108 @@ +use { + r3vi::{ + view::{ + ViewPort, OuterViewPort, + AnyViewPort, AnyInnerViewPort, AnyOuterViewPort, + port::UpdateTask, + View, Observer, + singleton::*, + sequence::*, + list::* + }, + buffer::{singleton::*, vec::*} + }, + laddertypes::{TypeTerm, TypeID}, + std::{ + collections::HashMap, + sync::{Arc, RwLock}, + any::Any + }, + super::{Context, ReprLeaf, ReprTree, ReprTreeExt, context::{TYPEID_list, TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree}} +}; + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +#[derive(Clone)] +pub struct ReprTreeBuilder { + ctx: Arc>, + pub required_leaves: Vec, +} + +#[derive(Debug)] +pub enum ReprTreeError { + MissingMorphism +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + +impl ReprTreeBuilder { + pub fn new(ctx: Arc>) -> Self { + ReprTreeBuilder { + ctx, + required_leaves: Vec::new() + } + } + + /// Add a type to the set of required representations. + pub fn require(mut self, t: TypeTerm) -> Self { + self.required_leaves.push(t); + self + } + + /// (re)build steiner tree with `required_leaves`, + /// and apply it to the projections in the ReprTree. + /// Updating and keeping existing nodes, while + /// adding new ones if required. + pub fn update( + &self, + rt: &Arc>, + master_leaf_type: impl Into + ) -> Result< Arc>, ReprTreeError > { + rt.write().unwrap().detach( &self.ctx ); + + let morphism_base = &self.ctx.read().unwrap().morphisms; + + let mt = master_leaf_type.into(); + let mut leaves = self.required_leaves.clone(); + leaves.retain(|t| t != &mt); + + let mut st_problem = laddertypes::steiner_tree::PathApproxSteinerTreeSolver::new( + mt, + leaves + ); + + if let Some( steiner_tree ) = st_problem.solve( &morphism_base ) { + for morphism_type in steiner_tree.into_edges() { + eprintln!("--> morph {} to {}", + self.ctx.read().unwrap().type_term_to_str(&morphism_type.src_type), + self.ctx.read().unwrap().type_term_to_str(&morphism_type.dst_type)); + + if let Some(( morphism, mut τ, σ )) = + morphism_base.find_morphism_with_subtyping( &morphism_type ) + { + let mut rt = rt.descend_create( τ ).expect("descend src repr"); + (morphism.setup_projection)( &mut rt, &σ ); + } else { + eprintln!("failed to get morphism"); + //return Err(ReprTreeError::MissingMorphism); + } + } + + Ok( rt.clone() ) + } else { + eprintln!("could not find steiner tree to build the requested repr tree"); + Err(ReprTreeError::MissingMorphism) + } + } + + /// Build fresh ReprTree from a master representation. + pub fn build_from( + &self, + mut master_rt: Arc> + ) -> Result< Arc>, ReprTreeError > { + let master_leaf_type = master_rt.get_full_type(); + self.update( &ReprTree::rise( master_rt ), master_leaf_type ) + } +} + +//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> diff --git a/lib-nested-core/src/repr_tree/context.rs b/lib-nested-core/src/repr_tree/context.rs index 37f16ae..4ff1f75 100644 --- a/lib-nested-core/src/repr_tree/context.rs +++ b/lib-nested-core/src/repr_tree/context.rs @@ -123,41 +123,9 @@ impl Context { } } else { eprintln!("no path found"); - } - } - - pub fn build_repr_tree( - &self, - rt: &Arc>, - root: TypeTerm, - leaves: Vec< TypeTerm > - ) { - let mut st_problem = laddertypes::steiner_tree::PathApproxSteinerTreeSolver::new( - root, - leaves - ); - - if let Some( steiner_tree ) = st_problem.solve( &self.morphisms ) { - for morphism_type in steiner_tree.into_edges() { - eprintln!("--> apply morph to {}", self.type_term_to_str(&morphism_type.dst_type)); - if let Some(( morphism, mut τ, σ )) = - self.morphisms.find_morphism_with_subtyping( &morphism_type ) - { - let mut rt = rt.descend( τ ).expect("descend src repr"); - (morphism.setup_projection)( &mut rt, &σ ); - } - } - } else { - eprintln!("could not find steiner tree to build the requested repr tree"); } } - pub fn make_repr(ctx: &Arc>, t: &TypeTerm) -> ReprTreeArc { - let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() ))); - ctx.read().unwrap().apply_morphism( &rt, &MorphismType{ src_type: TypeTerm::unit(), dst_type: t.clone() } ); - rt - } - pub fn parse(ctx: &Arc>, s: &str) -> TypeTerm { ctx.read().unwrap().type_term_from_str(s).expect("could not parse type term") } @@ -277,4 +245,3 @@ impl Context { } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - diff --git a/lib-nested-core/src/repr_tree/leaf.rs b/lib-nested-core/src/repr_tree/leaf.rs index 6a12440..a23e65e 100644 --- a/lib-nested-core/src/repr_tree/leaf.rs +++ b/lib-nested-core/src/repr_tree/leaf.rs @@ -50,13 +50,13 @@ impl ReprLeaf { in_keepalive: Some(in_keepalive), in_port: in_port.inner().into(), out_port: out_port.into(), - data: None, + data: None, } } pub fn detach(&mut self) where V: View + ?Sized + 'static, - V::Msg: Clone + V::Msg: Clone { self.keepalive = None; self.in_keepalive = None; @@ -213,4 +213,3 @@ impl ReprLeaf { } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs index e77774f..d4a3b52 100644 --- a/lib-nested-core/src/repr_tree/mod.rs +++ b/lib-nested-core/src/repr_tree/mod.rs @@ -1,5 +1,6 @@ pub mod node; pub mod leaf; +pub mod builder; pub mod context; pub mod morphism; @@ -10,6 +11,7 @@ pub use { context::{Context}, leaf::ReprLeaf, node::{ReprTree, ReprTreeArc}, + builder::{ReprTreeBuilder, ReprTreeError}, morphism::{GenericReprTreeMorphism} }; @@ -34,15 +36,15 @@ use { }, }; -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - pub trait ReprTreeExt { fn get_type(&self) -> TypeTerm; + fn get_full_type(&self) -> TypeTerm; fn insert_leaf(&mut self, type_ladder: impl Into, leaf: ReprLeaf); fn insert_branch(&mut self, repr: Arc>); fn create_branch(&mut self, rung: impl Into); fn descend(&self, target_type: impl Into) -> Option< ReprTreeArc >; + fn descend_create(&self, target_type: impl Into) -> Option< ReprTreeArc >; fn attach_leaf_to(&self, t: impl Into, v: OuterViewPort) where V::Msg: Clone; fn get_port(&self) -> Option> where V::Msg: Clone; @@ -60,7 +62,8 @@ pub trait ReprTreeExt { fn vec_buffer(&self) -> VecBuffer; fn edittree(&self, ctx: &Arc>) -> SingletonBuffer< Arc> > { - self.descend(Context::parse(&ctx, "EditTree")).unwrap() + self.descend_create(Context::parse(&ctx, "EditTree")) + .expect("failed to get EditTree") .singleton_buffer() } } @@ -70,6 +73,10 @@ impl ReprTreeExt for Arc> { self.read().unwrap().get_type().clone() } + fn get_full_type(&self) -> TypeTerm { + self.read().unwrap().get_full_type().clone() + } + 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) } @@ -78,8 +85,8 @@ impl ReprTreeExt for Arc> { self.write().unwrap().insert_branch(repr) } - fn create_branch(&mut self, rung: impl Into) { - let mut lnf = rung.into().get_lnf_vec().into_iter(); + fn create_branch(&mut self, branch: impl Into) { + let mut lnf = branch.into().get_lnf_vec().into_iter(); if let Some(rung) = lnf.next() { let mut parent = ReprTree::new_arc( rung ); self.insert_branch( parent.clone() ); @@ -104,6 +111,10 @@ impl ReprTreeExt for Arc> { ReprTree::descend( self, target_type ) } + fn descend_create(&self, target_type: impl Into)-> Option< ReprTreeArc > { + ReprTree::descend_create( self, target_type ) + } + fn view_char(&self) -> OuterViewPort> { self.read().unwrap().view_char() } @@ -142,4 +153,3 @@ impl ReprTreeExt for Arc> { } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs index fe59b6f..c5e5e8a 100644 --- a/lib-nested-core/src/repr_tree/morphism.rs +++ b/lib-nested-core/src/repr_tree/morphism.rs @@ -80,29 +80,44 @@ impl GenericReprTreeMorphism { lst_map_type.src_type.apply_substitution( &|x| subst.get(x).cloned() ); lst_map_type.dst_type.apply_substitution( &|x| subst.get(x).cloned() ); + lst_map_type = lst_map_type.normalize(); + eprintln!( - "lst map type : {:?}", lst_map_type + "lst map type ::\n {:?}\n===> {:?}\n\n", lst_map_type.src_type, lst_map_type.dst_type ); - let src_port = repr_tree - .descend( lst_map_type.src_type.clone() ) - .expect("descend src seq") - .view_list::(); + + let mut item_ladder = item_morph.morph_type.src_type.clone().get_lnf_vec(); + let top_type = item_ladder.remove( item_ladder.len() - 1 ); - let subst = subst.clone(); - let item_morph = item_morph.clone(); + if let Ok(item_sigma) = laddertypes::unify( + &top_type, + &TypeTerm::App(vec![ + TypeTerm::TypeID( list_typeid ), + TypeTerm::TypeID( TypeID::Var( 200 ) ) + ]) + ) { + eprintln!("List OF List..."); + } else { + let src_port = repr_tree + .descend( lst_map_type.src_type.clone() ) + .expect("descend src seq") + .view_list::(); - let dst_view = src_port.map( + let subst = subst.clone(); + let item_morph = item_morph.clone(); + + let dst_view = src_port.map( move |x| { - let mut item_ladder = item_morph.morph_type.src_type.clone().get_lnf_vec(); let mut item_rt = ReprTree::from_singleton_buffer( - item_ladder.remove( item_ladder.len() - 1 ), - r3vi::buffer::singleton::SingletonBuffer::new(x.clone()) + top_type.clone(), + r3vi::buffer::singleton::SingletonBuffer::new(x.clone()) ); + // TODO: required? - while item_ladder.len() > 0 { - let mut n = ReprTree::new_arc( item_ladder.remove( item_ladder.len() - 1) ); + for t in item_ladder.iter().rev() { + let mut n = ReprTree::new_arc( t.clone() ); n.insert_branch( item_rt ); item_rt = n; } @@ -112,13 +127,14 @@ impl GenericReprTreeMorphism { .view_singleton::< DstItem >() .get_view().unwrap() .get() - } - ); + }); - repr_tree.attach_leaf_to( - lst_map_type.dst_type.clone(), - dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView > - ); + + repr_tree.attach_leaf_to( + lst_map_type.dst_type.clone(), + dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView > + ); + } }) } } @@ -192,16 +208,4 @@ impl GenericReprTreeMorphism { } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -/* -impl MorphismType { - pub fn to_str(&self, ctx: &Context) -> String { - format!("{:?} -> {:?}", - if let Some(t) = self.src_type.as_ref() { - ctx.type_dict.read().unwrap().unparse(t) - } else { - "None".into() - }, - ctx.type_dict.read().unwrap().unparse(&self.dst_type)) - } -} -*/ + diff --git a/lib-nested-core/src/repr_tree/node.rs b/lib-nested-core/src/repr_tree/node.rs index bef682b..c0b34c5 100644 --- a/lib-nested-core/src/repr_tree/node.rs +++ b/lib-nested-core/src/repr_tree/node.rs @@ -1,5 +1,3 @@ - - use { r3vi::{ view::{ @@ -11,7 +9,7 @@ use { sequence::*, list::* }, - buffer::{singleton::*, vec::*} + buffer::{singleton::*, vec::*}, }, laddertypes::{TypeTerm, TypeID}, std::{ @@ -19,7 +17,12 @@ use { sync::{Arc, RwLock}, any::Any }, - super::{Context, ReprLeaf, ReprTreeExt, context::{TYPEID_list, TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree}} + super::{ + Context, + ReprLeaf, + ReprTreeExt, + context::{TYPEID_list, TYPEID_vec, TYPEID_char, TYPEID_u64, TYPEID_edittree} + } }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> @@ -29,28 +32,13 @@ pub struct ReprTree { halo: TypeTerm, type_tag: TypeTerm, branches: HashMap, - leaf: Option< ReprLeaf > + leaf: Option< ReprLeaf >, } pub type ReprTreeArc = Arc>; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> -impl std::fmt::Debug for ReprTree { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "| type: {:?}", self.type_tag)?; - - for (_k,x) in self.branches.iter() { - writeln!(f, "|--> child: {:?}", x)?; - } - writeln!(f, ""); - - Ok(()) - } -} - -//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - impl ReprTree { pub fn new(typ: impl Into) -> Self { let mut lnf = typ.into().get_lnf_vec(); @@ -69,10 +57,33 @@ impl ReprTree { } } + pub fn fmt(&self, ctx: &Arc>, depth: u32) -> String { + let mut s = String::new(); + if( depth == 0 ) { + s.push_str(&format!("{}", ctx.read().unwrap().type_term_to_str(self.get_halo_type()))) + } + s.push_str(&format!("+ {}\n", ctx.read().unwrap().type_term_to_str(&self.type_tag))); + + for (_k,x) in self.branches.iter() { + for _ in 0..depth { + s.push_str(" "); + } + s.push_str(&format!("|--{}", x.read().unwrap().fmt(ctx, depth+1))); + } + s + } + pub fn new_arc(type_tag: impl Into) -> ReprTreeArc { Arc::new(RwLock::new(Self::new(type_tag))) } + pub fn get_full_type(&self) -> TypeTerm { + TypeTerm::Ladder(vec![ + self.halo.clone(), + self.type_tag.clone() + ]).normalize() + } + pub fn get_type(&self) -> &TypeTerm { &self.type_tag } @@ -128,7 +139,10 @@ impl ReprTree { ) } - pub fn from_view( type_tag: impl Into, view: OuterViewPort ) -> ReprTreeArc + pub fn from_view( + type_tag: impl Into, + view: OuterViewPort + ) -> ReprTreeArc where V: View + ?Sized + 'static, V::Msg: Clone { @@ -137,7 +151,10 @@ impl ReprTree { Arc::new(RwLock::new(rt)) } - pub fn from_singleton_buffer( type_tag: impl Into, buf: SingletonBuffer ) -> ReprTreeArc + pub fn from_singleton_buffer( + type_tag: impl Into, + buf: SingletonBuffer + ) -> ReprTreeArc where T: Clone + Send + Sync + 'static { let mut rt = ReprTree::new(type_tag); @@ -145,23 +162,20 @@ impl ReprTree { Arc::new(RwLock::new(rt)) } - pub fn from_str( - type_tag: impl Into, - val: &str - ) -> ReprTreeArc { - let mut lnf = type_tag.into().get_lnf_vec(); - - let mut rt = ReprTree::from_vec_buffer( - lnf.pop().unwrap(), + pub fn from_str(val: &str) -> ReprTreeArc { + ReprTree::from_vec_buffer( + TypeTerm::App(vec![ TypeTerm::TypeID(TYPEID_vec), TypeTerm::TypeID(TYPEID_char) ]), VecBuffer::with_data( val.chars().collect() ) - ); + ) + } + pub fn rise( mut rt: Arc> ) -> Arc> { + let mut lnf = rt.read().unwrap().get_halo_type().clone().get_lnf_vec(); while let Some(t) = lnf.pop() { let mut new_rt = ReprTree::new_arc(t); new_rt.insert_branch(rt); - rt = new_rt; + rt = new_rt } - rt } @@ -198,7 +212,7 @@ impl ReprTree { V::Msg: Clone { while let Some(rung_type) = type_ladder.next() { - if &rung_type != self.get_type() { + if &rung_type != self.get_type() { if let Some(next_repr) = self.branches.get(&rung_type) { next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); } else { @@ -225,7 +239,7 @@ impl ReprTree { leaf.attach_to(src_port); self.leaf = Some(leaf); - } + } else if self.type_tag == TypeTerm::App(vec![ TypeTerm::TypeID(TYPEID_vec), TypeTerm::TypeID(TYPEID_char) @@ -342,7 +356,7 @@ impl ReprTree { //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - pub fn descend_one(&self, dst_type: impl Into) -> Option< ReprTreeArc > { + pub fn descend_rung(&self, dst_type: impl Into) -> Option< ReprTreeArc > { let dst_type = dst_type.into(); assert!( dst_type.is_flat() ); self.branches.get(&dst_type).cloned() @@ -352,7 +366,7 @@ impl ReprTree { if let Some(first) = repr_ladder.next() { let rt = rt.read().unwrap(); repr_ladder.fold( - rt.descend_one(first), + rt.descend_rung(first), |s, t| s?.descend(t)) } else { Some(rt.clone()) @@ -371,25 +385,36 @@ impl ReprTree { } } - pub fn ascend(rt: &Arc>, type_term: impl Into) -> Arc> { + pub fn descend_create( + rt: &Arc>, + dst_type: impl Into + ) -> Option< ReprTreeArc > { + let dst_type = dst_type.into(); + if let Some(branch) = ReprTree::descend(rt, dst_type.clone()) { + Some(branch) + } else { + let branch = ReprTree::new_arc(dst_type); + rt.write().unwrap().insert_branch(branch.clone()); + Some(branch) + } + } + + pub fn ascend(rt: &Arc>, type_term: impl Into) -> ReprTreeArc { let mut n = Self::new(type_term); n.insert_branch(rt.clone()); Arc::new(RwLock::new(n)) } - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ + // Buffer Access \\ + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ pub fn singleton_buffer(&mut self) -> Option> { 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 } } @@ -402,7 +427,10 @@ impl ReprTree { } } - //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> + + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ + // View Access \\ + //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\ pub fn get_port(&self) -> Option> where @@ -455,5 +483,3 @@ impl ReprTree { } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> - - diff --git a/lib-nested-tty/src/editors/list.rs b/lib-nested-tty/src/editors/list.rs index e55172c..cee4284 100644 --- a/lib-nested-tty/src/editors/list.rs +++ b/lib-nested-tty/src/editors/list.rs @@ -43,7 +43,7 @@ impl DisplaySegment for ListSegment { } else { usize::MAX }; - + atom .add_style_back(bg_style_from_depth(select)) .add_style_back(TerminalStyle::bold(select==1)) @@ -70,7 +70,7 @@ impl PTYListStyle { pub fn get_seg_seq_view(&self, editor: &ListEditor) -> OuterViewPort>> { let seg_seq = ListSegmentSequence::new( editor.get_cursor_port(), - editor.get_data_port() + editor.get_edittree_seq() ); let se = seg_seq.read().unwrap(); se.get_view().map(move |segment| segment.display_view()) @@ -79,7 +79,7 @@ impl PTYListStyle { pub fn pty_view(&self, editor: &ListEditor) -> OuterViewPort { let seg_seq = ListSegmentSequence::new( editor.get_cursor_port(), - editor.get_data_port() + editor.get_edittree_seq() ); let seg_seq0 = seg_seq.read().unwrap(); @@ -133,7 +133,7 @@ impl PTYListController { split_char, close_char, depth - } + } } pub fn for_node( @@ -162,17 +162,17 @@ impl PTYListController { } pub fn get_data_port(&self) -> OuterViewPort> { - self.editor.read().unwrap().get_data_port() + self.editor.read().unwrap().get_edittree_seq() } pub fn clear(&mut self) { self.editor.write().unwrap().clear(); } - +/* pub fn get_item(&self) -> Option { self.editor.read().unwrap().get_item() } - +*/ pub fn handle_term_event(&mut self, event: &TerminalEvent, cmd_obj: Arc>) -> TreeNavResult { let mut e = self.editor.write().unwrap(); match event { @@ -247,7 +247,7 @@ impl PTYListController { match ne.send_cmd_obj(cmd_obj.clone()) { TreeNavResult::Continue => { drop(ne); - e.insert(new_edittree.value.read().unwrap().clone()); + e.insert(rt); TreeNavResult::Continue } TreeNavResult::Exit => { @@ -260,7 +260,7 @@ impl PTYListController { } }, ListCursorMode::Select => { - if let Some(item) = e.get_item_mut() { + if let Some(item) = e.get_cur_edittree() { let res = item.write().unwrap().send_cmd_obj(cmd_obj.clone()); let child_close_char = item.read().unwrap().ctrl.close_char.get(); diff --git a/lib-nested-tty/src/lib.rs b/lib-nested-tty/src/lib.rs index 0e12095..022e8f9 100644 --- a/lib-nested-tty/src/lib.rs +++ b/lib-nested-tty/src/lib.rs @@ -127,9 +127,10 @@ pub fn setup_edittree_hook(ctx: &Arc>) { let posint_hex_type = Context::parse(&ctx, ""); let item_tyid = ctx.read().unwrap().get_var_typeid("Item").unwrap(); - ctx.write().unwrap().meta_chars.push(','); - ctx.write().unwrap().meta_chars.push('\"'); - ctx.write().unwrap().meta_chars.push('}'); + ctx.write().unwrap().meta_chars.push('\n'); + //ctx.write().unwrap().meta_chars.push(','); + //ctx.write().unwrap().meta_chars.push('\"'); + //ctx.write().unwrap().meta_chars.push('}'); // Define a hook which is executed when a new editTree of type `t` is created. // this will setup the display and navigation elements of the editor.