From b386fee6eb77352a35ea2775973360f598416a42 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Fri, 25 Aug 2023 04:00:38 +0200 Subject: [PATCH] wip typterm edit; list editor: split using spill buf --- nested/src/editors/list/cmd.rs | 10 +- nested/src/editors/list/editor.rs | 130 ++++++++-------- nested/src/editors/typeterm/mod.rs | 234 ++++++++++++++++++++++++----- nested/src/tree/node.rs | 13 +- 4 files changed, 268 insertions(+), 119 deletions(-) diff --git a/nested/src/editors/list/cmd.rs b/nested/src/editors/list/cmd.rs index e5fcb39..f74c753 100644 --- a/nested/src/editors/list/cmd.rs +++ b/nested/src/editors/list/cmd.rs @@ -35,7 +35,7 @@ impl ListCmd { 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(); @@ -144,12 +144,8 @@ impl ObjCommander for ListEditor { TreeNavResult::Continue } ListCmd::Split => { -/* - self.split(self.spill_node); - */ - self.listlist_split(); - - TreeNavResult::Continue + self.split(); + TreeNavResult::Exit } ListCmd::Clear => { self.clear(); diff --git a/nested/src/editors/list/editor.rs b/nested/src/editors/list/editor.rs index 007955e..95c9287 100644 --- a/nested/src/editors/list/editor.rs +++ b/nested/src/editors/list/editor.rs @@ -1,23 +1,29 @@ use { r3vi::{ - view::{port::UpdateTask, OuterViewPort, singleton::*, sequence::*}, + view::{ChannelSender, ChannelReceiver, port::UpdateTask, OuterViewPort, singleton::*, sequence::*}, buffer::{singleton::*, vec::*} }, crate::{ type_system::{Context, TypeTerm, ReprTree}, - editors::list::{ListCursor, ListCursorMode}, + editors::list::{ListCursor, ListCursorMode, ListCmd}, tree::{NestedNode, TreeNav, TreeCursor}, - diagnostics::Diagnostics + diagnostics::Diagnostics, + commander::ObjCommander }, - std::sync::{Arc, RwLock} + std::sync::{Arc, RwLock, Mutex}, + std::ops::Deref }; //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub struct ListEditor { pub(super) cursor: SingletonBuffer, + + // todo: (?) remove RwLock<..> around NestedNode ?? pub data: VecBuffer< Arc> >, + pub spillbuf: Arc>>>>, + pub(super) addr_port: OuterViewPort>, pub(super) mode_port: OuterViewPort>, @@ -33,7 +39,7 @@ impl ListEditor { typ: TypeTerm, ) -> Self { let cursor = SingletonBuffer::new(ListCursor::default()); - let data = VecBuffer::>>::new(); + let data : VecBuffer>> = VecBuffer::new(); ListEditor { mode_port: cursor @@ -83,8 +89,9 @@ impl ListEditor { .flatten(), cursor, data, + spillbuf: Arc::new(RwLock::new(Vec::new())), ctx, - typ, + typ } } @@ -95,7 +102,7 @@ impl ListEditor { let e = editor.read().unwrap(); - NestedNode::new(ctx, data, depth) + let mut node = NestedNode::new(ctx, data, depth) .set_editor(editor.clone()) .set_nav(editor.clone()) .set_cmd(editor.clone()) @@ -117,7 +124,10 @@ impl ListEditor { } ) .flatten() - ) + ); + + node.spillbuf = e.spillbuf.clone(); + node } pub fn get_item_type(&self) -> TypeTerm { @@ -235,26 +245,18 @@ impl ListEditor { } /// split the list off at the current cursor position and return the second half - pub fn split(&mut self, le_node: &mut NestedNode) { + pub fn split(&mut self) { let cur = self.cursor.get(); if let Some(idx) = cur.idx { let idx = idx as usize; - le_node.goto(TreeCursor::home()); for _ in idx .. self.data.len() { - - eprintln!("send items to new tail"); - le_node.cmd.get().unwrap().write().unwrap().send_cmd_obj( - self.data.get(idx).read().unwrap().data.clone() -/* - ReprTree::new_leaf( - self.ctx.read().unwrap().type_term_from_str("( NestedNode )").unwrap(), - SingletonBuffer::::new( self.data.get(idx).clone().read().unwrap().clone() ).get_port().into() - ) -*/ + self.spillbuf.write().unwrap().push( + self.data.get(idx) ); self.data.remove(idx); } - le_node.goto(TreeCursor::none()); + + /* TODO if self.is_listlist() { if idx > 0 && idx < self.data.len()+1 { @@ -276,7 +278,8 @@ impl ListEditor { } } } - } + } + */ } } @@ -317,53 +320,44 @@ impl ListEditor { pub fn listlist_split(&mut self) { let cur = self.get_cursor(); - if let Some(item) = self.get_item() { -// let item = item.read().unwrap(); - let _depth = item.depth; - - if let Some(head_editor) = item.editor.get() { - eprintln!("listlistsplit:editor = {:?}", Arc::into_raw(head_editor.clone())); + if let Some(mut item) = self.get_item().clone() { + item.send_cmd_obj(ListCmd::Split.into_repr_tree(&self.ctx)); - let head = head_editor.downcast::>().unwrap(); - let mut head = head.write().unwrap(); + let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), 0).unwrap(); + tail_node.goto(TreeCursor::home()); - let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), 0).unwrap(); - - if head.data.len() > 0 { - if cur.tree_addr.len() > 2 { - eprintln!("call child head listlist split"); - head.listlist_split(); - eprintln!("return"); - } - - /* - TODO: replace this by: (does not require ListEditor downcast) - head.send_cmd_obj(ListCmd::Split.into_repr()); - tail_node = head.spill_buf.clone(); - */ - - head.split( &mut tail_node ); - } - - head.goto(TreeCursor::none()); - drop(head); - - tail_node.goto( - TreeCursor { - tree_addr: vec![0], - leaf_mode: if cur.tree_addr.len() > 2 { - ListCursorMode::Select - } else { - ListCursorMode::Insert - } - } - ); - self.insert( - Arc::new(RwLock::new(tail_node)) - ); - - eprintln!("made insert"); + let mut b = item.spillbuf.write().unwrap(); + for node in b.iter() { + tail_node + .send_cmd_obj( + ReprTree::new_leaf( + (&self.ctx, "( NestedNode )"), + SingletonBuffer::::new( + node.read().unwrap().clone() + ).get_port().into() + ) + ); } + b.clear(); + drop(b); + + item.goto(TreeCursor::none()); + drop(item); + + tail_node.goto( + TreeCursor { + tree_addr: vec![0], + leaf_mode: if cur.tree_addr.len() > 2 { + ListCursorMode::Select + } else { + ListCursorMode::Insert + } + } + ); + + self.insert( + Arc::new(RwLock::new(tail_node)) + ); } } @@ -412,6 +406,7 @@ impl ListEditor { self.data.remove(next_idx); } } + /* use crate::{ type_system::TypeLadder, @@ -432,4 +427,5 @@ impl TreeType for ListEditor { } } } -*/ + */ + diff --git a/nested/src/editors/typeterm/mod.rs b/nested/src/editors/typeterm/mod.rs index 9fb84fc..9a646f5 100644 --- a/nested/src/editors/typeterm/mod.rs +++ b/nested/src/editors/typeterm/mod.rs @@ -4,7 +4,7 @@ pub use ctx::init_ctx; use { r3vi::{ - buffer::singleton::*, + buffer::{singleton::*, vec::*}, view::{singleton::*, sequence::*, OuterViewPort} }, crate::{ @@ -13,7 +13,7 @@ use { tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, commander::ObjCommander }, - std::{sync::{Arc, RwLock}, any::Any}, + std::{sync::{Arc, RwLock, Mutex}, any::Any}, cgmath::{Vector2} }; @@ -33,13 +33,9 @@ pub struct TypeTermEditor { ctx: Arc>, data: Arc>, - // forward the editor to the node that references TypeTermEditor - // will be removed once the node includes a spill buffer using which joins can be implemented - editor: SingletonBuffer< - Option< Arc > - >, - + // references to Node pointing to TypeTermEditor close_char: SingletonBuffer>, + spillbuf: Arc>>>>, state: State, cur_node: SingletonBuffer< NestedNode > @@ -110,8 +106,6 @@ impl TypeTermEditor { let int_edit = crate::editors::integer::PosIntEditor::from_u64(parent_ctx, 10, *n as u64); let node = int_edit.into_node(); - - editor.write().unwrap().editor.set(node.editor.get()); editor.write().unwrap().cur_node.set(node); editor.write().unwrap().state = State::Num; } @@ -131,6 +125,8 @@ impl TypeTermEditor { } fn set_state(&mut self, new_state: State) { + eprintln!("TypeEdit: set state to {:?}", new_state); + let old_node = self.cur_node.get(); let mut node = match new_state { @@ -171,15 +167,15 @@ impl TypeTermEditor { node.goto(TreeCursor::home()); let editor = node.editor.get(); - - self.editor.set(editor); self.close_char.set(node.close_char.get()); - self.cur_node.set(node); self.state = new_state; } - pub fn new_node(ctx: Arc>, depth: usize) -> NestedNode { + pub fn new_node(ctx: Arc>, depth: usize) -> NestedNode { + let ctx : Arc> = Arc::new(RwLock::new(Context::with_parent(Some(ctx)))); + ctx.write().unwrap().meta_chars.push('~'); + let mut symb_node = Context::make_node( &ctx, (&ctx, "( List Char )").into(), 0 ).unwrap(); symb_node = symb_node.morph( (&ctx, "( Type::Sym )").into() ); @@ -203,8 +199,9 @@ impl TypeTermEditor { state, data: data.clone(), cur_node: SingletonBuffer::new(node), - editor: SingletonBuffer::new(None), - close_char: SingletonBuffer::new(None) + //editor: SingletonBuffer::new(None), + close_char: SingletonBuffer::new(None), + spillbuf: Arc::new(RwLock::new(Vec::new())) }; let view = editor.cur_node @@ -224,11 +221,28 @@ impl TypeTermEditor { .set_editor(editor.clone()); editor.write().unwrap().close_char = node.close_char.clone(); - editor.write().unwrap().editor = node.editor.clone(); + node.spillbuf = editor.read().unwrap().spillbuf.clone(); node } + fn forward_spill(&mut self) { + eprintln!("forward spill"); + let node = self.cur_node.get(); + let mut buf = node.spillbuf.write().unwrap(); + for n in buf.iter() { + self.spillbuf.write().unwrap().push(n.clone()); + } + buf.clear(); + } + + fn send_child_cmd(&mut self, cmd: Arc>) -> TreeNavResult { + eprintln!("typterm forward cmd"); + let res = self.cur_node.get_mut().send_cmd_obj( cmd ); + self.forward_spill(); + res + } + fn get_typeterm(&self) -> Option { match self.state { State::Any => None, @@ -316,7 +330,7 @@ impl ObjCommander for TypeTermEditor { } '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' => { self.set_state( State::Num ); - self.cur_node.get_mut().send_cmd_obj( co ); + self.send_child_cmd( co ); TreeNavResult::Continue } '\'' => { @@ -329,11 +343,10 @@ impl ObjCommander for TypeTermEditor { _ => { self.set_state( State::AnySymbol ); self.cur_node.get_mut().goto(TreeCursor::home()); - self.cur_node.get_mut().send_cmd_obj( co ) + self.send_child_cmd( co ) } } } - State::Char => { match c { '\'' => { @@ -341,37 +354,181 @@ impl ObjCommander for TypeTermEditor { TreeNavResult::Exit } _ => { - self.cur_node.get_mut().send_cmd_obj( co ) + self.send_child_cmd( co ) } } } - _ => { - match self.cur_node.get_mut().send_cmd_obj( co ) { + State::Ladder => { + eprintln!("have LADDER, send cmd tochild"); + let res = self.send_child_cmd( co ); + let cur = self.get_cursor(); + + match res { + TreeNavResult::Continue => { + if cur.tree_addr.len() == 3 { + match c { + '~' => { + let mut ladder_node = self.cur_node.get().clone(); + let mut ladder_edit = ladder_node.get_edit::().unwrap(); + + let item = ladder_edit.write().unwrap().get_item().clone(); + + if let Some(mut it_node) = item { + if it_node.get_type() == (&self.ctx, "( Type )").into() { + let other_tt = it_node.get_edit::().unwrap(); + let other = other_tt.read().unwrap().cur_node.get().get_edit::().unwrap(); + let buf = other.read().unwrap().data.clone(); + + ladder_edit.write().unwrap().up(); + ladder_edit.write().unwrap().up(); + + ladder_node.send_cmd_obj( + ListCmd::DeleteNexd.into_repr_tree( &self.ctx ) + ); + //ladder_edit.write().unwrap().delete_nexd(); + + let l = buf.len(); + for i in 0..l { + ladder_edit.write().unwrap().insert( buf.get(i) ); + } + ladder_node.dn(); + + TreeNavResult::Continue + } else { + TreeNavResult::Continue + } + } else { + TreeNavResult::Continue + } + } + _=> res + } + } else { + TreeNavResult::Continue + } + } + res => res, + } + } + + State::App => { + let res = self.send_child_cmd( co ); + + match res { TreeNavResult::Exit => { match c { '~' => { - // todo: - - // in case previous item is not ladder - // create new intermediary ladder-node - // with the previous item as one step + // if item at cursor is Ladder + let app_edit = self.cur_node.get().get_edit::().expect("editor"); + let mut app_edit = app_edit.write().unwrap(); + app_edit.delete_nexd(); + app_edit.pxev(); - // in case previous item is ladder - // goto end + if let Some(item_node) = app_edit.get_item() { - eprintln!("TypeEdit: child exit ~"); - } - _ => {} + let item_typterm = item_node.get_edit::().expect("typetermedit"); + let mut item_typterm = item_typterm.write().unwrap(); + match item_typterm.state { + State::Ladder => { + drop(item_typterm); + + app_edit.dn(); + app_edit.qnexd(); + } + _ => { + eprintln!("create new ladder"); + + // else create enw ladder + let mut new_node = Context::make_node( &self.ctx, (&self.ctx, "( List Type )").into(), 0 ).unwrap(); + new_node = new_node.morph( (&self.ctx, "( Type::Ladder )").into() ); + // insert old node and split + new_node.goto(TreeCursor::home()); + + new_node.send_cmd_obj( + ReprTree::new_leaf( + (&self.ctx, "( NestedNode )"), + SingletonBuffer::::new( item_node ).get_port().into() + ) + ); + + drop(item_typterm); + *app_edit.get_item_mut().unwrap().write().unwrap() = new_node; + app_edit.dn(); + } + } + } + + TreeNavResult::Continue + }, + _ => {TreeNavResult::Exit} } + }, + res => res + } + } - TreeNavResult::Exit + State::AnySymbol | State::FunSymbol | State::VarSymbol | State::App => { + let res = self.send_child_cmd( co ); + match res { + TreeNavResult::Exit => { + match c { + '~' => { + eprintln!("typeterm: ~ "); + + let old_node = self.cur_node.get().clone(); + + // create a new NestedNode with TerminaltypeEditor, + // that has same data as current node. + let mut old_edit_node = TypeTermEditor::new_node( self.ctx.clone(), 0 ); + let mut old_edit_clone = old_edit_node.get_edit::().unwrap(); + old_edit_clone.write().unwrap().set_state( self.state ); + old_edit_clone.write().unwrap().close_char.set( old_node.close_char.get() ); + old_edit_clone.write().unwrap().cur_node.set( old_node ); + + // create new list-edit node for the ladder + let mut new_node = Context::make_node( &self.ctx, (&self.ctx, "( List Type )").into(), 0 ).unwrap(); + new_node = new_node.morph( (&self.ctx, "( Type::Ladder )").into() ); + + eprintln!("insert old node into new node"); + + // insert old node and split + new_node.goto(TreeCursor::home()); + new_node.send_cmd_obj( + ReprTree::new_leaf( + (&self.ctx, "( NestedNode )"), + SingletonBuffer::new( old_edit_node ).get_port().into() + ) + ); + + new_node.set_addr(0); + new_node.dn(); + + let res = new_node.send_cmd_obj( + ListCmd::Split.into_repr_tree( &self.ctx ) + ); + + // reconfigure current node to display new_node + self.close_char.set(new_node.close_char.get()); + self.cur_node.set(new_node); + self.state = State::Ladder; + + TreeNavResult::Continue + } + _ => { + TreeNavResult::Exit + } + } } TreeNavResult::Continue => { TreeNavResult::Continue } } } + + _ => { + self.send_child_cmd( co ) + } } } else { TreeNavResult::Exit @@ -379,17 +536,14 @@ impl ObjCommander for TypeTermEditor { } else { match &self.state { State::Any => { - eprintln!("undefined comd object set to ladder"); - self.set_state( State::Ladder ); + self.set_state( State::AnySymbol ); self.cur_node.get_mut().goto(TreeCursor::home()); - let res = self.cur_node.get().cmd.get().unwrap().write().unwrap().send_cmd_obj( co ); - self.cur_node.get_mut().goto(TreeCursor::none()); - res } _ => { - self.cur_node.get().cmd.get().unwrap().write().unwrap().send_cmd_obj( co ) } } + + self.send_child_cmd( co ) } } } diff --git a/nested/src/tree/node.rs b/nested/src/tree/node.rs index f4b3ca3..348b204 100644 --- a/nested/src/tree/node.rs +++ b/nested/src/tree/node.rs @@ -1,9 +1,9 @@ use { - std::{sync::{Arc, RwLock}, any::Any}, + std::{sync::{Arc, RwLock, Mutex}, any::Any}, cgmath::{Vector2, Point2}, r3vi::{ - view::{View, ViewPort, OuterViewPort, AnyOuterViewPort, singleton::*, sequence::*}, - buffer::{singleton::*} + view::{ChannelReceiver, View, ViewPort, OuterViewPort, AnyOuterViewPort, singleton::*, sequence::*}, + buffer::{singleton::*, vec::*} }, crate::{ type_system::{ReprTree, Context, TypeTerm}, @@ -34,7 +34,8 @@ struct NestedNodeEdit { Option< Arc > >, - pub spill_buf: VecBuffer< NestedNode >, + pub input_buf:: VecBuffer< NestedNode >, + pub output_buf: VecBuffer< NestedNode >, /// commander & navigation pub cmd: SingletonBuffer< @@ -91,7 +92,8 @@ pub struct NestedNode { /* TODO: * - spill buffer (contains overflowing elements as well as 'split-off' parts) */ - + pub spillbuf: Arc>>>>, + /// commander & navigation pub cmd: SingletonBuffer< Option< Arc> > @@ -113,6 +115,7 @@ impl NestedNode { diag: None, depth: SingletonBuffer::new(depth), editor: SingletonBuffer::new(None), + spillbuf: Arc::new(RwLock::new(Vec::new())), cmd: SingletonBuffer::new(None), close_char: SingletonBuffer::new(None), tree_nav: SingletonBuffer::new(None)