wip: Refactor ReprTree; add ReprTreeBuilder

This commit is contained in:
Michael Sippel 2024-12-24 12:50:02 +01:00
parent 41c02465be
commit 26186b3375
Signed by: senvas
GPG key ID: F96CF119C34B64A6
20 changed files with 924 additions and 563 deletions

View file

@ -11,7 +11,7 @@ use {
cgmath::Vector2, cgmath::Vector2,
nested::{ nested::{
editors::ObjCommander, editors::ObjCommander,
repr_tree::{Context, ReprTree, ReprTreeExt}, repr_tree::{Context, ReprTree, ReprTreeExt, ReprTreeBuilder},
edit_tree::{EditTree} edit_tree::{EditTree}
}, },
nested_tty::{ nested_tty::{
@ -39,50 +39,23 @@ async fn main() {
nested_tty::setup_edittree_hook(&ctx); nested_tty::setup_edittree_hook(&ctx);
/* structure of Repr-Tree let digit_builder = ReprTreeBuilder::new( ctx.clone() )
* .require(Context::parse(&ctx, "<Digit 16> ~ _2^64 ~ machine.UInt64"))
* === Repr-Tree === .require(Context::parse(&ctx, "<Digit 16> ~ EditTree"))
* ;
* <Digit 10>
* / | \
* / | \
* / | \
* u64 EditTree Char
* - Editor \
* - Display EditTree
* / | \ - Editor
* / | \ - Display
* TTY PixelBuf SDF / | \
* / | \
* TTY PixelBuf SDF
*/
let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
/* add initial representation /* add initial representation
* <Digit 16> ~ Char * <Digit 16> ~ Char
*/ */
rt_digit.insert_leaf( let mut rt_digit = ReprTree::from_singleton_buffer(
Context::parse(&ctx, "Char"), Context::parse(&ctx, "Char"),
nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') ) SingletonBuffer::new('5')
); );
rt_digit.write().unwrap().set_halo(
/* furthermore, setup projections to and from u8 value, Context::parse(&ctx, "<Digit 16>")
* this synchronizes the buffers
*/
ctx.read().unwrap().apply_morphism(
&rt_digit,
&laddertypes::MorphismType {
src_type: Context::parse(&ctx, "<Digit 16>~Char"),
dst_type: Context::parse(&ctx, "<Digit 16>~_2^64~machine.UInt64")
}
);
ctx.read().unwrap().apply_morphism(
&rt_digit,
&laddertypes::MorphismType {
src_type: Context::parse(&ctx, "<Digit 16>~Char"),
dst_type: Context::parse(&ctx, "<Digit 16>~EditTree")
}
); );
rt_digit = digit_builder.build_from(rt_digit)
.expect("failed to build repr tree");
/* setup terminal /* setup terminal
*/ */

View file

@ -15,7 +15,7 @@ use {
cgmath::Vector2, cgmath::Vector2,
nested::{ nested::{
editors::ObjCommander, editors::ObjCommander,
repr_tree::{Context, ReprTree, ReprTreeExt}, repr_tree::{Context, ReprTree, ReprTreeExt, ReprTreeBuilder},
edit_tree::{EditTree} edit_tree::{EditTree}
}, },
nested_tty::{ nested_tty::{
@ -43,35 +43,45 @@ async fn main() {
/* Create a Representation-Tree of type <List Char> /* Create a Representation-Tree of type <List Char>
*/ */
let mut rt_string = ReprTree::from_str( let mut ldata = VecBuffer::new();
Context::parse(&ctx, "<List Char>~<Vec Char>"), for c in "Hello World!".chars() {
"hello world" 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, "<Vec ReprTree>"),
ldata.clone()
); );
/* create EditTree ldata_rt.write().unwrap().set_halo(
*/ Context::parse(&ctx, "<List Char>~<List ReprTree>")
ctx.read().unwrap().apply_morphism(
&rt_string,
&laddertypes::MorphismType {
src_type: Context::parse(&ctx, "<List~Vec Char>"),
dst_type: Context::parse(&ctx, "<List Char> ~ EditTree")
}
); );
// .. avoid cycle of projections.. let mut ledit = nested::editors::list::ListEditor::with_data(
rt_string.write().unwrap().detach(&ctx); ctx.clone(),
Context::parse(&ctx, "Char"),
/* In order to get access to the values that are modified by the Editor, ldata
* 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, "<List Char>~EditTree"),
dst_type: Context::parse(&ctx, "<List Char>")
}
); );
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, "<List Char>~<Vec Char>"))
.require(Context::parse(&ctx, "<List Char>"))
.require(Context::parse(&ctx, "<List Char>~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. /* Now, get the ListView that serves our char-values.
* This view is a projection created by the morphism that was called above. * This view is a projection created by the morphism that was called above.
@ -81,17 +91,6 @@ async fn main() {
.get_port::<dyn ListView<char>>() .get_port::<dyn ListView<char>>()
.unwrap(); .unwrap();
/* Lets add another morphism which will store the values
* of the character-list in a `Vec<char>`
*/
ctx.read().unwrap().apply_morphism(
&rt_string,
&laddertypes::MorphismType {
src_type: Context::parse(&ctx, "<List Char>"),
dst_type: Context::parse(&ctx, "<List Char>~<Vec Char>")
}
);
/* Access the Vec<char> object (wrapped behind a VecBuffer<char>) /* Access the Vec<char> object (wrapped behind a VecBuffer<char>)
* from the ReprTree. * from the ReprTree.
*/ */
@ -109,7 +108,7 @@ async fn main() {
/* setup terminal /* setup terminal
*/ */
let app = TTYApplication::new({ let app = TTYApplication::new({
let edittree_list = rt_string.edittree(&ctx).clone(); let edittree_list = ledittree.clone();//rt_string.edittree(&ctx).clone();
/* event handler /* event handler
*/ */
@ -137,7 +136,8 @@ async fn main() {
.offset(Vector2::new(1,1))); .offset(Vector2::new(1,1)));
comp.push( comp.push(
rt_string.edittree(&ctx).get() //rt_string.edittree(&ctx).get()
ledittree.get()
.read().unwrap() .read().unwrap()
.display_view() .display_view()
.offset(Vector2::new(3,2))); .offset(Vector2::new(3,2)));
@ -145,6 +145,7 @@ async fn main() {
comp.push( comp.push(
string_view_tty string_view_tty
.offset(Vector2::new(5,3))); .offset(Vector2::new(5,3)));
} }
/* write the changes in the view of `term_port` to the terminal /* write the changes in the view of `term_port` to the terminal

View file

@ -16,7 +16,7 @@ use {
editors::{ editors::{
ObjCommander ObjCommander
}, },
repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, repr_tree::{Context, ReprTreeBuilder, ReprTree, ReprTreeExt, ReprLeaf},
edit_tree::{EditTree, TreeNav, TreeCursor} edit_tree::{EditTree, TreeNav, TreeCursor}
}, },
nested_tty::{ nested_tty::{
@ -46,76 +46,49 @@ async fn main() {
/* Create a Representation-Tree of type `` /* Create a Representation-Tree of type ``
* with a specific representation-path (big-endian hexadecimal string) * with a specific representation-path (big-endian hexadecimal string)
*/ */
let mut rt_int = nested::repr_tree::ReprTree::from_str( let int_builder = ReprTreeBuilder::new( ctx.clone() )
/* TYPE */ .require(Context::parse(&ctx,
" ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char> ~ EditTree"))
/*
.require(Context::parse(&ctx,
" ~ <PosInt 16 LittleEndian> ~ <Seq~List <Digit 16>> ~ EditTree"))
.require(Context::parse(&ctx,
" ~ <PosInt 16 BigEndian> ~ EditTree"))
.require(Context::parse(&ctx,
" ~ <PosInt 8 BigEndian> ~ EditTree"))
.require(Context::parse(&ctx,
" ~ <PosInt 2 BigEndian> ~ EditTree"))
*/
;
let mut rt_int = nested::repr_tree::ReprTree::from_str("cff");
rt_int.write().unwrap().set_halo(
/* HALO TYPE */
Context::parse(&ctx, " Context::parse(&ctx, "
~ <PosInt 16 BigEndian> ~ <PosInt 16 BigEndian>
~ <Seq <Digit 16>> ~ <Seq <Digit 16>>
~ <List <Digit 16>> ~ <List <Digit 16>>
~ <List Char> ~ <List Char>
~ <Vec Char> ")
"),
/* VALUE */
"cff"
); );
/* initially copy values from Vec to EditTree... eprintln!("rt_int = \n{}\n", rt_int.read().unwrap().fmt(&ctx, 0));
*/
ctx.read().unwrap().build_repr_tree(
&rt_int,
Context::parse(&ctx, " ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char> ~ <Vec Char>"),
vec![
Context::parse(&ctx, " ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
Context::parse(&ctx, " ~ <PosInt 16 LittleEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
]);
fn set_master( rt_int = int_builder.build_from( rt_int ).expect("cant build initial repr tree");
ctx: &Arc<RwLock<Context>>,
rt: &Arc<RwLock<ReprTree>>,
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![ eprintln!("rt_int = \n{}\n", rt_int.read().unwrap().fmt(&ctx, 0));
Context::parse(&ctx,
" ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
Context::parse(&ctx,
" ~ <PosInt 16 LittleEndian> ~ <Seq~List <Digit 16>> ~ EditTree"),
Context::parse(&ctx,
" ~ <PosInt 16 BigEndian> ~ EditTree"),
Context::parse(&ctx,
" ~ <PosInt 8 BigEndian> ~ EditTree"),
Context::parse(&ctx,
" ~ <PosInt 2 BigEndian> ~ EditTree"),
];
set_master(&ctx, &rt_int, editor_types.clone(), 0); return;
/* list of editors /* list of editors
*/ */
let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>")); let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>"));
// add all desired editors to the list // add all desired editors to the list
for leaf in editor_types.iter() { for edit_leaf in int_builder.required_leaves {
let et = let leaf_rt = rt_int.descend(edit_leaf.clone()).unwrap();
rt_int list_editor.data.push(leaf_rt);
.descend(leaf.clone()).unwrap()
.edittree(&ctx).get();
et.write().unwrap().goto(TreeCursor::none());
list_editor.data.push(et);
} }
let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port()); let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port());
@ -128,7 +101,7 @@ async fn main() {
tree_addr: vec![0,0] tree_addr: vec![0,0]
}); });
let edittree = Arc::new(RwLock::new(edittree)); let edittree = Arc::new(RwLock::new(edittree));
/* setup terminal /* setup terminal
*/ */
let app = TTYApplication::new({ let app = TTYApplication::new({
@ -137,7 +110,6 @@ async fn main() {
let ctx = ctx.clone(); let ctx = ctx.clone();
let rt_int = rt_int.clone(); let rt_int = rt_int.clone();
let last_idx = RwLock::new(0); let last_idx = RwLock::new(0);
let editor_types = editor_types.clone();
move |ev| { move |ev| {
let cur = edittree.read().unwrap().get_cursor(); let cur = edittree.read().unwrap().get_cursor();
if cur.tree_addr.len() > 0 { if cur.tree_addr.len() > 0 {
@ -145,6 +117,7 @@ async fn main() {
let ci = cur.tree_addr[0]; let ci = cur.tree_addr[0];
if *li != ci { if *li != ci {
/*
eprintln!("----------------------------------"); eprintln!("----------------------------------");
set_master( set_master(
&ctx, &ctx,
@ -152,6 +125,8 @@ async fn main() {
editor_types.clone(), editor_types.clone(),
ci as usize ci as usize
); );
*/
int_builder.update( &rt_int, int_builder.required_leaves[ci as usize].clone() );
*li = ci; *li = ci;
} }
} }
@ -177,7 +152,7 @@ async fn main() {
let halo_type = rt_edittree.read().unwrap().get_halo_type().clone(); let halo_type = rt_edittree.read().unwrap().get_halo_type().clone();
let edittree = rt_edittree.edittree( &ctx ); 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)))) .map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90))))
.offset(Vector2::new(1,y))); .offset(Vector2::new(1,y)));
@ -186,7 +161,7 @@ async fn main() {
} }
let mut y = 1; 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); show_edit_tree(&ctx, &mut comp, &rt_int.descend(t.clone()).expect(""), y);
y += 3; y += 3;
} }
@ -196,4 +171,3 @@ async fn main() {
*/ */
app.show().await.expect("output error!"); app.show().await.expect("output error!");
} }

View file

@ -10,7 +10,7 @@ use {
editors::{ editors::{
ObjCommander ObjCommander
}, },
repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf}, repr_tree::{Context, ReprTreeBuilder, ReprTree, ReprTreeExt, ReprLeaf},
edit_tree::{EditTree, TreeNav, TreeCursor} edit_tree::{EditTree, TreeNav, TreeCursor}
}, },
laddertypes::{ 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_u64_to_str );
ctx.write().unwrap().morphisms.add_morphism( symbol_morph_str_to_u64 ); ctx.write().unwrap().morphisms.add_morphism( symbol_morph_str_to_u64 );
let mut symbol_rt = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, " let mut symbol_rt = nested::repr_tree::ReprTree::from_str("Call");
Instruction ~ Mnemonic ~ <Seq~List~Vec Char> symbol_rt.write().unwrap().set_halo(Context::parse(&ctx, "
"), Instruction ~ Mnemonic ~ <Seq~List Char>
"Call" "));
);
// this is required to initialize the <Vec EditTree> representation, let symbol_builder = ReprTreeBuilder::new( ctx.clone() )
// and to take the value from <Vec Char> //.require(Context::parse(&ctx, "Instruction ~ Opcode ~ ~ <PosInt 10 BigEndian> ~ EditTree"))
ctx.read().unwrap().build_repr_tree( .require(Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List Char> ~ EditTree"))
&symbol_rt, ;
Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List~Vec Char>"),
vec![
Context::parse(&ctx, "Instruction ~ Opcode ~ ~ <PosInt 10 BigEndian> ~ EditTree"),
Context::parse(&ctx, "Instruction ~ Mnemonic ~ <Seq~List Char> ~ 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<RwLock<Context>>,
rt: &Arc<RwLock<ReprTree>>,
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 ~ <Seq~List Char> ~ EditTree"),
Context::parse(&ctx,
"Instruction ~ Opcode ~ ~ <PosInt 10 BigEndian> ~ EditTree"),
Context::parse(&ctx,
"Instruction ~ Opcode ~ ~ <PosInt 16 BigEndian> ~ EditTree"),
];
set_master(&ctx, &symbol_rt, editor_types.clone(), 0);
let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>")); let mut list_editor = nested::editors::list::ListEditor::new(ctx.clone(), Context::parse(&ctx, "<Seq Char>"));
// add all desired editors to the list // add all desired editors to the list
for leaf in editor_types.iter() { for edit_leaf in symbol_builder.required_leaves {
let et = let leaf_rt = symbol_rt.descend(edit_leaf.clone()).unwrap();
symbol_rt list_editor.data.push(leaf_rt);
.descend(leaf.clone()).unwrap()
.edittree(&ctx).get();
et.write().unwrap().goto(TreeCursor::none());
list_editor.data.push(et);
} }
let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port()); let mut edittree = list_editor.into_node(SingletonBuffer::new(0).get_port());
@ -233,7 +195,6 @@ async fn main() {
let ctx = ctx.clone(); let ctx = ctx.clone();
let symbol_rt = symbol_rt.clone(); let symbol_rt = symbol_rt.clone();
let last_idx = RwLock::new(0); let last_idx = RwLock::new(0);
let editor_types = editor_types.clone();
move |ev| { move |ev| {
let cur = edittree.read().unwrap().get_cursor(); let cur = edittree.read().unwrap().get_cursor();
if cur.tree_addr.len() > 0 { if cur.tree_addr.len() > 0 {
@ -241,13 +202,7 @@ async fn main() {
let ci = cur.tree_addr[0]; let ci = cur.tree_addr[0];
if *li != ci { if *li != ci {
eprintln!("----------------------------------"); // symbol_builder.update()
set_master(
&ctx,
&symbol_rt,
editor_types.clone(),
ci as usize
);
*li = ci; *li = ci;
} }
} }

View file

@ -32,16 +32,20 @@ struct LineDiagnostic {
msg: String msg: String
} }
struct LineEditor {
num_buf: SingletonBuffer< u64 >,
diag_buf: VecBuffer< LineDiagnostic >,
chars_edit: Arc<RwLock<ListEditor>>,
out_port: ViewPort< dyn TerminalView >,
view: Arc<RwLock< LineView >>,
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>,
}
struct LineView { struct LineView {
line_num: Arc< dyn SingletonView<Item = u64> >, line_num: Arc< dyn SingletonView<Item = u64> >,
segments: Arc< dyn SequenceView<Item = ListSegment> >, segments: Arc< dyn SequenceView<Item = ListSegment> >,
diagnostics: Arc< dyn SequenceView<Item = LineDiagnostic> >, diagnostics: Arc< dyn SequenceView<Item = LineDiagnostic> >,
proj_helper: ProjectionHelper<usize, LineEditor>
diag_buf: VecBuffer< LineDiagnostic >,
cast: Arc<RwLock<ObserverBroadcast<dyn TerminalView>>>,
out_port: OuterViewPort<dyn TerminalView>,
proj_helper: ProjectionHelper<usize, Self>
} }
impl View for LineView { impl View for LineView {
@ -121,10 +125,9 @@ impl IndexView<Point2<i16>> for LineView {
while n > 0 { n_digits += 1; n /= 10; } 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); let diag_len = self.diagnostics.iter().map(|d| d.msg.chars().count() as i16).max().unwrap_or(0);
IndexArea::Range( IndexArea::Range(
Point2::new( xoff -1-n_digits , 0) ..= Point2::new( xoff - n_digits - 1 , 0) ..=
Point2::new( Point2::new(
xoff+ xoff + i16::max(
i16::max(
self.segments.len().unwrap_or(i16::MAX as usize) as i16, self.segments.len().unwrap_or(i16::MAX as usize) as i16,
diag_len diag_len
), ),
@ -134,57 +137,72 @@ impl IndexView<Point2<i16>> for LineView {
} }
} }
impl LineView { impl LineEditor {
pub fn new( pub fn new(
ctx: &Arc<RwLock<Context>>,
n: u64, n: u64,
le: &ListEditor,
) -> Arc<RwLock<Self>> { ) -> Arc<RwLock<Self>> {
let line_num_buf = SingletonBuffer::new(n); let num_buf = SingletonBuffer::new(n);
let diag_buf = VecBuffer::new(); 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, "<List Char>")
);
let chars_seg_seq = ListSegmentSequence::new(chars_edit.get_cursor_port(), chars_edit.get_data_port())
.read().unwrap().get_view(); .read().unwrap().get_view();
let out_port = ViewPort::new(); let out_port = ViewPort::new();
let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone());
let lv = Arc::new(RwLock::new(LineView{ let mut proj_helper = ProjectionHelper::new(out_port.update_hooks.clone());
line_num: proj_helper.new_singleton_arg(0, line_num_buf.get_port(), let line_view = Arc::new(RwLock::new(LineView {
|s: &mut LineView, _msg|{ line_num: proj_helper.new_singleton_arg(0, num_buf.get_port(),
s.cast.write().unwrap() |e: &mut LineEditor, _msg|{
e.cast.write().unwrap()
.notify(&IndexArea::Range( .notify(&IndexArea::Range(
(Point2::new(-100, 0) ..= Point2::new(0, 0)) (Point2::new(-100, 0) ..= Point2::new(0, 0))
)); ));
}), }),
segments: proj_helper.new_sequence_arg(1, seg_seq, segments: proj_helper.new_sequence_arg(1, chars_seg_seq,
|s: &mut LineView, idx| { |e: &mut LineEditor, idx| {
s.cast.write().unwrap() e.cast.write().unwrap()
.notify(&IndexArea::Range( .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(), diagnostics: proj_helper.new_sequence_arg(2, diag_buf.get_port().to_sequence(),
|s: &mut LineView, idx| { |e: &mut LineEditor, idx| {
s.cast.write().unwrap() e.cast.write().unwrap()
.notify(&IndexArea::Range( .notify(&IndexArea::Range(
(Point2::new(-100, 1+*idx as i16) ..= Point2::new(100, 1+*idx as i16)) (Point2::new(-100, 1+*idx as i16) ..= Point2::new(100, 1+*idx as i16))
)); ));
}), }),
diag_buf,
cast: out_port.inner().get_broadcast(),
proj_helper, proj_helper,
out_port: out_port.outer()
})); }));
lv.write().unwrap().proj_helper.set_proj(&lv); let line_edit = Arc::new(RwLock::new(LineEditor {
out_port.inner().set_view(Some(lv.clone())); 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<dyn TerminalView> { pub fn get_port(&self) -> OuterViewPort<dyn TerminalView> {
self.out_port.clone() self.out_port.outer()
} }
} }
@ -205,6 +223,11 @@ impl LinesEditor {
Context::parse(&ctx, "Line ~ EditTree"), Context::parse(&ctx, "Line ~ EditTree"),
|rt, σ| { |rt, σ| {
eprintln!("LINE EDITOR CONSTRUCT"); eprintln!("LINE EDITOR CONSTRUCT");
/*
rt.insert_branch(
Context::parse(&ctx, "EditTree"),
)*/
} }
); );
ctx.write().unwrap().morphisms.add_morphism( line_to_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 ); let mut list_edit = list_edit.into_node( depth_port );
nested_tty::editors::list::PTYListController::for_node( &mut list_edit, Some('\n'), None ); nested_tty::editors::list::PTYListController::for_node( &mut list_edit, Some('\n'), None );
list_edit.disp.view list_edit.disp.view.write().unwrap()
.write().unwrap() .insert_branch(ReprTree::from_view(
.insert_branch(ReprTree::from_view( Context::parse(&ctx, "TerminalView"),
Context::parse(&ctx, "TerminalView"), lines_view
lines_view ));
));
LinesEditor { LinesEditor {
// lines, // lines,
@ -258,26 +280,34 @@ impl LinesEditor {
.read().unwrap() .read().unwrap()
.data.len() as u64; .data.len() as u64;
let line = let depth = SingletonBuffer::new(0).get_port();
self.make_line(line_value)
.descend(Context::parse(&self.ctx, "EditTree")).unwrap()
.edittree(&self.ctx).get();
let le = line.read().unwrap().get_edit::<ListEditor>().unwrap(); let chars_rt = self.make_line(line_value);
le.write().unwrap().goto(TreeCursor::none()); 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(); let line = LineEditor::new(&self.ctx, n);
line.write().unwrap().disp.view line.write().unwrap().chars_edit = chars_edittree.get_edit::<ListEditor>().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( .insert_leaf(
Context::parse(&self.ctx, "TerminalView"), Context::parse(&self.ctx, "TerminalView"),
ReprLeaf::from_view( lvport ) ReprLeaf::from_view( line_port )
); );
self.edit.write().unwrap() self.edit.write().unwrap()
.get_edit::< ListEditor >().unwrap() .get_edit::< ListEditor >().unwrap()
.write().unwrap() .write().unwrap()
.data .data
.push(line); .push( Arc::new(RwLock::new(line_edittree)) );
} }
pub fn make_line(&self, line_value: &str) -> Arc<RwLock<ReprTree>> { pub fn make_line(&self, line_value: &str) -> Arc<RwLock<ReprTree>> {
@ -287,6 +317,7 @@ impl LinesEditor {
line_value line_value
); );
// create Editor & transfer data to Editor
ctx.read().unwrap().apply_morphism( ctx.read().unwrap().apply_morphism(
&rt_line, &rt_line,
&laddertypes::MorphismType { &laddertypes::MorphismType {

View file

@ -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"]

View file

@ -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 = {:?}, <Vec EditTree> = {:?}",
Context::parse(&ctx, "Char"),
Context::parse(&ctx, "machine.UInt64"),
Context::parse(&ctx, "EditTree"),
Context::parse(&ctx, "<Vec EditTree>")
);
let mut red = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, "
~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ <Vec Char>
"),
"221"
);
ctx.read().unwrap().apply_morphism( &red,
&laddertypes::MorphismType {
src_type: Context::parse(&ctx, " ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char > ~ <Vec Char>"),
dst_type: Context::parse(&ctx, "~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > ~ EditTree")
});
let red_edit = ctx.read().unwrap().setup_edittree(
red.descend(Context::parse(&ctx, "
~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>
")).unwrap(),
SingletonBuffer::new(0).get_port()
).unwrap();
let mut green = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, "
~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ <Vec Char>
"),
"220"
);
ctx.read().unwrap().apply_morphism( &green,
&laddertypes::MorphismType {
src_type: Context::parse(&ctx, " ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char > ~ <Vec Char>"),
dst_type: Context::parse(&ctx, "~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > ~ EditTree")
});
let green_edit = ctx.read().unwrap().setup_edittree(green.descend(Context::parse(&ctx, "
~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>
")).unwrap(),
SingletonBuffer::new(0).get_port()
).unwrap();
let mut blue = nested::repr_tree::ReprTree::from_str(Context::parse(&ctx, "
~ <PosInt 10 BigEndian> ~ <Seq <Digit 10>> ~ <List <Digit 10> ~ Char> ~ <Vec Char>
"),
"5"
);
ctx.read().unwrap().apply_morphism( &blue,
&laddertypes::MorphismType {
src_type: Context::parse(&ctx, " ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char > ~ <Vec Char>"),
dst_type: Context::parse(&ctx, "~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > ~ EditTree")
});
let blue_edit = ctx.read().unwrap().setup_edittree(
blue.descend(Context::parse(&ctx, "
~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~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, "<List >")
);
color.insert_leaf(
Context::parse(&ctx, "
<List
~ <PosInt 16 BigEndian>
~ <Seq <Digit 16>>
~ <List <Digit 16>
~ Char >
>
~ <List EditTree>
~ <Vec EditTree>
"),
ReprLeaf::from_vec_buffer(VecBuffer::<
Arc<RwLock< EditTree >>
>::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, "<List ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > ~ EditTree > ~ <Vec EditTree>"),
dst_type: Context::parse(&ctx, "<List ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > > ~ EditTree")
});
let edit = ctx.read().unwrap().setup_edittree(
color.descend(Context::parse(&ctx, "
<List
~ < PosInt 16 BigEndian >
~ < Seq~List <Digit 16>
~ 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, "<List ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > > ~ EditTree"),
dst_type: Context::parse(&ctx, "<List ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char > >")
});
eprintln!("list char ==> list u64");
ctx.read().unwrap().apply_morphism(
&color,
&laddertypes::MorphismType {
src_type: Context::parse(&ctx, "<List ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ Char>>"),
dst_type: Context::parse(&ctx, "<List ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ _2^64 ~ machine.UInt64>>")
});
return;
ctx.read().unwrap().apply_morphism(
&color,
&laddertypes::MorphismType {
src_type: Context::parse(&ctx, "<List ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16> ~ _2^64 ~ machine.UInt64 > >"),
dst_type: Context::parse(&ctx, "<List ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10> ~ Char > >")
});
/*
let edit2 = ctx.read().unwrap().setup_edittree(
color.descend(Context::parse(&ctx, "
<List
~ < PosInt 10 BigEndian >
~ < Seq~List <Digit 10>
~ 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<RwLock<Context>>, comp: &mut TerminalCompositor, rt: &Arc<RwLock<ReprTree>>, 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::<dyn r3vi::view::singleton::SingletonView<Item = Arc<RwLock<EditTree>>>>().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, "<List ~ <PosInt 16 BigEndian> ~ <Seq~List <Digit 16>~Char>>")).unwrap(), 1 );
show_edit_tree( &ctx, &mut comp, &color.descend(Context::parse(&ctx, "<List ~ <PosInt 10 BigEndian> ~ <Seq~List <Digit 10>~Char>>")).unwrap(), 3 );
}
/* write the changes in the view of `term_port` to the terminal
*/
app.show().await.expect("output error!");
}

View file

@ -7,7 +7,7 @@ use {
}, },
laddertypes::{TypeTerm}, laddertypes::{TypeTerm},
crate::{ crate::{
repr_tree::{ReprTree, Context}, repr_tree::{ReprTree, ReprTreeArc, Context},
edit_tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}}, edit_tree::{TreeNav, TreeCursor, TreeNavResult, TreeHeightOp, diagnostics::{Diagnostics, Message}},
editors::{list::{ListCursorMode}, ObjCommander} editors::{list::{ListCursorMode}, ObjCommander}
} }
@ -32,9 +32,7 @@ pub struct EdittreeControl {
Option< Arc<dyn Any + Send + Sync> > Option< Arc<dyn Any + Send + Sync> >
>, >,
pub spillbuf: Arc<RwLock< pub spillbuf: Arc<RwLock< Vec< ReprTreeArc > >>,
Vec< Arc<RwLock< EditTree >> >
>>,
/// commander & navigation /// commander & navigation
pub cmd: SingletonBuffer< pub cmd: SingletonBuffer<
@ -46,7 +44,7 @@ pub struct EdittreeControl {
// could be replaced by cmd when TreeNav -CmdObjects are used // could be replaced by cmd when TreeNav -CmdObjects are used
pub tree_nav: SingletonBuffer< pub tree_nav: SingletonBuffer<
Option< Arc<RwLock<dyn TreeNav + Send + Sync>> > Option< Arc<RwLock<dyn TreeNav + Send + Sync>> >
>, >,
} }
#[derive(Clone)] #[derive(Clone)]
@ -153,7 +151,7 @@ impl TreeNav for EditTree {
tn.read().unwrap().get_mode_view() tn.read().unwrap().get_mode_view()
} else { } else {
OuterViewPort::default() OuterViewPort::default()
} }
} }
fn get_cursor_warp(&self) -> TreeCursor { fn get_cursor_warp(&self) -> TreeCursor {
@ -225,4 +223,3 @@ impl Diagnostics for EditTree {
self.get_diag() self.get_diag()
} }
} }

View file

@ -25,7 +25,7 @@ impl ListCmd {
// note: cant use Into becaue of ctx (maybe global typedict?) // note: cant use Into becaue of ctx (maybe global typedict?)
pub fn into_repr_tree(self, ctx: &Arc<RwLock<Context>>) -> Arc<RwLock<ReprTree>> { pub fn into_repr_tree(self, ctx: &Arc<RwLock<Context>>) -> Arc<RwLock<ReprTree>> {
ReprTree::from_singleton_buffer( ReprTree::from_singleton_buffer(
Context::parse(ctx, "ListCmd"), Context::parse(ctx, "ListCmd"),
r3vi::buffer::singleton::SingletonBuffer::new(self) r3vi::buffer::singleton::SingletonBuffer::new(self)
) )
} }
@ -35,28 +35,7 @@ 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 = EditTree>>() { if let Some(cmd) = cmd_repr.get_view::<dyn SingletonView<Item = ListCmd>>() {
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::<dyn SingletonView<Item = ListCmd>>() {
let cur = self.cursor.get(); let cur = self.cursor.get();
drop(cmd_repr); drop(cmd_repr);
@ -69,10 +48,11 @@ impl ObjCommander for ListEditor {
_ => { _ => {
if let Some(idx) = cur.idx { if let Some(idx) = cur.idx {
match cur.mode { match cur.mode {
ListCursorMode::Select => { ListCursorMode::Select => {
if let Some(mut item) = self.get_item().clone() { if let Some(mut item) = self.get_cur_edittree() {
let mut item = item.write().unwrap();
let item_cur = item.get_cursor(); let item_cur = item.get_cursor();
match cmd.get() { match cmd.get() {
ListCmd::DeletePxev => { ListCmd::DeletePxev => {
if idx > 0 if idx > 0
@ -151,14 +131,30 @@ impl ObjCommander for ListEditor {
} }
} else { } else {
if let Some(cur_item) = self.get_item_mut() { let cur = self.cursor.get();
drop(cmd_repr);
cur_item.write().unwrap().send_cmd_obj(cmd_obj); if let Some(idx) = cur.idx {
TreeNavResult::Continue 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 { } else {
TreeNavResult::Exit TreeNavResult::Exit
} }
} }
} }
} }

View file

@ -1,23 +1,14 @@
use { use {
r3vi::{
view::{
ViewPort, port::UpdateTask,
OuterViewPort, Observer,
singleton::*,
list::*
},
buffer::{singleton::*, vec::*}
},
laddertypes::{TypeTerm},
crate::{ crate::{
repr_tree::{Context, ReprTree, ReprLeaf, ReprTreeExt, GenericReprTreeMorphism}, edit_tree::EditTree, editors::{
edit_tree::{EditTree}, char::CharEditor,
editors::{ list::ListEditor
char::{CharEditor}, }, repr_tree::{context::TYPEID_char, Context, GenericReprTreeMorphism, ReprLeaf, ReprTree, ReprTreeArc, ReprTreeExt}
list::{ListEditor} }, 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<RwLock<Context>>) {
ctx.write().unwrap().add_varname("Item"); ctx.write().unwrap().add_varname("Item");
let list_morph_editsetup1 = GenericReprTreeMorphism::new( let list_morph_editsetup1 = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<List Item>~<List EditTree>~<Vec EditTree>"), Context::parse(&ctx, "<List Item>~<List ReprTree>~<Vec ReprTree>"),
Context::parse(&ctx, "<List Item>~EditTree"), Context::parse(&ctx, "<List Item>~EditTree"),
{ {
let ctx = ctx.clone(); let ctx = ctx.clone();
move |src_rt, σ| { 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 ) { if let Some( item_type ) = σ.get( &item_id ) {
let mut item_vec_rt = src_rt let mut item_vec_rt = src_rt
.descend( .descend(
Context::parse(&ctx, "<List Item~EditTree>~<Vec EditTree>") Context::parse(&ctx, "<List ReprTree>~<Vec ReprTree>")
.apply_substitution(&|id| σ.get(id).cloned()).clone() .apply_substitution(&|id| σ.get(id).cloned()).clone()
) )
.expect("cant descend src repr"); .expect("cant descend src repr");
let item_vec_buffer = item_vec_rt.vec_buffer::< Arc<RwLock<EditTree>> >(); 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 mut list_editor = ListEditor::with_data(ctx.clone(), item_type.clone(), item_vec_buffer);
let edittree_list = list_editor.into_node( let edittree_list = list_editor.into_node(
@ -62,7 +53,7 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
} }
} }
); );
/*
let list_morph_editsetup3 = GenericReprTreeMorphism::new( let list_morph_editsetup3 = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<List Item> ~ EditTree"), Context::parse(&ctx, "<List Item> ~ EditTree"),
Context::parse(&ctx, "<List Item> ~ <List EditTree>"), Context::parse(&ctx, "<List Item> ~ <List EditTree>"),
@ -83,6 +74,46 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
} }
} }
); );
*/
let list_morph_rt_to_char = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<List Char> ~ <List ReprTree>"),
Context::parse(&ctx, "<List Char>"),
{
let ctx = ctx.clone();
move |src_rt, σ| {
src_rt.attach_leaf_to(
Context::parse(&ctx, "<List Char>"),
src_rt.descend(Context::parse(&ctx, "<List ReprTree>")).expect("cant descend")
.view_list::<ReprTreeArc>()
.map(|rt| {
rt.view_singleton::<char>().get_view().get()
})
);
}
}
);
let list_morph_rt_from_char = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<List Char>"),
Context::parse(&ctx, "<List Char> ~ <List ReprTree>"),
{
let ctx = ctx.clone();
move |src_rt, σ| {
src_rt.attach_leaf_to(
Context::parse(&ctx, "<List Char>~<List ReprTree>"),
src_rt.view_list::<char>()
.map({|c| {
ReprTree::from_singleton_buffer(
TypeTerm::TypeID(TYPEID_char),
SingletonBuffer::<char>::new( *c )
)
}})
);
}
}
);
let seq_morph_to_list_char = GenericReprTreeMorphism::new( let seq_morph_to_list_char = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<Seq Char>"), Context::parse(&ctx, "<Seq Char>"),
@ -154,6 +185,22 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
} }
); );
let list_morph_from_vec_rt = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<List ReprTree>~<Vec ReprTree>"),
Context::parse(&ctx, "<List ReprTree>"),
{
let ctx = ctx.clone();
move |src_rt, σ| {
let src_port = src_rt.descend(Context::parse(&ctx, "<List ReprTree>~<Vec ReprTree>")).expect("descend")
.get_port::<RwLock<Vec<ReprTreeArc>>>().unwrap();
src_rt.attach_leaf_to( Context::parse(&ctx, "<List ReprTree>"), src_port.to_list() );
}
}
);
let list_morph_to_vec_edittree = GenericReprTreeMorphism::new( let list_morph_to_vec_edittree = GenericReprTreeMorphism::new(
Context::parse(&ctx, "<List EditTree>"), Context::parse(&ctx, "<List EditTree>"),
@ -169,12 +216,13 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
); );
ctx.write().unwrap().morphisms.add_morphism( list_morph_editsetup1 ); 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_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_char );
ctx.write().unwrap().morphisms.add_morphism( seq_morph_to_list_u64 ); 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_char );
ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_u64 ); ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_u64 );
ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_edittree ); ctx.write().unwrap().morphisms.add_morphism( list_morph_to_vec_edittree );
} }

View file

@ -1,14 +1,14 @@
use { use {
r3vi::{
view::{OuterViewPort, singleton::*, sequence::*},
buffer::{singleton::*, vec::*},
projection::*
},
laddertypes::{TypeTerm},
crate::{ crate::{
repr_tree::{Context, ReprTree}, edit_tree::{diagnostics::Diagnostics, EditTree, TreeCursor, TreeNav},
edit_tree::{EditTree, TreeNav, TreeCursor, diagnostics::Diagnostics}, editors::{list::{ListCmd, ListCursor, ListCursorMode}, ObjCommander},
editors::{list::{ListCursor, ListCursorMode, ListCmd}, 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} std::sync::{Arc, RwLock}
}; };
@ -17,17 +17,15 @@ use {
pub struct ListEditor { pub struct ListEditor {
pub cursor: SingletonBuffer<ListCursor>, pub cursor: SingletonBuffer<ListCursor>,
pub data: VecBuffer< ReprTreeArc >,
// todo: (?) remove RwLock<..> around NestedNode ?? pub spillbuf: Arc<RwLock< Vec< ReprTreeArc > >>,
pub data: VecBuffer< Arc<RwLock<EditTree>> >,
pub spillbuf: Arc<RwLock<Vec<Arc<RwLock<EditTree>>>>>,
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>>,
depth: OuterViewPort<dyn SingletonView<Item = usize>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>,
pub item_builder: ReprTreeBuilder,
pub ctx: Arc<RwLock<Context>>, pub ctx: Arc<RwLock<Context>>,
/// item type /// item type
@ -37,7 +35,7 @@ pub struct ListEditor {
impl ListEditor { impl ListEditor {
pub fn new( pub fn new(
ctx: Arc<RwLock<Context>>, ctx: Arc<RwLock<Context>>,
typ: TypeTerm typ: TypeTerm
) -> Self { ) -> Self {
Self::with_data( Self::with_data(
ctx, ctx,
@ -49,7 +47,7 @@ impl ListEditor {
pub fn with_data( pub fn with_data(
ctx: Arc<RwLock<Context>>, ctx: Arc<RwLock<Context>>,
typ: TypeTerm, typ: TypeTerm,
data: VecBuffer<Arc<RwLock<EditTree>>> data: VecBuffer< ReprTreeArc >
) -> Self { ) -> Self {
let cursor = SingletonBuffer::new(ListCursor::default()); let cursor = SingletonBuffer::new(ListCursor::default());
@ -58,6 +56,7 @@ impl ListEditor {
.get_port() .get_port()
.map({ .map({
let data = data.clone(); let data = data.clone();
let ctx = ctx.clone();
move |c| { move |c| {
let ip = SingletonBuffer::new(c.mode).get_port(); let ip = SingletonBuffer::new(c.mode).get_port();
match c.mode { match c.mode {
@ -65,7 +64,10 @@ impl ListEditor {
ListCursorMode::Select => { ListCursorMode::Select => {
if let Some(idx) = c.idx { if let Some(idx) = c.idx {
if idx >= 0 && idx < data.len() as isize { 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 { } else {
ip ip
} }
@ -86,11 +88,15 @@ impl ListEditor {
cursor.get_port() cursor.get_port()
.map({ .map({
let data = data.clone(); let data = data.clone();
let ctx = ctx.clone();
move |cur| { move |cur| {
if cur.mode == ListCursorMode::Select { if cur.mode == ListCursorMode::Select {
if let Some(idx) = cur.idx { if let Some(idx) = cur.idx {
if idx >= 0 && idx < data.len() as isize { 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() .to_sequence()
.flatten() .flatten()
]) ])
.get_port() .get_port()
.to_sequence() .to_sequence()
@ -106,8 +112,15 @@ impl ListEditor {
cursor, cursor,
data, data,
spillbuf: Arc::new(RwLock::new(Vec::new())), 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, typ,
ctx,
depth: SingletonBuffer::new(0).get_port() depth: SingletonBuffer::new(0).get_port()
} }
} }
@ -124,7 +137,7 @@ impl ListEditor {
.set_editor(editor.clone()) .set_editor(editor.clone())
.set_nav(editor.clone()) .set_nav(editor.clone())
.set_cmd(editor.clone()) .set_cmd(editor.clone())
.set_diag(e.get_data_port() .set_diag(e.get_edittree_seq()
.enumerate() .enumerate()
.map(|(idx, item_editor)| { .map(|(idx, item_editor)| {
let idx = *idx; let idx = *idx;
@ -141,11 +154,17 @@ impl ListEditor {
node 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 { pub fn get_item_type(&self) -> TypeTerm {
self.typ.clone() self.typ.clone()
} }
pub fn get_seq_type(&self) -> TypeTerm { pub fn get_list_type(&self) -> TypeTerm {
TypeTerm::App(vec![ TypeTerm::App(vec![
TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("List").unwrap()), TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("List").unwrap()),
self.get_item_type().into() self.get_item_type().into()
@ -156,10 +175,21 @@ impl ListEditor {
self.cursor.get_port() self.cursor.get_port()
} }
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> { pub fn get_reprtree_list(&self) -> OuterViewPort<dyn ListView<ReprTreeArc>> {
self.data.get_port().to_list().map( self.data.get_port().to_list()
|x| x.read().unwrap().clone() }
).to_sequence()
pub fn get_edittree_list(&self) -> OuterViewPort<dyn ListView<EditTree>> {
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<dyn SequenceView<Item = EditTree>> {
self.get_edittree_list().to_sequence()
} }
/* /*
pub fn get_data(&self) -> Arc<RwLock<ReprTree>> { pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
@ -170,11 +200,11 @@ impl ListEditor {
) )
} }
*/ */
pub fn get_item(&self) -> Option<EditTree> { pub fn get_item(&self) -> Option< ReprTreeArc > {
if let Some(idx) = self.cursor.get().idx { if let Some(idx) = self.cursor.get().idx {
let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize;
if idx < self.data.len() { if idx < self.data.len() {
Some(self.data.get(idx).read().unwrap().clone()) Some( self.data.get(idx).clone() )
} else { } else {
None None
} }
@ -183,7 +213,7 @@ impl ListEditor {
} }
} }
pub fn get_item_mut(&mut self) -> Option<MutableVecAccess<Arc<RwLock<EditTree>>>> { pub fn get_item_mut(&mut self) -> Option<MutableVecAccess< ReprTreeArc >> {
if let Some(idx) = self.cursor.get().idx { if let Some(idx) = self.cursor.get().idx {
let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize; let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize;
if idx < self.data.len() { if idx < self.data.len() {
@ -196,6 +226,23 @@ impl ListEditor {
} }
} }
pub fn get_edittree(&self, idx: usize) -> Arc<RwLock<EditTree>> {
self.data.get(idx).edittree(&self.ctx).get()
}
pub fn get_cur_edittree(&self) -> Option< Arc<RwLock<EditTree>> > {
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) /// is the element-type also a list-like editor (i.e. impls TreeNav)
pub fn is_listlist(&self) -> bool { pub fn is_listlist(&self) -> bool {
self.ctx.read().unwrap().is_list_type(&self.typ) self.ctx.read().unwrap().is_list_type(&self.typ)
@ -207,7 +254,7 @@ impl ListEditor {
for i in 0..self.data.len() { for i in 0..self.data.len() {
b.push( self.data.get(i) ); b.push( self.data.get(i) );
} }
self.data.clear(); self.data.clear();
self.cursor.set(ListCursor::home()); self.cursor.set(ListCursor::home());
} }
@ -234,8 +281,9 @@ impl ListEditor {
} }
/// insert a new element /// insert a new element
pub fn insert(&mut self, item: Arc<RwLock<EditTree>>) { pub fn insert(&mut self, item: ReprTreeArc) {
item.read().unwrap().disp.depth.0.set_view( 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() self.depth.map(|d| d+1).get_view()
); );
@ -247,13 +295,13 @@ impl ListEditor {
if self.is_listlist() { if self.is_listlist() {
cur.mode = ListCursorMode::Select; cur.mode = ListCursorMode::Select;
} else { } else {
item.write().unwrap().goto(TreeCursor::none()); item_edit.write().unwrap().goto(TreeCursor::none());
cur.idx = Some(idx + 1); cur.idx = Some(idx + 1);
} }
} }
ListCursorMode::Select => { ListCursorMode::Select => {
self.data.insert(1 + idx as usize, item.clone()); self.data.insert(1 + idx as usize, item.clone());
if self.is_listlist() { if self.is_listlist() {
cur.idx = Some(idx + 1); cur.idx = Some(idx + 1);
} }
@ -304,51 +352,41 @@ impl ListEditor {
let cur = self.get_cursor(); let cur = self.get_cursor();
if let Some(mut item) = self.get_item().clone() { 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 { if cur.tree_addr.len() < 3 {
item.goto(TreeCursor::none()); ie.goto(TreeCursor::none());
self.set_leaf_mode(ListCursorMode::Insert); self.set_leaf_mode(ListCursorMode::Insert);
self.nexd(); 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 rt = ReprTree::new_arc(self.typ.clone());
let mut et = self.ctx.read().unwrap().setup_edittree(&rt); let mut et = self.ctx.read().unwrap().setup_edittree(&rt);
if let Some(edittree) = et.as_mut(){ 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(); for n in b.iter() {
let mut tail_node = tail_node.write().unwrap(); tail_node.send_cmd_obj(n.clone());
tail_node.goto(TreeCursor::home()); }
for node in b.iter() { b.clear();
tail_node drop(b);
.send_cmd_obj( drop(item);
ReprTree::from_singleton_buffer(
Context::parse(&self.ctx, "EditTree"),
SingletonBuffer::<EditTree>::new(
node.read().unwrap().clone()
)
)
);
}
b.clear(); tail_node.goto(TreeCursor::home());
drop(b); if cur.tree_addr.len() > 1 {
drop(item); tail_node.dn();
}
tail_node.goto(TreeCursor::home()); drop(tail_node);
if cur.tree_addr.len() > 1 {
tail_node.dn();
}
drop(tail_node);
self.insert(
edittree.value.read().unwrap().clone()
);
self.insert(rt);
} }
} else { } else {
@ -361,8 +399,8 @@ impl ListEditor {
pub fn listlist_join_pxev(&mut self, idx: isize) { pub fn listlist_join_pxev(&mut self, idx: isize) {
{ {
let cur_editor = self.data.get(idx as usize); let cur_editor = self.data.get(idx as usize).edittree(&self.ctx).get();
let pxv_editor = self.data.get(idx as usize-1); let pxv_editor = self.data.get(idx as usize-1).edittree(&self.ctx).get();
let mut cur_editor = cur_editor.write().unwrap(); let mut cur_editor = cur_editor.write().unwrap();
let mut pxv_editor = pxv_editor.write().unwrap(); let mut pxv_editor = pxv_editor.write().unwrap();
@ -373,7 +411,7 @@ impl ListEditor {
cur_editor.send_cmd_obj( cur_editor.send_cmd_obj(
ListCmd::Clear.into_repr_tree( &self.ctx ) ListCmd::Clear.into_repr_tree( &self.ctx )
); );
pxv_editor.goto(TreeCursor { pxv_editor.goto(TreeCursor {
tree_addr: vec![-1], tree_addr: vec![-1],
leaf_mode: ListCursorMode::Insert leaf_mode: ListCursorMode::Insert
@ -383,14 +421,7 @@ impl ListEditor {
let data = cur_editor.ctrl.spillbuf.read().unwrap(); let data = cur_editor.ctrl.spillbuf.read().unwrap();
for x in data.iter() { for x in data.iter() {
pxv_editor.send_cmd_obj( pxv_editor.send_cmd_obj(x.clone());
ReprTree::from_singleton_buffer(
Context::parse(&self.ctx, "EditTree"),
SingletonBuffer::<EditTree>::new(
x.read().unwrap().clone()
)
)
);
} }
@ -398,13 +429,13 @@ impl ListEditor {
if oc0.tree_addr.len() > 1 { if oc0.tree_addr.len() > 1 {
pxv_editor.goto(TreeCursor { pxv_editor.goto(TreeCursor {
tree_addr: vec![ old_cur.tree_addr[0], 0 ], 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 )); pxv_editor.send_cmd_obj(ListCmd::DeletePxev.into_repr_tree( &self.ctx ));
} else if oc0.tree_addr.len() > 0 { } else if oc0.tree_addr.len() > 0 {
pxv_editor.goto(TreeCursor { pxv_editor.goto(TreeCursor {
tree_addr: vec![ old_cur.tree_addr[0] ], 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) { pub fn listlist_join_nexd(&mut self, idx: usize) {
{ {
let cur_editor = self.data.get(idx); let cur_editor = self.data.get(idx).edittree(&self.ctx).get();
let nxd_editor = self.data.get(idx + 1); let nxd_editor = self.data.get(idx + 1).edittree(&self.ctx).get();
let mut cur_editor = cur_editor.write().unwrap(); let mut cur_editor = cur_editor.write().unwrap();
let mut nxd_editor = nxd_editor.write().unwrap(); let mut nxd_editor = nxd_editor.write().unwrap();
@ -438,25 +469,18 @@ impl ListEditor {
tree_addr: vec![-1], tree_addr: vec![-1],
leaf_mode: ListCursorMode::Insert leaf_mode: ListCursorMode::Insert
}); });
let data = nxd_editor.ctrl.spillbuf.read().unwrap(); let data = nxd_editor.ctrl.spillbuf.read().unwrap();
for x in data.iter() { for x in data.iter() {
cur_editor.send_cmd_obj( cur_editor.send_cmd_obj(x.clone());
ReprTree::from_singleton_buffer(
Context::parse(&self.ctx, "EditTree"),
SingletonBuffer::<EditTree>::new(
x.read().unwrap().clone()
)
)
);
} }
// fixme: is it oc0 or old_cur ?? // fixme: is it oc0 or old_cur ??
if oc0.tree_addr.len() > 1 { if oc0.tree_addr.len() > 1 {
cur_editor.goto(TreeCursor { cur_editor.goto(TreeCursor {
tree_addr: vec![ old_cur.tree_addr[0], -1 ], 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 )); cur_editor.send_cmd_obj(ListCmd::DeleteNexd.into_repr_tree( &self.ctx ));
} else if oc0.tree_addr.len() > 0 { } 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 idx = crate::utils::modulo::modulo(addr.0[0] as isize, self.data.len() as isize) as usize;
let mut addr = addr.clone(); let mut addr = addr.clone();
if self.data.len() > 0 { if self.data.len() > 0 {
addr.0.remove(0); addr.0.remove(0);
self.data.get(idx).get_type(addr) self.data.get(idx).get_type(addr)
@ -495,5 +519,3 @@ impl TreeType for ListEditor {
} }
} }
*/ */

View file

@ -11,6 +11,7 @@ use {
ListCursor, ListCursorMode, ListCursor, ListCursorMode,
editor::ListEditor editor::ListEditor
}, },
repr_tree::{ReprTreeExt},
edit_tree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp} edit_tree::{TreeCursor, TreeNav, TreeNavResult, TreeHeightOp}
}, },
cgmath::Vector2 cgmath::Vector2
@ -26,7 +27,7 @@ impl TreeNav for ListEditor {
fn get_mode_view(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursorMode>> { fn get_mode_view(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursorMode>> {
self.mode_port.clone() self.mode_port.clone()
} }
fn get_height(&self, op: &TreeHeightOp) -> usize { fn get_height(&self, op: &TreeHeightOp) -> usize {
match op { match op {
TreeHeightOp::P | TreeHeightOp::Q => { TreeHeightOp::P | TreeHeightOp::Q => {
@ -35,7 +36,10 @@ impl TreeNav for ListEditor {
TreeHeightOp::P => 0, TreeHeightOp::P => 0,
TreeHeightOp::Q => self.data.len() - 1, TreeHeightOp::Q => self.data.len() - 1,
_ => 0 _ => 0
}).read().unwrap().get_height(op) })
.edittree(&self.ctx).get()
.read().unwrap()
.get_height(op)
} else { } else {
1 1
} }
@ -43,7 +47,9 @@ impl TreeNav for ListEditor {
TreeHeightOp::Max => { TreeHeightOp::Max => {
1 + (0..self.data.len() as usize) 1 + (0..self.data.len() as usize)
.map(|i| self.data .map(|i| self.data
.get(i).read().unwrap() .get(i)
.edittree(&self.ctx).get()
.read().unwrap()
.get_height(&TreeHeightOp::Max) .get_height(&TreeHeightOp::Max)
) )
.max() .max()
@ -68,7 +74,9 @@ impl TreeNav for ListEditor {
ListCursorMode::Select => { ListCursorMode::Select => {
if let Some(i) = cur.idx { if let Some(i) = cur.idx {
if i < self.data.len() as isize { 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); sub_cur.tree_addr.insert(0, i as isize - self.data.len() as isize);
return sub_cur; return sub_cur;
} else { } else {
@ -100,11 +108,11 @@ impl TreeNav for ListEditor {
ListCursorMode::Select => { ListCursorMode::Select => {
if let Some(i) = cur.idx { if let Some(i) = cur.idx {
if i < self.data.len() as isize { 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 { if sub_cur.tree_addr.len() > 0 {
sub_cur.tree_addr.insert(0, i as isize); sub_cur.tree_addr.insert(0, i as isize);
return sub_cur; return sub_cur;
} else { } else {
return TreeCursor { return TreeCursor {
leaf_mode: ListCursorMode::Select, leaf_mode: ListCursorMode::Select,
tree_addr: vec![ i ], tree_addr: vec![ i ],
@ -124,7 +132,7 @@ impl TreeNav for ListEditor {
let old_cur = self.cursor.get(); let old_cur = self.cursor.get();
if let Some(i) = old_cur.idx { if let Some(i) = old_cur.idx {
if i < self.data.len() as isize { 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 { if new_cur.leaf_mode == ListCursorMode::Select && self.data.len() > 0 {
self.data self.get_edittree(idx as usize)
.get_mut(idx as usize)
.write().unwrap() .write().unwrap()
.goto(TreeCursor { .goto(TreeCursor {
leaf_mode: ListCursorMode::Select, leaf_mode: ListCursorMode::Select,
@ -165,8 +172,7 @@ impl TreeNav for ListEditor {
idx: Some(idx), idx: Some(idx),
}); });
self.data self.get_edittree(idx as usize)
.get_mut(idx as usize)
.write().unwrap() .write().unwrap()
.goto(TreeCursor { .goto(TreeCursor {
leaf_mode: new_cur.leaf_mode, leaf_mode: new_cur.leaf_mode,
@ -176,7 +182,7 @@ impl TreeNav for ListEditor {
self.cursor.set(ListCursor::home()); self.cursor.set(ListCursor::home());
} }
TreeNavResult::Continue TreeNavResult::Continue
} }
} }
} }
@ -212,8 +218,7 @@ impl TreeNav for ListEditor {
// dn // dn
if cur.tree_addr[0] < self.data.len() as isize { if cur.tree_addr[0] < self.data.len() as isize {
if self.data if self.get_edittree(cur.tree_addr[0] as usize)
.get_mut(cur.tree_addr[0] as usize)
.write().unwrap() .write().unwrap()
.goby(Vector2::new(direction.x, direction.y)) .goby(Vector2::new(direction.x, direction.y))
== TreeNavResult::Continue { == TreeNavResult::Continue {
@ -247,11 +252,10 @@ impl TreeNav for ListEditor {
match cur.leaf_mode { match cur.leaf_mode {
ListCursorMode::Select => { 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 cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::Max);
let new_item = self.data let new_item = self.get_edittree(idx as usize);
.get_mut(idx as usize);
let height = new_item.read().unwrap().get_height( let height = new_item.read().unwrap().get_height(
if direction.x < 0 { if direction.x < 0 {
@ -277,28 +281,28 @@ impl TreeNav for ListEditor {
if direction.x > 0 if direction.x > 0
{ {
if (cur.tree_addr[0] as usize) < self.data.len() { 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); let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::P);
if gravity && cur_height > 1 { if gravity && cur_height > 1 {
new_addr.push( cur.tree_addr[0] ); new_addr.push( cur.tree_addr[0] );
new_addr.push(0); new_addr.push(0);
} else { } else {
new_addr.push( idx ); new_addr.push( idx );
} }
} }
} else { } else {
if (idx as usize) < self.data.len() { 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); let pxv_height = pxv_item.read().unwrap().get_height(&TreeHeightOp::P);
if gravity && pxv_height > 1 { if gravity && pxv_height > 1 {
new_addr.push( idx ); new_addr.push( idx );
new_addr.push( -1 ); new_addr.push( -1 );
} else { } else {
new_addr.push( idx ); new_addr.push( idx );
} }
} }
} }
} }
} }
@ -324,10 +328,7 @@ impl TreeNav for ListEditor {
// nested // nested
if cur.tree_addr[0] < self.data.len() as isize { if cur.tree_addr[0] < self.data.len() as isize {
let cur_item = self.get_edittree(cur.tree_addr[0] as usize);
let cur_item = self.data
.get_mut(cur.tree_addr[0] as usize);
let result = cur_item.write().unwrap().goby(direction); let result = cur_item.write().unwrap().goby(direction);
match result match result
@ -353,8 +354,7 @@ impl TreeNav for ListEditor {
let mut new_addr = Vec::new(); let mut new_addr = Vec::new();
if direction.x < 0 { if direction.x < 0 {
let pxv_item = self.data let pxv_item = self.get_edittree(cur.tree_addr[0] as usize - 1);
.get_mut(cur.tree_addr[0] as usize - 1);
let pxv_height = pxv_item.read().unwrap().get_height(&TreeHeightOp::Q) as isize; 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; 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 { for _i in 0..n_steps_down {
new_addr.push( -1 ); new_addr.push( -1 );
} }
} else { } else {
let nxd_item = self.data let nxd_item = self.get_edittree(cur.tree_addr[0] as usize + 1);
.get_mut(cur.tree_addr[0] as usize + 1);
let cur_height = cur_item.read().unwrap().get_height(&TreeHeightOp::Q) as isize; 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; let nxd_height = nxd_item.read().unwrap().get_height(&TreeHeightOp::P) as isize;
@ -422,4 +421,3 @@ impl TreeNav for ListEditor {
} }
} }
} }

View file

@ -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<RwLock<Context>>,
pub required_leaves: Vec<TypeTerm>,
}
#[derive(Debug)]
pub enum ReprTreeError {
MissingMorphism
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl ReprTreeBuilder {
pub fn new(ctx: Arc<RwLock<Context>>) -> 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<RwLock<ReprTree>>,
master_leaf_type: impl Into<TypeTerm>
) -> Result< Arc<RwLock<ReprTree>>, 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<RwLock<ReprTree>>
) -> Result< Arc<RwLock<ReprTree>>, ReprTreeError > {
let master_leaf_type = master_rt.get_full_type();
self.update( &ReprTree::rise( master_rt ), master_leaf_type )
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -123,41 +123,9 @@ impl Context {
} }
} else { } else {
eprintln!("no path found"); eprintln!("no path found");
}
}
pub fn build_repr_tree(
&self,
rt: &Arc<RwLock<ReprTree>>,
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<RwLock<Self>>, 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<RwLock<Self>>, s: &str) -> TypeTerm { pub fn parse(ctx: &Arc<RwLock<Self>>, s: &str) -> TypeTerm {
ctx.read().unwrap().type_term_from_str(s).expect("could not parse type term") ctx.read().unwrap().type_term_from_str(s).expect("could not parse type term")
} }
@ -277,4 +245,3 @@ impl Context {
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -50,13 +50,13 @@ impl ReprLeaf {
in_keepalive: Some(in_keepalive), in_keepalive: Some(in_keepalive),
in_port: in_port.inner().into(), in_port: in_port.inner().into(),
out_port: out_port.into(), out_port: out_port.into(),
data: None, data: None,
} }
} }
pub fn detach<V>(&mut self) pub fn detach<V>(&mut self)
where V: View + ?Sized + 'static, where V: View + ?Sized + 'static,
V::Msg: Clone V::Msg: Clone
{ {
self.keepalive = None; self.keepalive = None;
self.in_keepalive = None; self.in_keepalive = None;
@ -213,4 +213,3 @@ impl ReprLeaf {
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -1,5 +1,6 @@
pub mod node; pub mod node;
pub mod leaf; pub mod leaf;
pub mod builder;
pub mod context; pub mod context;
pub mod morphism; pub mod morphism;
@ -10,6 +11,7 @@ pub use {
context::{Context}, context::{Context},
leaf::ReprLeaf, leaf::ReprLeaf,
node::{ReprTree, ReprTreeArc}, node::{ReprTree, ReprTreeArc},
builder::{ReprTreeBuilder, ReprTreeError},
morphism::{GenericReprTreeMorphism} morphism::{GenericReprTreeMorphism}
}; };
@ -34,15 +36,15 @@ use {
}, },
}; };
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub trait ReprTreeExt { pub trait ReprTreeExt {
fn get_type(&self) -> TypeTerm; fn get_type(&self) -> TypeTerm;
fn get_full_type(&self) -> TypeTerm;
fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf); fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf);
fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>); fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>);
fn create_branch(&mut self, rung: impl Into<TypeTerm>); fn create_branch(&mut self, rung: impl Into<TypeTerm>);
fn descend(&self, target_type: impl Into<TypeTerm>) -> Option< ReprTreeArc >; fn descend(&self, target_type: impl Into<TypeTerm>) -> Option< ReprTreeArc >;
fn descend_create(&self, target_type: impl Into<TypeTerm>) -> Option< ReprTreeArc >;
fn attach_leaf_to<V: View + ?Sized + 'static>(&self, t: impl Into<TypeTerm>, v: OuterViewPort<V>) where V::Msg: Clone; fn attach_leaf_to<V: View + ?Sized + 'static>(&self, t: impl Into<TypeTerm>, v: OuterViewPort<V>) where V::Msg: Clone;
fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone; fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> where V::Msg: Clone;
@ -60,7 +62,8 @@ pub trait ReprTreeExt {
fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>; fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>;
fn edittree(&self, ctx: &Arc<RwLock<Context>>) -> SingletonBuffer< Arc<RwLock<crate::edit_tree::EditTree>> > { fn edittree(&self, ctx: &Arc<RwLock<Context>>) -> SingletonBuffer< Arc<RwLock<crate::edit_tree::EditTree>> > {
self.descend(Context::parse(&ctx, "EditTree")).unwrap() self.descend_create(Context::parse(&ctx, "EditTree"))
.expect("failed to get EditTree")
.singleton_buffer() .singleton_buffer()
} }
} }
@ -70,6 +73,10 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
self.read().unwrap().get_type().clone() 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<TypeTerm>, leaf: ReprLeaf) { fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf) {
self.write().unwrap().insert_leaf(type_ladder.into().get_lnf_vec().into_iter(), leaf) self.write().unwrap().insert_leaf(type_ladder.into().get_lnf_vec().into_iter(), leaf)
} }
@ -78,8 +85,8 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
self.write().unwrap().insert_branch(repr) self.write().unwrap().insert_branch(repr)
} }
fn create_branch(&mut self, rung: impl Into<TypeTerm>) { fn create_branch(&mut self, branch: impl Into<TypeTerm>) {
let mut lnf = rung.into().get_lnf_vec().into_iter(); let mut lnf = branch.into().get_lnf_vec().into_iter();
if let Some(rung) = lnf.next() { if let Some(rung) = lnf.next() {
let mut parent = ReprTree::new_arc( rung ); let mut parent = ReprTree::new_arc( rung );
self.insert_branch( parent.clone() ); self.insert_branch( parent.clone() );
@ -104,6 +111,10 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
ReprTree::descend( self, target_type ) ReprTree::descend( self, target_type )
} }
fn descend_create(&self, target_type: impl Into<TypeTerm>)-> Option< ReprTreeArc > {
ReprTree::descend_create( self, target_type )
}
fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> { fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
self.read().unwrap().view_char() self.read().unwrap().view_char()
} }
@ -142,4 +153,3 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -80,29 +80,44 @@ impl GenericReprTreeMorphism {
lst_map_type.src_type.apply_substitution( &|x| subst.get(x).cloned() ); 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.dst_type.apply_substitution( &|x| subst.get(x).cloned() );
lst_map_type = lst_map_type.normalize();
eprintln!( 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() ) let mut item_ladder = item_morph.morph_type.src_type.clone().get_lnf_vec();
.expect("descend src seq") let top_type = item_ladder.remove( item_ladder.len() - 1 );
.view_list::<SrcItem>();
let subst = subst.clone(); if let Ok(item_sigma) = laddertypes::unify(
let item_morph = item_morph.clone(); &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::<SrcItem>();
let dst_view = src_port.map( let subst = subst.clone();
let item_morph = item_morph.clone();
let dst_view = src_port.map(
move |x| { move |x| {
let mut item_ladder = item_morph.morph_type.src_type.clone().get_lnf_vec();
let mut item_rt = ReprTree::from_singleton_buffer( let mut item_rt = ReprTree::from_singleton_buffer(
item_ladder.remove( item_ladder.len() - 1 ), top_type.clone(),
r3vi::buffer::singleton::SingletonBuffer::new(x.clone()) r3vi::buffer::singleton::SingletonBuffer::new(x.clone())
); );
// TODO: required? // TODO: required?
while item_ladder.len() > 0 { for t in item_ladder.iter().rev() {
let mut n = ReprTree::new_arc( item_ladder.remove( item_ladder.len() - 1) ); let mut n = ReprTree::new_arc( t.clone() );
n.insert_branch( item_rt ); n.insert_branch( item_rt );
item_rt = n; item_rt = n;
} }
@ -112,13 +127,14 @@ impl GenericReprTreeMorphism {
.view_singleton::< DstItem >() .view_singleton::< DstItem >()
.get_view().unwrap() .get_view().unwrap()
.get() .get()
} });
);
repr_tree.attach_leaf_to(
lst_map_type.dst_type.clone(), repr_tree.attach_leaf_to(
dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView<DstItem> > lst_map_type.dst_type.clone(),
); dst_view as r3vi::view::OuterViewPort::< dyn r3vi::view::list::ListView<DstItem> >
);
}
}) })
} }
} }
@ -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))
}
}
*/

View file

@ -1,5 +1,3 @@
use { use {
r3vi::{ r3vi::{
view::{ view::{
@ -11,7 +9,7 @@ use {
sequence::*, sequence::*,
list::* list::*
}, },
buffer::{singleton::*, vec::*} buffer::{singleton::*, vec::*},
}, },
laddertypes::{TypeTerm, TypeID}, laddertypes::{TypeTerm, TypeID},
std::{ std::{
@ -19,7 +17,12 @@ use {
sync::{Arc, RwLock}, sync::{Arc, RwLock},
any::Any 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, halo: TypeTerm,
type_tag: TypeTerm, type_tag: TypeTerm,
branches: HashMap<TypeTerm, ReprTreeArc>, branches: HashMap<TypeTerm, ReprTreeArc>,
leaf: Option< ReprLeaf > leaf: Option< ReprLeaf >,
} }
pub type ReprTreeArc = Arc<RwLock<ReprTree>>; pub type ReprTreeArc = Arc<RwLock<ReprTree>>;
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
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 { impl ReprTree {
pub fn new(typ: impl Into<TypeTerm>) -> Self { pub fn new(typ: impl Into<TypeTerm>) -> Self {
let mut lnf = typ.into().get_lnf_vec(); let mut lnf = typ.into().get_lnf_vec();
@ -69,10 +57,33 @@ impl ReprTree {
} }
} }
pub fn fmt(&self, ctx: &Arc<RwLock<Context>>, 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<TypeTerm>) -> ReprTreeArc { pub fn new_arc(type_tag: impl Into<TypeTerm>) -> ReprTreeArc {
Arc::new(RwLock::new(Self::new(type_tag))) 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 { pub fn get_type(&self) -> &TypeTerm {
&self.type_tag &self.type_tag
} }
@ -128,7 +139,10 @@ impl ReprTree {
) )
} }
pub fn from_view<V>( type_tag: impl Into<TypeTerm>, view: OuterViewPort<V> ) -> ReprTreeArc pub fn from_view<V>(
type_tag: impl Into<TypeTerm>,
view: OuterViewPort<V>
) -> ReprTreeArc
where V: View + ?Sized + 'static, where V: View + ?Sized + 'static,
V::Msg: Clone V::Msg: Clone
{ {
@ -137,7 +151,10 @@ impl ReprTree {
Arc::new(RwLock::new(rt)) Arc::new(RwLock::new(rt))
} }
pub fn from_singleton_buffer<T>( type_tag: impl Into<TypeTerm>, buf: SingletonBuffer<T> ) -> ReprTreeArc pub fn from_singleton_buffer<T>(
type_tag: impl Into<TypeTerm>,
buf: SingletonBuffer<T>
) -> ReprTreeArc
where T: Clone + Send + Sync + 'static where T: Clone + Send + Sync + 'static
{ {
let mut rt = ReprTree::new(type_tag); let mut rt = ReprTree::new(type_tag);
@ -145,23 +162,20 @@ impl ReprTree {
Arc::new(RwLock::new(rt)) Arc::new(RwLock::new(rt))
} }
pub fn from_str( pub fn from_str(val: &str) -> ReprTreeArc {
type_tag: impl Into<TypeTerm>, ReprTree::from_vec_buffer(
val: &str TypeTerm::App(vec![ TypeTerm::TypeID(TYPEID_vec), TypeTerm::TypeID(TYPEID_char) ]),
) -> ReprTreeArc {
let mut lnf = type_tag.into().get_lnf_vec();
let mut rt = ReprTree::from_vec_buffer(
lnf.pop().unwrap(),
VecBuffer::with_data( val.chars().collect() ) VecBuffer::with_data( val.chars().collect() )
); )
}
pub fn rise( mut rt: Arc<RwLock<ReprTree>> ) -> Arc<RwLock<ReprTree>> {
let mut lnf = rt.read().unwrap().get_halo_type().clone().get_lnf_vec();
while let Some(t) = lnf.pop() { while let Some(t) = lnf.pop() {
let mut new_rt = ReprTree::new_arc(t); let mut new_rt = ReprTree::new_arc(t);
new_rt.insert_branch(rt); new_rt.insert_branch(rt);
rt = new_rt; rt = new_rt
} }
rt rt
} }
@ -198,7 +212,7 @@ impl ReprTree {
V::Msg: Clone V::Msg: Clone
{ {
while let Some(rung_type) = type_ladder.next() { 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) { if let Some(next_repr) = self.branches.get(&rung_type) {
next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port); next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port);
} else { } else {
@ -225,7 +239,7 @@ impl ReprTree {
leaf.attach_to(src_port); leaf.attach_to(src_port);
self.leaf = Some(leaf); self.leaf = Some(leaf);
} }
else if self.type_tag == TypeTerm::App(vec![ else if self.type_tag == TypeTerm::App(vec![
TypeTerm::TypeID(TYPEID_vec), TypeTerm::TypeID(TYPEID_vec),
TypeTerm::TypeID(TYPEID_char) TypeTerm::TypeID(TYPEID_char)
@ -342,7 +356,7 @@ impl ReprTree {
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub fn descend_one(&self, dst_type: impl Into<TypeTerm>) -> Option< ReprTreeArc > { pub fn descend_rung(&self, dst_type: impl Into<TypeTerm>) -> Option< ReprTreeArc > {
let dst_type = dst_type.into(); let dst_type = dst_type.into();
assert!( dst_type.is_flat() ); assert!( dst_type.is_flat() );
self.branches.get(&dst_type).cloned() self.branches.get(&dst_type).cloned()
@ -352,7 +366,7 @@ impl ReprTree {
if let Some(first) = repr_ladder.next() { if let Some(first) = repr_ladder.next() {
let rt = rt.read().unwrap(); let rt = rt.read().unwrap();
repr_ladder.fold( repr_ladder.fold(
rt.descend_one(first), rt.descend_rung(first),
|s, t| s?.descend(t)) |s, t| s?.descend(t))
} else { } else {
Some(rt.clone()) Some(rt.clone())
@ -371,25 +385,36 @@ impl ReprTree {
} }
} }
pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> { pub fn descend_create(
rt: &Arc<RwLock<Self>>,
dst_type: impl Into<TypeTerm>
) -> 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<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> ReprTreeArc {
let mut n = Self::new(type_term); let mut n = Self::new(type_term);
n.insert_branch(rt.clone()); n.insert_branch(rt.clone());
Arc::new(RwLock::new(n)) Arc::new(RwLock::new(n))
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
// Buffer Access \\
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
pub fn singleton_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<SingletonBuffer<T>> { pub fn singleton_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<SingletonBuffer<T>> {
if let Some(leaf) = self.leaf.as_mut() { if let Some(leaf) = self.leaf.as_mut() {
leaf.as_singleton_buffer::<T>() leaf.as_singleton_buffer::<T>()
} else { } else {
// create new singleton buffer
/*
// default value??
let buf = SingletonBuffer::<T>::default();
self.leaf = Some(ReprLeaf::from_singleton_buffer(buf.clone()));
Some(buf)
*/
None None
} }
} }
@ -402,7 +427,10 @@ impl ReprTree {
} }
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
// View Access \\
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>\\
pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>> pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
where where
@ -455,5 +483,3 @@ impl ReprTree {
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -43,7 +43,7 @@ impl DisplaySegment for ListSegment {
} else { } else {
usize::MAX usize::MAX
}; };
atom atom
.add_style_back(bg_style_from_depth(select)) .add_style_back(bg_style_from_depth(select))
.add_style_back(TerminalStyle::bold(select==1)) .add_style_back(TerminalStyle::bold(select==1))
@ -70,7 +70,7 @@ impl PTYListStyle {
pub fn get_seg_seq_view(&self, editor: &ListEditor) -> OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>> { pub fn get_seg_seq_view(&self, editor: &ListEditor) -> OuterViewPort<dyn SequenceView<Item = OuterViewPort<dyn TerminalView>>> {
let seg_seq = ListSegmentSequence::new( let seg_seq = ListSegmentSequence::new(
editor.get_cursor_port(), editor.get_cursor_port(),
editor.get_data_port() editor.get_edittree_seq()
); );
let se = seg_seq.read().unwrap(); let se = seg_seq.read().unwrap();
se.get_view().map(move |segment| segment.display_view()) se.get_view().map(move |segment| segment.display_view())
@ -79,7 +79,7 @@ impl PTYListStyle {
pub fn pty_view(&self, editor: &ListEditor) -> OuterViewPort<dyn TerminalView> { pub fn pty_view(&self, editor: &ListEditor) -> OuterViewPort<dyn TerminalView> {
let seg_seq = ListSegmentSequence::new( let seg_seq = ListSegmentSequence::new(
editor.get_cursor_port(), editor.get_cursor_port(),
editor.get_data_port() editor.get_edittree_seq()
); );
let seg_seq0 = seg_seq.read().unwrap(); let seg_seq0 = seg_seq.read().unwrap();
@ -133,7 +133,7 @@ impl PTYListController {
split_char, split_char,
close_char, close_char,
depth depth
} }
} }
pub fn for_node( pub fn for_node(
@ -162,17 +162,17 @@ impl PTYListController {
} }
pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> { pub fn get_data_port(&self) -> OuterViewPort<dyn SequenceView<Item = EditTree>> {
self.editor.read().unwrap().get_data_port() self.editor.read().unwrap().get_edittree_seq()
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {
self.editor.write().unwrap().clear(); self.editor.write().unwrap().clear();
} }
/*
pub fn get_item(&self) -> Option<EditTree> { pub fn get_item(&self) -> Option<EditTree> {
self.editor.read().unwrap().get_item() self.editor.read().unwrap().get_item()
} }
*/
pub fn handle_term_event(&mut self, event: &TerminalEvent, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { pub fn handle_term_event(&mut self, event: &TerminalEvent, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
let mut e = self.editor.write().unwrap(); let mut e = self.editor.write().unwrap();
match event { match event {
@ -247,7 +247,7 @@ impl PTYListController {
match ne.send_cmd_obj(cmd_obj.clone()) { match ne.send_cmd_obj(cmd_obj.clone()) {
TreeNavResult::Continue => { TreeNavResult::Continue => {
drop(ne); drop(ne);
e.insert(new_edittree.value.read().unwrap().clone()); e.insert(rt);
TreeNavResult::Continue TreeNavResult::Continue
} }
TreeNavResult::Exit => { TreeNavResult::Exit => {
@ -260,7 +260,7 @@ impl PTYListController {
} }
}, },
ListCursorMode::Select => { 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 res = item.write().unwrap().send_cmd_obj(cmd_obj.clone());
let child_close_char = item.read().unwrap().ctrl.close_char.get(); let child_close_char = item.read().unwrap().ctrl.close_char.get();

View file

@ -127,9 +127,10 @@ pub fn setup_edittree_hook(ctx: &Arc<RwLock<Context>>) {
let posint_hex_type = Context::parse(&ctx, "<PosInt 16 BigEndian>"); let posint_hex_type = Context::parse(&ctx, "<PosInt 16 BigEndian>");
let item_tyid = ctx.read().unwrap().get_var_typeid("Item").unwrap(); let item_tyid = ctx.read().unwrap().get_var_typeid("Item").unwrap();
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('}'); //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. // 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. // this will setup the display and navigation elements of the editor.