wip typterm edit; list editor: split using spill buf

This commit is contained in:
Michael Sippel 2023-08-25 04:00:38 +02:00
parent bbac1c3d5a
commit b386fee6eb
Signed by: senvas
GPG key ID: F96CF119C34B64A6
4 changed files with 268 additions and 119 deletions

View file

@ -35,7 +35,7 @@ impl ListCmd {
impl ObjCommander for ListEditor { impl ObjCommander for ListEditor {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
let cmd_repr = cmd_obj.read().unwrap(); let cmd_repr = cmd_obj.read().unwrap();
if let Some(view) = cmd_repr.get_view::<dyn SingletonView<Item = NestedNode>>() { if let Some(view) = cmd_repr.get_view::<dyn SingletonView<Item = NestedNode>>() {
let node = view.get(); let node = view.get();
let cur = self.cursor.get(); let cur = self.cursor.get();
@ -144,12 +144,8 @@ impl ObjCommander for ListEditor {
TreeNavResult::Continue TreeNavResult::Continue
} }
ListCmd::Split => { ListCmd::Split => {
/* self.split();
self.split(self.spill_node); TreeNavResult::Exit
*/
self.listlist_split();
TreeNavResult::Continue
} }
ListCmd::Clear => { ListCmd::Clear => {
self.clear(); self.clear();

View file

@ -1,23 +1,29 @@
use { use {
r3vi::{ r3vi::{
view::{port::UpdateTask, OuterViewPort, singleton::*, sequence::*}, view::{ChannelSender, ChannelReceiver, port::UpdateTask, OuterViewPort, singleton::*, sequence::*},
buffer::{singleton::*, vec::*} buffer::{singleton::*, vec::*}
}, },
crate::{ crate::{
type_system::{Context, TypeTerm, ReprTree}, type_system::{Context, TypeTerm, ReprTree},
editors::list::{ListCursor, ListCursorMode}, editors::list::{ListCursor, ListCursorMode, ListCmd},
tree::{NestedNode, TreeNav, TreeCursor}, 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 struct ListEditor {
pub(super) cursor: SingletonBuffer<ListCursor>, pub(super) cursor: SingletonBuffer<ListCursor>,
// todo: (?) remove RwLock<..> around NestedNode ??
pub data: VecBuffer< Arc<RwLock<NestedNode>> >, pub data: VecBuffer< Arc<RwLock<NestedNode>> >,
pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>,
pub(super) addr_port: OuterViewPort<dyn SequenceView<Item = isize>>, pub(super) addr_port: OuterViewPort<dyn SequenceView<Item = isize>>,
pub(super) mode_port: OuterViewPort<dyn SingletonView<Item = ListCursorMode>>, pub(super) mode_port: OuterViewPort<dyn SingletonView<Item = ListCursorMode>>,
@ -33,7 +39,7 @@ impl ListEditor {
typ: TypeTerm, typ: TypeTerm,
) -> Self { ) -> Self {
let cursor = SingletonBuffer::new(ListCursor::default()); let cursor = SingletonBuffer::new(ListCursor::default());
let data = VecBuffer::<Arc<RwLock<NestedNode>>>::new(); let data : VecBuffer<Arc<RwLock<NestedNode>>> = VecBuffer::new();
ListEditor { ListEditor {
mode_port: cursor mode_port: cursor
@ -83,8 +89,9 @@ impl ListEditor {
.flatten(), .flatten(),
cursor, cursor,
data, data,
spillbuf: Arc::new(RwLock::new(Vec::new())),
ctx, ctx,
typ, typ
} }
} }
@ -95,7 +102,7 @@ impl ListEditor {
let e = editor.read().unwrap(); let e = editor.read().unwrap();
NestedNode::new(ctx, data, depth) let mut node = NestedNode::new(ctx, data, depth)
.set_editor(editor.clone()) .set_editor(editor.clone())
.set_nav(editor.clone()) .set_nav(editor.clone())
.set_cmd(editor.clone()) .set_cmd(editor.clone())
@ -117,7 +124,10 @@ impl ListEditor {
} }
) )
.flatten() .flatten()
) );
node.spillbuf = e.spillbuf.clone();
node
} }
pub fn get_item_type(&self) -> TypeTerm { 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 /// 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(); let cur = self.cursor.get();
if let Some(idx) = cur.idx { if let Some(idx) = cur.idx {
let idx = idx as usize; let idx = idx as usize;
le_node.goto(TreeCursor::home());
for _ in idx .. self.data.len() { for _ in idx .. self.data.len() {
self.spillbuf.write().unwrap().push(
eprintln!("send items to new tail"); self.data.get(idx)
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::<NestedNode>::new( self.data.get(idx).clone().read().unwrap().clone() ).get_port().into()
)
*/
); );
self.data.remove(idx); self.data.remove(idx);
} }
le_node.goto(TreeCursor::none());
/* TODO
if self.is_listlist() { if self.is_listlist() {
if idx > 0 && idx < self.data.len()+1 { 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) { pub fn listlist_split(&mut self) {
let cur = self.get_cursor(); let cur = self.get_cursor();
if let Some(item) = self.get_item() { if let Some(mut item) = self.get_item().clone() {
// let item = item.read().unwrap(); item.send_cmd_obj(ListCmd::Split.into_repr_tree(&self.ctx));
let _depth = item.depth;
if let Some(head_editor) = item.editor.get() {
eprintln!("listlistsplit:editor = {:?}", Arc::into_raw(head_editor.clone()));
let head = head_editor.downcast::<RwLock<ListEditor>>().unwrap(); let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), 0).unwrap();
let mut head = head.write().unwrap(); tail_node.goto(TreeCursor::home());
let mut tail_node = Context::make_node(&self.ctx, self.typ.clone(), 0).unwrap(); let mut b = item.spillbuf.write().unwrap();
for node in b.iter() {
if head.data.len() > 0 { tail_node
if cur.tree_addr.len() > 2 { .send_cmd_obj(
eprintln!("call child head listlist split"); ReprTree::new_leaf(
head.listlist_split(); (&self.ctx, "( NestedNode )"),
eprintln!("return"); SingletonBuffer::<NestedNode>::new(
} node.read().unwrap().clone()
).get_port().into()
/* )
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");
} }
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); self.data.remove(next_idx);
} }
} }
/* /*
use crate::{ use crate::{
type_system::TypeLadder, type_system::TypeLadder,
@ -432,4 +427,5 @@ impl TreeType for ListEditor {
} }
} }
} }
*/ */

View file

@ -4,7 +4,7 @@ pub use ctx::init_ctx;
use { use {
r3vi::{ r3vi::{
buffer::singleton::*, buffer::{singleton::*, vec::*},
view::{singleton::*, sequence::*, OuterViewPort} view::{singleton::*, sequence::*, OuterViewPort}
}, },
crate::{ crate::{
@ -13,7 +13,7 @@ use {
tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor}, tree::{NestedNode, TreeNav, TreeNavResult, TreeCursor},
commander::ObjCommander commander::ObjCommander
}, },
std::{sync::{Arc, RwLock}, any::Any}, std::{sync::{Arc, RwLock, Mutex}, any::Any},
cgmath::{Vector2} cgmath::{Vector2}
}; };
@ -33,13 +33,9 @@ pub struct TypeTermEditor {
ctx: Arc<RwLock<Context>>, ctx: Arc<RwLock<Context>>,
data: Arc<RwLock<ReprTree>>, data: Arc<RwLock<ReprTree>>,
// forward the editor to the node that references TypeTermEditor // references to Node pointing to TypeTermEditor
// will be removed once the node includes a spill buffer using which joins can be implemented
editor: SingletonBuffer<
Option< Arc<dyn Any + Send + Sync> >
>,
close_char: SingletonBuffer<Option<char>>, close_char: SingletonBuffer<Option<char>>,
spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>,
state: State, state: State,
cur_node: SingletonBuffer< NestedNode > 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 int_edit = crate::editors::integer::PosIntEditor::from_u64(parent_ctx, 10, *n as u64);
let node = int_edit.into_node(); let node = int_edit.into_node();
editor.write().unwrap().editor.set(node.editor.get());
editor.write().unwrap().cur_node.set(node); editor.write().unwrap().cur_node.set(node);
editor.write().unwrap().state = State::Num; editor.write().unwrap().state = State::Num;
} }
@ -131,6 +125,8 @@ impl TypeTermEditor {
} }
fn set_state(&mut self, new_state: State) { fn set_state(&mut self, new_state: State) {
eprintln!("TypeEdit: set state to {:?}", new_state);
let old_node = self.cur_node.get(); let old_node = self.cur_node.get();
let mut node = match new_state { let mut node = match new_state {
@ -171,15 +167,15 @@ impl TypeTermEditor {
node.goto(TreeCursor::home()); node.goto(TreeCursor::home());
let editor = node.editor.get(); let editor = node.editor.get();
self.editor.set(editor);
self.close_char.set(node.close_char.get()); self.close_char.set(node.close_char.get());
self.cur_node.set(node); self.cur_node.set(node);
self.state = new_state; self.state = new_state;
} }
pub fn new_node(ctx: Arc<RwLock<Context>>, depth: usize) -> NestedNode { pub fn new_node(ctx: Arc<RwLock<Context>>, depth: usize) -> NestedNode {
let ctx : Arc<RwLock<Context>> = 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(); let mut symb_node = Context::make_node( &ctx, (&ctx, "( List Char )").into(), 0 ).unwrap();
symb_node = symb_node.morph( (&ctx, "( Type::Sym )").into() ); symb_node = symb_node.morph( (&ctx, "( Type::Sym )").into() );
@ -203,8 +199,9 @@ impl TypeTermEditor {
state, state,
data: data.clone(), data: data.clone(),
cur_node: SingletonBuffer::new(node), cur_node: SingletonBuffer::new(node),
editor: SingletonBuffer::new(None), //editor: SingletonBuffer::new(None),
close_char: SingletonBuffer::new(None) close_char: SingletonBuffer::new(None),
spillbuf: Arc::new(RwLock::new(Vec::new()))
}; };
let view = editor.cur_node let view = editor.cur_node
@ -224,11 +221,28 @@ impl TypeTermEditor {
.set_editor(editor.clone()); .set_editor(editor.clone());
editor.write().unwrap().close_char = node.close_char.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 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<RwLock<ReprTree>>) -> 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<TypeTerm> { fn get_typeterm(&self) -> Option<TypeTerm> {
match self.state { match self.state {
State::Any => None, State::Any => None,
@ -316,7 +330,7 @@ impl ObjCommander for TypeTermEditor {
} }
'0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' => { '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' => {
self.set_state( State::Num ); self.set_state( State::Num );
self.cur_node.get_mut().send_cmd_obj( co ); self.send_child_cmd( co );
TreeNavResult::Continue TreeNavResult::Continue
} }
'\'' => { '\'' => {
@ -329,11 +343,10 @@ impl ObjCommander for TypeTermEditor {
_ => { _ => {
self.set_state( State::AnySymbol ); self.set_state( State::AnySymbol );
self.cur_node.get_mut().goto(TreeCursor::home()); self.cur_node.get_mut().goto(TreeCursor::home());
self.cur_node.get_mut().send_cmd_obj( co ) self.send_child_cmd( co )
} }
} }
} }
State::Char => { State::Char => {
match c { match c {
'\'' => { '\'' => {
@ -341,37 +354,181 @@ impl ObjCommander for TypeTermEditor {
TreeNavResult::Exit TreeNavResult::Exit
} }
_ => { _ => {
self.cur_node.get_mut().send_cmd_obj( co ) self.send_child_cmd( co )
} }
} }
} }
_ => { State::Ladder => {
match self.cur_node.get_mut().send_cmd_obj( co ) { 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::<ListEditor>().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::<TypeTermEditor>().unwrap();
let other = other_tt.read().unwrap().cur_node.get().get_edit::<ListEditor>().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 => { TreeNavResult::Exit => {
match c { match c {
'~' => { '~' => {
// todo: // if item at cursor is Ladder
let app_edit = self.cur_node.get().get_edit::<ListEditor>().expect("editor");
// in case previous item is not ladder let mut app_edit = app_edit.write().unwrap();
// create new intermediary ladder-node app_edit.delete_nexd();
// with the previous item as one step app_edit.pxev();
// in case previous item is ladder if let Some(item_node) = app_edit.get_item() {
// goto end
eprintln!("TypeEdit: child exit ~"); let item_typterm = item_node.get_edit::<TypeTermEditor>().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::<NestedNode>::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::<TypeTermEditor>().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 => {
TreeNavResult::Continue TreeNavResult::Continue
} }
} }
} }
_ => {
self.send_child_cmd( co )
}
} }
} else { } else {
TreeNavResult::Exit TreeNavResult::Exit
@ -379,17 +536,14 @@ impl ObjCommander for TypeTermEditor {
} else { } else {
match &self.state { match &self.state {
State::Any => { State::Any => {
eprintln!("undefined comd object set to ladder"); self.set_state( State::AnySymbol );
self.set_state( State::Ladder );
self.cur_node.get_mut().goto(TreeCursor::home()); 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 )
} }
} }
} }

View file

@ -1,9 +1,9 @@
use { use {
std::{sync::{Arc, RwLock}, any::Any}, std::{sync::{Arc, RwLock, Mutex}, any::Any},
cgmath::{Vector2, Point2}, cgmath::{Vector2, Point2},
r3vi::{ r3vi::{
view::{View, ViewPort, OuterViewPort, AnyOuterViewPort, singleton::*, sequence::*}, view::{ChannelReceiver, View, ViewPort, OuterViewPort, AnyOuterViewPort, singleton::*, sequence::*},
buffer::{singleton::*} buffer::{singleton::*, vec::*}
}, },
crate::{ crate::{
type_system::{ReprTree, Context, TypeTerm}, type_system::{ReprTree, Context, TypeTerm},
@ -34,7 +34,8 @@ struct NestedNodeEdit {
Option< Arc<dyn Any + Send + Sync> > Option< Arc<dyn Any + Send + Sync> >
>, >,
pub spill_buf: VecBuffer< NestedNode >, pub input_buf:: VecBuffer< NestedNode >,
pub output_buf: VecBuffer< NestedNode >,
/// commander & navigation /// commander & navigation
pub cmd: SingletonBuffer< pub cmd: SingletonBuffer<
@ -91,7 +92,8 @@ pub struct NestedNode {
/* TODO: /* TODO:
* - spill buffer (contains overflowing elements as well as 'split-off' parts) * - spill buffer (contains overflowing elements as well as 'split-off' parts)
*/ */
pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>,
/// commander & navigation /// commander & navigation
pub cmd: SingletonBuffer< pub cmd: SingletonBuffer<
Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> > Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> >
@ -113,6 +115,7 @@ impl NestedNode {
diag: None, diag: None,
depth: SingletonBuffer::new(depth), depth: SingletonBuffer::new(depth),
editor: SingletonBuffer::new(None), editor: SingletonBuffer::new(None),
spillbuf: Arc::new(RwLock::new(Vec::new())),
cmd: SingletonBuffer::new(None), cmd: SingletonBuffer::new(None),
close_char: SingletonBuffer::new(None), close_char: SingletonBuffer::new(None),
tree_nav: SingletonBuffer::new(None) tree_nav: SingletonBuffer::new(None)