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 {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
let cmd_repr = cmd_obj.read().unwrap();
if let Some(view) = cmd_repr.get_view::<dyn SingletonView<Item = NestedNode>>() {
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();

View file

@ -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<ListCursor>,
// todo: (?) remove RwLock<..> around 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) mode_port: OuterViewPort<dyn SingletonView<Item = ListCursorMode>>,
@ -33,7 +39,7 @@ impl ListEditor {
typ: TypeTerm,
) -> Self {
let cursor = SingletonBuffer::new(ListCursor::default());
let data = VecBuffer::<Arc<RwLock<NestedNode>>>::new();
let data : VecBuffer<Arc<RwLock<NestedNode>>> = 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::<NestedNode>::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::<RwLock<ListEditor>>().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::<NestedNode>::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 {
}
}
}
*/
*/

View file

@ -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<RwLock<Context>>,
data: Arc<RwLock<ReprTree>>,
// 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<dyn Any + Send + Sync> >
>,
// references to Node pointing to TypeTermEditor
close_char: SingletonBuffer<Option<char>>,
spillbuf: Arc<RwLock<Vec<Arc<RwLock<NestedNode>>>>>,
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<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();
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<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> {
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::<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 => {
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::<ListEditor>().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::<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
}
}
}
_ => {
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 )
}
}
}

View file

@ -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<dyn Any + Send + Sync> >
>,
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<RwLock<Vec<Arc<RwLock<NestedNode>>>>>,
/// commander & navigation
pub cmd: SingletonBuffer<
Option< Arc<RwLock<dyn ObjCommander + Send + Sync>> >
@ -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)