refactor ReprTree
- ReprLeaf with In- & Out-Ports - Optional Buffers
This commit is contained in:
parent
03dc9f1133
commit
658f5c1000
17 changed files with 946 additions and 242 deletions
|
@ -8,17 +8,19 @@ use {
|
|||
cgmath::Vector2,
|
||||
nested::{
|
||||
editors::ObjCommander,
|
||||
repr_tree::{Context, ReprTree},
|
||||
repr_tree::{Context, ReprTree, ReprTreeExt},
|
||||
edit_tree::{EditTree}
|
||||
},
|
||||
nested_tty::{
|
||||
DisplaySegment, TTYApplication,
|
||||
TerminalCompositor, TerminalStyle, TerminalView,
|
||||
TerminalAtom
|
||||
TerminalAtom, TerminalEvent
|
||||
},
|
||||
r3vi::{
|
||||
buffer::{singleton::*, vec::*},
|
||||
view::{port::UpdateTask}
|
||||
},
|
||||
// termion::{},
|
||||
std::sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
|
@ -48,8 +50,8 @@ async fn main() {
|
|||
// It provides the necessary bridge to the rendering- & input-backend.
|
||||
ctx.write().unwrap().set_edittree_hook(
|
||||
Arc::new(
|
||||
move |et: Arc<RwLock<EditTree>>, t: laddertypes::TypeTerm| {
|
||||
let mut et = et.write().unwrap();
|
||||
move |et: &mut EditTree, t: laddertypes::TypeTerm| {
|
||||
// let mut et = et.write().unwrap();
|
||||
|
||||
if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) {
|
||||
*et = nested_tty::editors::edittree_make_char_view(et.clone());
|
||||
|
@ -95,31 +97,49 @@ async fn main() {
|
|||
* / | \
|
||||
* TTY PixelBuf SDF
|
||||
*/
|
||||
let rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
|
||||
let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
|
||||
|
||||
/* add initial representation
|
||||
* <Digit 16> ~ Char
|
||||
*/
|
||||
rt_digit.write().unwrap()
|
||||
.insert_leaf(
|
||||
vec![ Context::parse(&ctx, "Char") ].into_iter(),
|
||||
SingletonBuffer::new('4').get_port().into()
|
||||
);
|
||||
rt_digit.insert_leaf(
|
||||
Context::parse(&ctx, "Char"),
|
||||
nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') )
|
||||
);
|
||||
|
||||
/* furthermore, setup projections to and from u8 value,
|
||||
* this synchronizes the buffers
|
||||
*/
|
||||
ctx.read().unwrap().morphisms.apply_morphism(
|
||||
rt_digit.clone(),
|
||||
&Context::parse(&ctx, "<Digit 16>~Char"),
|
||||
&Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8")
|
||||
);
|
||||
|
||||
/* setup TTY-Display for DigitEditor
|
||||
*
|
||||
* `setup_edittree` will setup the projection
|
||||
* Char -> Char~EditTree
|
||||
* and call the hook defined above with `set_edittree_hook()`
|
||||
*
|
||||
*/
|
||||
let edittree_digit = ctx.read().unwrap()
|
||||
.setup_edittree(
|
||||
rt_digit
|
||||
.read().unwrap()
|
||||
.descend( Context::parse(&ctx, "Char") ).unwrap()
|
||||
.clone(),
|
||||
r3vi::buffer::singleton::SingletonBuffer::new(0).get_port());
|
||||
rt_digit.clone(),
|
||||
r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()
|
||||
);
|
||||
|
||||
let mut digit_u8_buffer = rt_digit
|
||||
.descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap()
|
||||
.singleton_buffer::<u8>();
|
||||
|
||||
//---
|
||||
let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List <Digit 10>>") );
|
||||
let edittree = ctx.read().unwrap()
|
||||
.setup_edittree(rt_string.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port());
|
||||
let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") );
|
||||
|
||||
let edittree_list = ctx.read().unwrap()
|
||||
.setup_edittree(
|
||||
rt_string.clone(),
|
||||
r3vi::buffer::singleton::SingletonBuffer::new(0).get_port());
|
||||
|
||||
/* setup terminal
|
||||
*/
|
||||
|
@ -127,9 +147,22 @@ async fn main() {
|
|||
/* event handler
|
||||
*/
|
||||
let ctx = ctx.clone();
|
||||
let et1 = edittree.clone();
|
||||
let mut editors = Vec::new();
|
||||
editors.push(edittree_digit.clone());
|
||||
editors.push(edittree_list.clone());
|
||||
|
||||
let edit_select = Arc::new(RwLock::new(0));
|
||||
move |ev| {
|
||||
et1.write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx));
|
||||
match ev {
|
||||
TerminalEvent::Input(termion::event::Event::Key(termion::event::Key::Char('\t'))) => {
|
||||
let mut i = edit_select.write().unwrap();
|
||||
*i = (*i + 1) % editors.len();
|
||||
}
|
||||
_ => {
|
||||
let i = edit_select.read().unwrap();
|
||||
editors[*i].get().send_cmd_obj(ev.to_repr_tree(&ctx));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -150,25 +183,37 @@ async fn main() {
|
|||
);
|
||||
|
||||
comp.push(
|
||||
edittree_digit.read().unwrap().display_view()
|
||||
.offset(Vector2::new(0,2))
|
||||
edittree_digit.get().display_view()
|
||||
.offset(Vector2::new(2,2))
|
||||
);
|
||||
|
||||
let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type());
|
||||
comp.push(
|
||||
nested_tty::make_label(&label_str)
|
||||
.map_item(|_pt,atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90))))
|
||||
.offset(Vector2::new(0, 1))
|
||||
);
|
||||
|
||||
comp.push(
|
||||
edittree.read().unwrap().display_view()
|
||||
.offset(Vector2::new(0,4))
|
||||
digit_u8_buffer.get_port().map(
|
||||
|d| nested_tty::make_label(&format!("Digit={}", d))
|
||||
)
|
||||
.to_grid()
|
||||
.flatten()
|
||||
.offset(Vector2::new(2,3))
|
||||
);
|
||||
|
||||
|
||||
comp.push(
|
||||
edittree_list.get().display_view()
|
||||
.offset(Vector2::new(2,6))
|
||||
);
|
||||
|
||||
let label_str = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type());
|
||||
comp.push(
|
||||
nested_tty::make_label(&label_str)
|
||||
.offset(Vector2::new(0, 3))
|
||||
.map_item(|_pt, atom| atom.add_style_front(TerminalStyle::fg_color((90,90,90))))
|
||||
.offset(Vector2::new(0, 5))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,13 @@ use {
|
|||
view::{
|
||||
OuterViewPort,
|
||||
singleton::*,
|
||||
port::UpdateTask
|
||||
},
|
||||
buffer::singleton::*
|
||||
},
|
||||
laddertypes::{TypeTerm},
|
||||
crate::{
|
||||
repr_tree::{Context, ReprTree},
|
||||
repr_tree::{Context, ReprTree, ReprTreeExt},
|
||||
edit_tree::{EditTree, TreeNavResult},
|
||||
editors::ObjCommander,
|
||||
},
|
||||
|
@ -17,7 +18,6 @@ use {
|
|||
};
|
||||
|
||||
pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
|
||||
|
||||
let morphtype =
|
||||
crate::repr_tree::MorphismType {
|
||||
src_type: Context::parse(&ctx, "Char"),
|
||||
|
@ -37,19 +37,25 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
|
|||
|
||||
/* Create EditTree object
|
||||
*/
|
||||
let mut edittree_char = CharEditor::new_edit_tree(
|
||||
rt.view_char().0.update();
|
||||
|
||||
let char_buf = rt.write().unwrap().singleton_buffer::<char>().unwrap();
|
||||
|
||||
eprintln!("make edittree: char val = {}", char_buf.get());
|
||||
let mut edittree = CharEditor::new_edit_tree(
|
||||
ctx.clone(),
|
||||
SingletonBuffer::new('>'),
|
||||
char_buf,
|
||||
r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
|
||||
);
|
||||
|
||||
/* Insert EditTree into ReprTree
|
||||
*/
|
||||
let mut rt = rt.write().unwrap();
|
||||
rt.insert_leaf(
|
||||
vec![ Context::parse(&ctx, "EditTree") ].into_iter(),
|
||||
SingletonBuffer::new( Arc::new(RwLock::new( edittree_char )) ).get_port().into()
|
||||
);
|
||||
eprintln!("insert Char~EditTree");
|
||||
rt.write().unwrap()
|
||||
.insert_branch(
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&ctx, "EditTree"),
|
||||
SingletonBuffer::new(edittree)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -105,7 +111,7 @@ impl CharEditor {
|
|||
data: SingletonBuffer<char>,
|
||||
depth: OuterViewPort<dyn SingletonView<Item = usize>>
|
||||
) -> EditTree {
|
||||
let data = SingletonBuffer::new('\0');
|
||||
//let data = SingletonBuffer::new('\0');
|
||||
let ctx = ctx0.clone();
|
||||
let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.clone() }));
|
||||
|
||||
|
|
52
lib-nested-core/src/editors/digit/cmd.rs
Normal file
52
lib-nested-core/src/editors/digit/cmd.rs
Normal file
|
@ -0,0 +1,52 @@
|
|||
|
||||
use {
|
||||
r3vi::view::singleton::SingletonView,
|
||||
crate::{
|
||||
repr_tree::{ReprTree, Context},
|
||||
edit_tree::{TreeNav, TreeNavResult},
|
||||
editors::{ObjCommander, digit::DigitEditor}
|
||||
},
|
||||
|
||||
std::sync::{Arc, RwLock}
|
||||
};
|
||||
|
||||
impl ObjCommander for DigitEditor {
|
||||
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
|
||||
let cmd_obj = cmd_obj.read().unwrap();
|
||||
let cmd_type = cmd_obj.get_type().clone();
|
||||
|
||||
if cmd_type == Context::parse(&self.ctx, "Char") {
|
||||
if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
|
||||
let c = cmd_view.get();
|
||||
|
||||
self.msg.clear();
|
||||
|
||||
if self.ctx.read().unwrap().meta_chars.contains(&c) {
|
||||
return TreeNavResult::Exit;
|
||||
|
||||
} else if c.to_digit(self.radix).is_none() {
|
||||
/* in case the character c is not in the range of digit-chars,
|
||||
add a message to the diagnostics view
|
||||
*/
|
||||
/*
|
||||
let message = IndexBuffer::from_iter(vec![
|
||||
(Point2::new(1, 0), make_label("invalid digit '")),
|
||||
(Point2::new(2, 0), make_label(&format!("{}", c))
|
||||
.map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((140,140,250))))),
|
||||
(Point2::new(3, 0), make_label("'"))
|
||||
]);
|
||||
|
||||
self.msg.push(crate::diagnostics::make_error(message.get_port().flatten()));
|
||||
*/
|
||||
|
||||
self.data.set(c);
|
||||
} else {
|
||||
self.data.set(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TreeNavResult::Continue
|
||||
}
|
||||
}
|
||||
|
149
lib-nested-core/src/editors/digit/ctx.rs
Normal file
149
lib-nested-core/src/editors/digit/ctx.rs
Normal file
|
@ -0,0 +1,149 @@
|
|||
|
||||
use {
|
||||
laddertypes::TypeTerm,
|
||||
r3vi::{
|
||||
buffer::singleton::SingletonBuffer,
|
||||
view::{
|
||||
AnyOuterViewPort,
|
||||
singleton::*
|
||||
}
|
||||
},
|
||||
crate::{
|
||||
repr_tree::{Context, ReprTree, ReprTreeExt, ReprLeaf},
|
||||
editors::digit::DigitEditor,
|
||||
},
|
||||
std::sync::{Arc, RwLock}
|
||||
};
|
||||
|
||||
pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
|
||||
|
||||
// todo: proper scoping of Radix variable
|
||||
ctx.write().unwrap().add_varname("Radix");
|
||||
|
||||
let morphtype =
|
||||
crate::repr_tree::MorphismType {
|
||||
src_type: Context::parse(&ctx, "<Digit Radix>"),
|
||||
dst_type: Context::parse(&ctx, "<Digit Radix>~EditTree")
|
||||
};
|
||||
|
||||
ctx.write().unwrap()
|
||||
.morphisms
|
||||
.add_morphism(
|
||||
morphtype,
|
||||
{
|
||||
let ctx = ctx.clone();
|
||||
move |src_rt, σ| {
|
||||
let radix =
|
||||
match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) {
|
||||
Some(TypeTerm::Num(n)) => *n as u32,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
/* Create EditTree object
|
||||
*/
|
||||
let mut edittree = DigitEditor::new(
|
||||
ctx.clone(),
|
||||
radix,
|
||||
src_rt.descend(
|
||||
Context::parse(&ctx, "Char")
|
||||
).unwrap()
|
||||
.singleton_buffer::<char>()
|
||||
).into_node(
|
||||
r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
|
||||
);
|
||||
|
||||
src_rt.write().unwrap()
|
||||
.insert_branch(
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&ctx, "EditTree"),
|
||||
SingletonBuffer::new(edittree)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
let morphtype =
|
||||
crate::repr_tree::MorphismType {
|
||||
src_type: Context::parse(&ctx, "<Digit Radix>~Char"),
|
||||
dst_type: Context::parse(&ctx, "<Digit Radix>~ℤ_256~machine::UInt8")
|
||||
};
|
||||
|
||||
ctx.write().unwrap()
|
||||
.morphisms
|
||||
.add_morphism(
|
||||
morphtype,
|
||||
{
|
||||
let ctx = ctx.clone();
|
||||
move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| {
|
||||
/* infer radix from type
|
||||
*/
|
||||
let radix =
|
||||
match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) {
|
||||
Some(TypeTerm::Num(n)) => (*n) as u32,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
if radix <= 256 {
|
||||
|
||||
if let Some(src_rt) = rt.descend(Context::parse(&ctx, "Char")) {
|
||||
/* insert projected view into ReprTree
|
||||
*/
|
||||
let u8_view =
|
||||
src_rt.view_char()
|
||||
.map(move |c| c.to_digit(radix).unwrap_or(0) as u8);
|
||||
|
||||
rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = u8>>(
|
||||
Context::parse(&ctx, "ℤ_256~machine::UInt8").get_lnf_vec().into_iter(),
|
||||
u8_view
|
||||
);
|
||||
} else {
|
||||
eprintln!("could not find required source representation: <Digit {}>~Char", radix);
|
||||
}
|
||||
} else {
|
||||
eprintln!("radix too large ({})", radix);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
let morphtype =
|
||||
crate::repr_tree::MorphismType {
|
||||
src_type: Context::parse(&ctx, "<Digit Radix>~ℤ_256~machine::UInt8"),
|
||||
dst_type: Context::parse(&ctx, "<Digit Radix>~Char")
|
||||
};
|
||||
|
||||
ctx.write().unwrap().morphisms
|
||||
.add_morphism(morphtype, {
|
||||
let ctx = ctx.clone();
|
||||
move |rt: &mut Arc<RwLock<ReprTree>>, σ: &std::collections::HashMap<laddertypes::TypeID, TypeTerm>| {
|
||||
/* infer radix from type
|
||||
*/
|
||||
let radix =
|
||||
match σ.get( &laddertypes::TypeID::Var(ctx.read().unwrap().get_var_typeid("Radix").unwrap()) ) {
|
||||
Some(TypeTerm::Num(n)) => (*n) as u32,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
if radix <= 256 {
|
||||
/* insert projected view into ReprTree
|
||||
*/
|
||||
let char_view =
|
||||
rt.descend(Context::parse(&ctx, "ℤ_256~machine::UInt8"))
|
||||
.unwrap()
|
||||
.view_u8()
|
||||
.map(move |digit| char::from_digit(digit as u32, radix).unwrap_or('?'));
|
||||
|
||||
rt.write().unwrap().attach_leaf_to::<dyn SingletonView<Item = char>>(
|
||||
Context::parse(&ctx, "Char").get_lnf_vec().into_iter(),
|
||||
char_view
|
||||
);
|
||||
} else {
|
||||
eprintln!("radix too large ({})", radix);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
89
lib-nested-core/src/editors/digit/editor.rs
Normal file
89
lib-nested-core/src/editors/digit/editor.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
|
||||
use {
|
||||
laddertypes::TypeTerm,
|
||||
r3vi::{
|
||||
view::{OuterViewPort,singleton::*},
|
||||
buffer::{singleton::*, vec::*}
|
||||
},
|
||||
crate::{
|
||||
repr_tree::{ReprTree, Context},
|
||||
edit_tree::{
|
||||
EditTree,
|
||||
diagnostics::Message
|
||||
}
|
||||
},
|
||||
|
||||
std::sync::{Arc, RwLock}
|
||||
};
|
||||
|
||||
|
||||
pub struct DigitEditor {
|
||||
pub(super) ctx: Arc<RwLock<Context>>,
|
||||
pub(super) radix: u32,
|
||||
pub(super) data: SingletonBuffer<char>,
|
||||
pub(super) msg: VecBuffer<Message>,
|
||||
}
|
||||
|
||||
|
||||
impl DigitEditor {
|
||||
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32, data: SingletonBuffer<char>) -> Self {
|
||||
DigitEditor {
|
||||
ctx,
|
||||
radix,
|
||||
data,
|
||||
msg: VecBuffer::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_node(self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree {
|
||||
// let data = self.get_data();
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
let ed = editor.write().unwrap();
|
||||
let r = ed.radix;
|
||||
|
||||
EditTree::new(ed.ctx.clone(), depth)
|
||||
.set_editor(editor.clone())
|
||||
.set_cmd(editor.clone())
|
||||
.set_diag(
|
||||
ed.msg.get_port().to_sequence()
|
||||
)
|
||||
}
|
||||
|
||||
pub fn attach_to(&mut self, source: OuterViewPort<dyn SingletonView<Item = u32>>) {
|
||||
/*
|
||||
source.add_observer(
|
||||
Arc::new(NotifyFnObserver::new(|_msg| {
|
||||
self.data.set( source.get() )
|
||||
}))
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
pub fn get_data_port(&self) -> OuterViewPort<dyn SingletonView<Item = Result<u32, char>>> {
|
||||
let radix = self.radix;
|
||||
self.data.get_port().map(move |c|
|
||||
if let Some(d) = c.to_digit(radix) {
|
||||
Ok(d)
|
||||
} else {
|
||||
Err(c)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> TypeTerm {
|
||||
TypeTerm::TypeID(self.ctx.read().unwrap().get_typeid("Digit").unwrap())
|
||||
}
|
||||
/*
|
||||
pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
|
||||
ReprTree::ascend(
|
||||
&ReprTree::from_view(
|
||||
self.ctx.read().unwrap().type_term_from_str("<Seq u32>").unwrap(),
|
||||
self.get_data_port()
|
||||
),
|
||||
self.get_type()
|
||||
)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
8
lib-nested-core/src/editors/digit/mod.rs
Normal file
8
lib-nested-core/src/editors/digit/mod.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
pub mod ctx;
|
||||
pub mod cmd;
|
||||
pub mod editor;
|
||||
|
||||
pub use editor::DigitEditor;
|
||||
pub use ctx::init_ctx;
|
||||
|
|
@ -24,10 +24,9 @@ pub enum ListCmd {
|
|||
impl ListCmd {
|
||||
// note: cant use Into becaue of ctx (maybe global typedict?)
|
||||
pub fn into_repr_tree(self, ctx: &Arc<RwLock<Context>>) -> Arc<RwLock<ReprTree>> {
|
||||
let buf = r3vi::buffer::singleton::SingletonBuffer::new(self);
|
||||
ReprTree::new_leaf(
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(ctx, "ListCmd"),
|
||||
buf.get_port().into()
|
||||
r3vi::buffer::singleton::SingletonBuffer::new(self)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use {
|
|||
r3vi::{view::{OuterViewPort, singleton::*}, buffer::singleton::*},
|
||||
laddertypes::{TypeTerm},
|
||||
crate::{
|
||||
repr_tree::{Context},
|
||||
repr_tree::{Context, ReprTree},
|
||||
editors::list::{ListEditor}//, PTYListController, PTYListStyle}
|
||||
},
|
||||
std::sync::{Arc, RwLock}
|
||||
|
@ -13,6 +13,7 @@ use {
|
|||
pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
|
||||
ctx.write().unwrap().add_list_typename("List".into());
|
||||
ctx.write().unwrap().add_varname("Item");
|
||||
|
||||
let mt = crate::repr_tree::MorphismType {
|
||||
src_type: Context::parse(&ctx, "<List Item>"),
|
||||
dst_type: Context::parse(&ctx, "<List Item>~EditTree")
|
||||
|
@ -21,9 +22,10 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
|
|||
mt,
|
||||
{
|
||||
let ctx = ctx.clone();
|
||||
move |rt, σ| {
|
||||
move |src_rt, σ| {
|
||||
let item_id = laddertypes::TypeID::Var( ctx.read().unwrap().get_var_typeid("Item").unwrap() );
|
||||
if let Some( item_type ) = σ.get( &item_id ) {
|
||||
|
||||
let mut edittree_list = ListEditor::new(
|
||||
ctx.clone(),
|
||||
item_type.clone()
|
||||
|
@ -31,10 +33,11 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
|
|||
r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
|
||||
);
|
||||
|
||||
let mut rt = rt.write().unwrap();
|
||||
rt.insert_leaf(
|
||||
vec![ Context::parse(&ctx, "EditTree") ].into_iter(),
|
||||
SingletonBuffer::new( Arc::new(RwLock::new( edittree_list )) ).get_port().into()
|
||||
src_rt.write().unwrap().insert_branch(
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&ctx, "EditTree"),
|
||||
SingletonBuffer::new(edittree_list)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
eprintln!("no item type");
|
||||
|
|
|
@ -101,7 +101,6 @@ impl ListEditor {
|
|||
}
|
||||
|
||||
pub fn into_node(mut self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree {
|
||||
let data = self.get_data();
|
||||
let ctx = self.ctx.clone();
|
||||
|
||||
self.depth = depth.clone();
|
||||
|
@ -155,7 +154,7 @@ impl ListEditor {
|
|||
|x| x.read().unwrap().clone()
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
|
||||
let data_view = self.get_data_port();
|
||||
ReprTree::new_leaf(
|
||||
|
@ -163,7 +162,7 @@ impl ListEditor {
|
|||
data_view.into()
|
||||
)
|
||||
}
|
||||
|
||||
*/
|
||||
pub fn get_item(&self) -> Option<EditTree> {
|
||||
if let Some(idx) = self.cursor.get().idx {
|
||||
let idx = crate::utils::modulo(idx as isize, self.data.len() as isize) as usize;
|
||||
|
@ -309,22 +308,23 @@ impl ListEditor {
|
|||
let mut b = item.ctrl.spillbuf.write().unwrap();
|
||||
|
||||
let rt = ReprTree::new_arc(self.typ.clone());
|
||||
let new_edittree = self.ctx.read().unwrap()
|
||||
let edittree = self.ctx.read().unwrap()
|
||||
.setup_edittree(
|
||||
rt,
|
||||
self.depth.map(|d| d+1)
|
||||
);
|
||||
let mut tail_node = new_edittree.write().unwrap();
|
||||
|
||||
let mut tail_node = edittree.get_mut();
|
||||
tail_node.goto(TreeCursor::home());
|
||||
|
||||
for node in b.iter() {
|
||||
tail_node
|
||||
.send_cmd_obj(
|
||||
ReprTree::new_leaf(
|
||||
Context::parse(&self.ctx, "NestedNode"),
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&self.ctx, "EditTree"),
|
||||
SingletonBuffer::<EditTree>::new(
|
||||
node.read().unwrap().clone()
|
||||
).get_port().into()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ impl ListEditor {
|
|||
drop(tail_node);
|
||||
|
||||
self.insert(
|
||||
new_edittree
|
||||
edittree.value.clone()
|
||||
);
|
||||
|
||||
} else {
|
||||
|
@ -376,11 +376,11 @@ impl ListEditor {
|
|||
let data = cur_editor.ctrl.spillbuf.read().unwrap();
|
||||
for x in data.iter() {
|
||||
pxv_editor.send_cmd_obj(
|
||||
ReprTree::new_leaf(
|
||||
Context::parse(&self.ctx, "NestedNode"),
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&self.ctx, "EditTree"),
|
||||
SingletonBuffer::<EditTree>::new(
|
||||
x.read().unwrap().clone()
|
||||
).get_port().into()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -435,11 +435,11 @@ impl ListEditor {
|
|||
|
||||
for x in data.iter() {
|
||||
cur_editor.send_cmd_obj(
|
||||
ReprTree::new_leaf(
|
||||
Context::parse(&self.ctx, "NestedNode"),
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&self.ctx, "EditTree"),
|
||||
SingletonBuffer::<EditTree>::new(
|
||||
x.read().unwrap().clone()
|
||||
).get_port().into()
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use {
|
|||
r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}},
|
||||
laddertypes::{TypeDict, TypeTerm, TypeID},
|
||||
crate::{
|
||||
repr_tree::{ReprTree, MorphismType, GenericReprTreeMorphism, MorphismBase},
|
||||
repr_tree::{ReprTree, ReprTreeExt, MorphismType, GenericReprTreeMorphism, MorphismBase},
|
||||
edit_tree::EditTree
|
||||
},
|
||||
std::{
|
||||
|
@ -29,7 +29,7 @@ pub struct Context {
|
|||
pub list_types: Vec< TypeID >,
|
||||
pub meta_chars: Vec< char >,
|
||||
|
||||
edittree_hook: Arc< dyn Fn(Arc<RwLock<EditTree>>, TypeTerm) + Send +Sync +'static >,
|
||||
edittree_hook: Arc< dyn Fn(&mut EditTree, TypeTerm) + Send +Sync +'static >,
|
||||
|
||||
/// recursion
|
||||
parent: Option<Arc<RwLock<Context>>>,
|
||||
|
@ -64,7 +64,7 @@ impl Context {
|
|||
Context::with_parent(None)
|
||||
}
|
||||
|
||||
pub fn set_edittree_hook(&mut self, hook: Arc< dyn Fn(Arc<RwLock<EditTree>>, TypeTerm) + Send +Sync +'static >) {
|
||||
pub fn set_edittree_hook(&mut self, hook: Arc< dyn Fn(&mut EditTree, TypeTerm) + Send +Sync +'static >) {
|
||||
self.edittree_hook = hook;
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ impl Context {
|
|||
|
||||
pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> Arc<RwLock<ReprTree>> {
|
||||
let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() )));
|
||||
ctx.read().unwrap().morphisms.morph( rt.clone(), t );
|
||||
ctx.read().unwrap().morphisms.apply_morphism( rt.clone(), &TypeTerm::unit(), t );
|
||||
rt
|
||||
}
|
||||
|
||||
|
@ -180,30 +180,32 @@ impl Context {
|
|||
&self,
|
||||
rt: Arc<RwLock<ReprTree>>,
|
||||
depth: OuterViewPort<dyn SingletonView<Item = usize>>
|
||||
) -> Arc<RwLock<EditTree>> {
|
||||
) -> SingletonBuffer<EditTree> {
|
||||
let ladder = TypeTerm::Ladder(vec![
|
||||
rt.read().unwrap().get_type().clone(),
|
||||
self.type_term_from_str("EditTree").expect("")
|
||||
]);
|
||||
|
||||
self.morphisms.morph(
|
||||
eprintln!("setp_edittree: apply morphism T -> T~EditTree");
|
||||
self.morphisms.apply_morphism(
|
||||
rt.clone(),
|
||||
&rt.get_type(),
|
||||
&ladder
|
||||
);
|
||||
|
||||
let new_edittree = rt
|
||||
.read().unwrap()
|
||||
.descend(
|
||||
self.type_term_from_str("EditTree").expect("")
|
||||
).unwrap()
|
||||
.read().unwrap()
|
||||
.get_view::<dyn SingletonView<Item = Arc<RwLock<EditTree>> >>()
|
||||
.unwrap()
|
||||
.get();
|
||||
|
||||
(*self.edittree_hook)( new_edittree.clone(), rt.read().unwrap().get_type().clone() );
|
||||
|
||||
new_edittree
|
||||
eprintln!("get repr-node of editTree");
|
||||
if let Some(new_edittree) =
|
||||
rt.descend(self.type_term_from_str("EditTree").unwrap())
|
||||
{
|
||||
let buf = new_edittree.singleton_buffer::<EditTree>();
|
||||
(*self.edittree_hook)(
|
||||
&mut *buf.get_mut(),
|
||||
rt.read().unwrap().get_type().clone()
|
||||
);
|
||||
buf
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,50 @@
|
|||
pub mod context;
|
||||
pub mod morphism;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use {
|
||||
context::{Context},
|
||||
morphism::{MorphismType, GenericReprTreeMorphism, MorphismBase}
|
||||
};
|
||||
|
||||
use {
|
||||
r3vi::view::{AnyOuterViewPort, OuterViewPort, View, singleton::*},
|
||||
r3vi::{
|
||||
view::{
|
||||
ViewPort, OuterViewPort,
|
||||
AnyViewPort, AnyInnerViewPort, AnyOuterViewPort,
|
||||
port::UpdateTask,
|
||||
View,
|
||||
singleton::*, sequence::*
|
||||
},
|
||||
buffer::{singleton::*, vec::*}
|
||||
},
|
||||
laddertypes::{TypeTerm},
|
||||
std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, RwLock},
|
||||
any::Any
|
||||
},
|
||||
};
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ReprLeaf {
|
||||
out_port: AnyViewPort,
|
||||
in_port: AnyInnerViewPort,
|
||||
data: Option< Arc<dyn Any + Send + Sync> >,
|
||||
|
||||
/// keepalive for the observer that updates the buffer from in_port
|
||||
keepalive: Option<Arc<dyn Any + Send + Sync>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ReprTree {
|
||||
type_tag: TypeTerm,
|
||||
port: Option<AnyOuterViewPort>,
|
||||
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
|
||||
leaf: Option< ReprLeaf >
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
@ -38,18 +61,282 @@ impl std::fmt::Debug for ReprTree {
|
|||
}
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
impl ReprLeaf {
|
||||
pub fn from_view<V>( src_port: OuterViewPort<V> ) -> Self
|
||||
where V: View + ?Sized + 'static,
|
||||
V::Msg: Clone
|
||||
{
|
||||
let mut in_port = ViewPort::<V>::new();
|
||||
in_port.attach_to(src_port);
|
||||
|
||||
let mut buf_port = ViewPort::<V>::new();
|
||||
buf_port.attach_to(in_port.outer());
|
||||
|
||||
ReprLeaf {
|
||||
keepalive: None,
|
||||
in_port: in_port.inner().into(),
|
||||
out_port: buf_port.into(),
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn attach_to<V>(&mut self, src_port: OuterViewPort<V>)
|
||||
where V: View + ?Sized + 'static,
|
||||
V::Msg: Clone
|
||||
{
|
||||
self.in_port.clone()
|
||||
.downcast::<V>().ok().unwrap()
|
||||
.0.attach_to( src_port );
|
||||
}
|
||||
|
||||
pub fn from_singleton_buffer<T>( buffer: SingletonBuffer<T> ) -> Self
|
||||
where T: Clone + Send + Sync + 'static
|
||||
{
|
||||
let in_port = ViewPort::<dyn SingletonView<Item = T>>::new();
|
||||
ReprLeaf {
|
||||
keepalive: Some(buffer.attach_to(in_port.outer())),
|
||||
in_port: in_port.inner().into(),
|
||||
out_port: buffer.get_port().0.into(),
|
||||
data: Some(buffer.into_inner())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_singleton_buffer<T>(&mut self) -> Option<SingletonBuffer<T>>
|
||||
where T: Clone + Send + Sync + 'static
|
||||
{
|
||||
let sgl_port = self.get_port::< dyn SingletonView<Item = T> >().unwrap().0;
|
||||
|
||||
let data_arc =
|
||||
if let Some(data) = self.data.as_ref() {
|
||||
data.clone().downcast::<RwLock<T>>().ok()
|
||||
} else {
|
||||
sgl_port.update();
|
||||
let value = sgl_port.outer().get_view().unwrap().get();
|
||||
eprintln!("make new data ARC from old value");
|
||||
Some(Arc::new(RwLock::new( value )))
|
||||
};
|
||||
|
||||
if let Some(data_arc) = data_arc {
|
||||
self.data = Some(data_arc.clone() as Arc<dyn Any + Send + Sync>);
|
||||
let buf = SingletonBuffer {
|
||||
value: data_arc,
|
||||
port: sgl_port.inner()
|
||||
};
|
||||
self.keepalive = Some(buf.attach_to(
|
||||
self.in_port.0.clone()
|
||||
.downcast::<dyn SingletonView<Item = T>>()
|
||||
.ok().unwrap()
|
||||
.outer()
|
||||
));
|
||||
Some(buf)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_port<V>(&self) -> Option<OuterViewPort<V>>
|
||||
where V: View + ?Sized + 'static,
|
||||
V::Msg: Clone
|
||||
{
|
||||
self.out_port.clone().downcast::<V>().ok().map(|p| p.outer())
|
||||
}
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
impl ReprTree {
|
||||
pub fn new(type_tag: impl Into<TypeTerm>) -> Self {
|
||||
ReprTree {
|
||||
type_tag: type_tag.into(),
|
||||
branches: HashMap::new(),
|
||||
leaf: None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_arc(type_tag: impl Into<TypeTerm>) -> Arc<RwLock<Self>> {
|
||||
Arc::new(RwLock::new(Self::new(type_tag)))
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> &TypeTerm {
|
||||
&self.type_tag
|
||||
}
|
||||
|
||||
pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) {
|
||||
self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone());
|
||||
}
|
||||
|
||||
pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char ) -> Arc<RwLock<Self>> {
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(ctx, "Char"),
|
||||
SingletonBuffer::new(c)
|
||||
)
|
||||
}
|
||||
|
||||
pub fn from_view<V>( type_tag: impl Into<TypeTerm>, view: OuterViewPort<V> ) -> Arc<RwLock<Self>>
|
||||
where V: View + ?Sized + 'static,
|
||||
V::Msg: Clone
|
||||
{
|
||||
let mut rt = ReprTree::new(type_tag);
|
||||
rt.leaf = Some(ReprLeaf::from_view(view));
|
||||
Arc::new(RwLock::new(rt))
|
||||
}
|
||||
|
||||
pub fn from_singleton_buffer<T>( type_tag: impl Into<TypeTerm>, buf: SingletonBuffer<T> ) -> Arc<RwLock<Self>>
|
||||
where T: Clone + Send + Sync + 'static
|
||||
{
|
||||
let mut rt = ReprTree::new(type_tag);
|
||||
rt.leaf = Some(ReprLeaf::from_singleton_buffer(buf));
|
||||
Arc::new(RwLock::new(rt))
|
||||
}
|
||||
|
||||
/// find, and if necessary, create corresponding path in repr-tree.
|
||||
/// Attach src_port to input of that node
|
||||
pub fn attach_leaf_to<V>(
|
||||
&mut self,
|
||||
mut type_ladder: impl Iterator<Item = TypeTerm>,
|
||||
src_port: OuterViewPort<V>
|
||||
)
|
||||
where V: View + ?Sized + 'static,
|
||||
V::Msg: Clone
|
||||
{
|
||||
if let Some(rung_type) = type_ladder.next() {
|
||||
if let Some(next_repr) = self.branches.get(&rung_type) {
|
||||
next_repr.write().unwrap().attach_leaf_to(type_ladder, src_port);
|
||||
} else {
|
||||
let mut next_repr = ReprTree::new(rung_type.clone());
|
||||
next_repr.attach_leaf_to(type_ladder, src_port);
|
||||
self.insert_branch(Arc::new(RwLock::new(next_repr)));
|
||||
}
|
||||
} else {
|
||||
if let Some(leaf) = self.leaf.as_mut() {
|
||||
leaf.attach_to(src_port);
|
||||
} else {
|
||||
self.leaf = Some(ReprLeaf::from_view(src_port));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_leaf(
|
||||
&mut self,
|
||||
mut type_ladder: impl Iterator<Item = TypeTerm>,
|
||||
leaf: ReprLeaf
|
||||
) {
|
||||
if let Some(type_term) = type_ladder.next() {
|
||||
if let Some(next_repr) = self.branches.get(&type_term) {
|
||||
next_repr.write().unwrap().insert_leaf(type_ladder, leaf);
|
||||
} else {
|
||||
let mut next_repr = ReprTree::new(type_term.clone());
|
||||
next_repr.insert_leaf(type_ladder, leaf);
|
||||
self.insert_branch(Arc::new(RwLock::new(next_repr)));
|
||||
}
|
||||
} else {
|
||||
self.leaf = Some(leaf)
|
||||
}
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub fn descend_one(&self, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
|
||||
let dst_type = dst_type.into();
|
||||
assert!( dst_type.is_flat() );
|
||||
self.branches.get(&dst_type).cloned()
|
||||
}
|
||||
|
||||
pub fn descend_ladder(rt: &Arc<RwLock<Self>>, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
|
||||
if let Some(first) = repr_ladder.next() {
|
||||
let rt = rt.read().unwrap();
|
||||
repr_ladder.fold(
|
||||
rt.descend_one(first),
|
||||
|s, t| s?.descend(t))
|
||||
} else {
|
||||
Some(rt.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn descend(rt: &Arc<RwLock<Self>>, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
|
||||
ReprTree::descend_ladder(rt, dst_type.into().get_lnf_vec().into_iter())
|
||||
}
|
||||
|
||||
pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> {
|
||||
let mut n = Self::new(type_term);
|
||||
n.insert_branch(rt.clone());
|
||||
Arc::new(RwLock::new(n))
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub fn singleton_buffer<T: Clone + Send + Sync + 'static>(&mut self) -> Option<SingletonBuffer<T>> {
|
||||
if let Some(leaf) = self.leaf.as_mut() {
|
||||
leaf.as_singleton_buffer::<T>()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> Option<VecBuffer<T>> {
|
||||
}
|
||||
*/
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
|
||||
where
|
||||
V::Msg: Clone,
|
||||
{
|
||||
if let Some(leaf) = self.leaf.as_ref() {
|
||||
leaf.get_port::<V>()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>>
|
||||
where
|
||||
V::Msg: Clone,
|
||||
{
|
||||
self.get_port::<V>()?
|
||||
.get_view()
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub fn view_seq<T: 'static>(&self) -> OuterViewPort<dyn SequenceView<Item = T>> {
|
||||
self.get_port::<dyn SequenceView<Item = T>>().expect("no sequence-view available")
|
||||
}
|
||||
|
||||
pub fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
|
||||
self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available")
|
||||
}
|
||||
|
||||
pub fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> {
|
||||
self.get_port::<dyn SingletonView<Item = u8>>().expect("no u8-view available")
|
||||
}
|
||||
|
||||
pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> {
|
||||
self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
pub trait ReprTreeExt {
|
||||
fn get_type(&self) -> TypeTerm;
|
||||
|
||||
fn insert_leaf(&mut self, type_ladder: impl Iterator<Item = TypeTerm>, port: AnyOuterViewPort);
|
||||
fn insert_leaf(&mut self, type_ladder: impl Into<TypeTerm>, leaf: ReprLeaf);
|
||||
fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>);
|
||||
|
||||
fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>;
|
||||
fn descend_ladder(&self, ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>>;
|
||||
|
||||
fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>>;
|
||||
fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>>;
|
||||
fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>;
|
||||
|
||||
fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T>;
|
||||
// fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T>;
|
||||
}
|
||||
|
||||
impl ReprTreeExt for Arc<RwLock<ReprTree>> {
|
||||
|
@ -57,8 +344,8 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
|
|||
self.read().unwrap().get_type().clone()
|
||||
}
|
||||
|
||||
fn insert_leaf(&mut self, type_ladder: impl Iterator<Item = TypeTerm>, port: AnyOuterViewPort) {
|
||||
self.write().unwrap().insert_leaf(type_ladder, port)
|
||||
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)
|
||||
}
|
||||
|
||||
fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) {
|
||||
|
@ -66,11 +353,7 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
|
|||
}
|
||||
|
||||
fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
|
||||
self.read().unwrap().descend(target_type)
|
||||
}
|
||||
|
||||
fn descend_ladder(&self, ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
|
||||
ReprTree::descend_ladder(self, ladder)
|
||||
ReprTree::descend( self, target_type )
|
||||
}
|
||||
|
||||
fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
|
||||
|
@ -84,125 +367,16 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
|
|||
fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> {
|
||||
self.read().unwrap().view_u64()
|
||||
}
|
||||
|
||||
fn singleton_buffer<T: Clone + Send + Sync + 'static>(&self) -> SingletonBuffer<T> {
|
||||
self.write().unwrap().singleton_buffer::<T>().expect("")
|
||||
}
|
||||
/*
|
||||
fn vec_buffer<T: Clone + Send + Sync + 'static>(&self) -> VecBuffer<T> {
|
||||
self.read().unwrap().vec_buffer::<T>().expect("")
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
impl ReprTree {
|
||||
pub fn new(type_tag: impl Into<TypeTerm>) -> Self {
|
||||
ReprTree {
|
||||
type_tag: type_tag.into(),
|
||||
port: None,
|
||||
branches: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_arc(type_tag: impl Into<TypeTerm>) -> Arc<RwLock<Self>> {
|
||||
Arc::new(RwLock::new(Self::new(type_tag)))
|
||||
}
|
||||
|
||||
pub fn get_type(&self) -> &TypeTerm {
|
||||
&self.type_tag
|
||||
}
|
||||
|
||||
pub fn from_char(ctx: &Arc<RwLock<Context>>, c: char) -> Arc<RwLock<Self>> {
|
||||
let buf = r3vi::buffer::singleton::SingletonBuffer::<char>::new(c);
|
||||
ReprTree::new_leaf(
|
||||
Context::parse(ctx, "Char"),
|
||||
buf.get_port().into()
|
||||
)
|
||||
}
|
||||
|
||||
pub fn from_u64(ctx: &Arc<RwLock<Context>>, v: u64) -> Arc<RwLock<Self>> {
|
||||
let buf = r3vi::buffer::singleton::SingletonBuffer::<u64>::new(v);
|
||||
ReprTree::new_leaf(
|
||||
Context::parse(ctx, "<MachineInt 64>"),
|
||||
buf.get_port().into()
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_leaf(type_tag: impl Into<TypeTerm>, port: AnyOuterViewPort) -> Arc<RwLock<Self>> {
|
||||
let mut tree = ReprTree::new(type_tag.into());
|
||||
tree.insert_leaf(vec![].into_iter(), port);
|
||||
Arc::new(RwLock::new(tree))
|
||||
}
|
||||
|
||||
pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) {
|
||||
self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone());
|
||||
}
|
||||
|
||||
pub fn insert_leaf(
|
||||
&mut self,
|
||||
mut type_ladder: impl Iterator<Item = TypeTerm>,
|
||||
port: AnyOuterViewPort,
|
||||
) {
|
||||
if let Some(type_term) = type_ladder.next() {
|
||||
if let Some(next_repr) = self.branches.get(&type_term) {
|
||||
next_repr.write().unwrap().insert_leaf(type_ladder, port);
|
||||
} else {
|
||||
let mut next_repr = ReprTree::new(type_term.clone());
|
||||
next_repr.insert_leaf(type_ladder, port);
|
||||
self.insert_branch(Arc::new(RwLock::new(next_repr)));
|
||||
}
|
||||
} else {
|
||||
self.port = Some(port);
|
||||
}
|
||||
}
|
||||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
|
||||
pub fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
|
||||
self.get_port::<dyn SingletonView<Item = char>>().expect("no char-view available")
|
||||
}
|
||||
|
||||
pub fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> {
|
||||
self.get_port::<dyn SingletonView<Item = u8>>().expect("no u8-view available")
|
||||
}
|
||||
|
||||
pub fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> {
|
||||
self.get_port::<dyn SingletonView<Item = u64>>().expect("no u64-view available")
|
||||
}
|
||||
|
||||
pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
|
||||
where
|
||||
V::Msg: Clone,
|
||||
{
|
||||
Some(
|
||||
self.port
|
||||
.clone()?
|
||||
.downcast::<V>()
|
||||
.ok()?
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>>
|
||||
where
|
||||
V::Msg: Clone,
|
||||
{
|
||||
self.get_port::<V>()?
|
||||
.get_view()
|
||||
}
|
||||
|
||||
pub fn descend(&self, dst_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
|
||||
self.branches.get(&dst_type.into()).cloned()
|
||||
}
|
||||
|
||||
pub fn descend_ladder(rt: &Arc<RwLock<Self>>, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
|
||||
if let Some(first) = repr_ladder.next() {
|
||||
let rt = rt.read().unwrap();
|
||||
repr_ladder.fold(
|
||||
rt.descend(first),
|
||||
|s, t| s?.read().unwrap().descend(t))
|
||||
} else {
|
||||
Some(rt.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ascend(rt: &Arc<RwLock<Self>>, type_term: impl Into<TypeTerm>) -> Arc<RwLock<ReprTree>> {
|
||||
let mut n = Self::new(type_term);
|
||||
n.insert_branch(rt.clone());
|
||||
Arc::new(RwLock::new(n))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use {
|
||||
laddertypes::{TypeTerm, TypeID},
|
||||
r3vi::view::AnyOuterViewPort,
|
||||
crate::{
|
||||
repr_tree::{ReprTree},
|
||||
repr_tree::{ReprTree, ReprTreeExt, ReprLeaf},
|
||||
},
|
||||
std::{
|
||||
sync::{Arc, RwLock},
|
||||
|
@ -20,8 +21,9 @@ pub struct MorphismType {
|
|||
#[derive(Clone)]
|
||||
pub struct GenericReprTreeMorphism {
|
||||
morph_type: MorphismType,
|
||||
repr_tree_op: Arc<
|
||||
dyn Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> )
|
||||
setup_projection: Arc<
|
||||
dyn Fn( &mut Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> )
|
||||
// -> Result< ReprLeaf, () >
|
||||
+ Send + Sync
|
||||
>
|
||||
}
|
||||
|
@ -43,12 +45,15 @@ impl MorphismBase {
|
|||
pub fn add_morphism(
|
||||
&mut self,
|
||||
morph_type: MorphismType,
|
||||
repr_tree_op: impl Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> ) + Send + Sync + 'static
|
||||
setup_projection:
|
||||
impl Fn( &mut Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> )
|
||||
// -> Result< ReprLeaf, () /* TODO: error */ >
|
||||
+ Send + Sync + 'static
|
||||
) {
|
||||
self.morphisms.push(
|
||||
GenericReprTreeMorphism {
|
||||
morph_type,
|
||||
repr_tree_op: Arc::new(repr_tree_op)
|
||||
setup_projection: Arc::new(setup_projection)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -75,14 +80,15 @@ impl MorphismBase {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn morph(
|
||||
pub fn apply_morphism(
|
||||
&self,
|
||||
repr_tree: Arc<RwLock<ReprTree>>,
|
||||
target_type: &TypeTerm
|
||||
mut repr_tree: Arc<RwLock<ReprTree>>,
|
||||
src_type: &TypeTerm,
|
||||
dst_type: &TypeTerm
|
||||
) {
|
||||
let t = repr_tree.read().unwrap().get_type().clone();
|
||||
if let Some((m, σ)) = self.find_morphism( &t, target_type ) {
|
||||
(m.repr_tree_op)( repr_tree.clone(), &σ );
|
||||
// let t = repr_tree.read().unwrap().get_type().clone();
|
||||
if let Some((m, σ)) = self.find_morphism( &src_type, dst_type ) {
|
||||
(m.setup_projection)( &mut repr_tree, &σ );
|
||||
} else {
|
||||
eprintln!("could not find morphism");
|
||||
}
|
||||
|
|
168
lib-nested-core/src/repr_tree/tests.rs
Normal file
168
lib-nested-core/src/repr_tree/tests.rs
Normal file
|
@ -0,0 +1,168 @@
|
|||
|
||||
use {
|
||||
r3vi::{
|
||||
buffer::singleton::{
|
||||
SingletonBuffer
|
||||
},
|
||||
view::port::UpdateTask
|
||||
},
|
||||
crate::{
|
||||
repr_tree::{Context, ReprTreeExt, ReprTree, ReprLeaf}
|
||||
},
|
||||
std::sync::{Arc, RwLock}
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn char_view() {
|
||||
let ctx = Arc::new(RwLock::new(Context::new()));
|
||||
crate::editors::digit::init_ctx( ctx.clone() );
|
||||
|
||||
let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
|
||||
rt_digit.insert_leaf(
|
||||
Context::parse(&ctx, "Char"),
|
||||
ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') )
|
||||
);
|
||||
|
||||
//<><><><>
|
||||
let mut digit_char_buffer = rt_digit
|
||||
.descend( Context::parse(&ctx, "Char") ).unwrap()
|
||||
.singleton_buffer::<char>();
|
||||
|
||||
assert_eq!( digit_char_buffer.get(), '5' );
|
||||
//<><><><>
|
||||
|
||||
let digit_char_view = rt_digit
|
||||
.descend(Context::parse(&ctx, "Char")).unwrap()
|
||||
.view_char();
|
||||
|
||||
assert_eq!( digit_char_view.get_view().unwrap().get(), '5' );
|
||||
|
||||
|
||||
//<><><><>
|
||||
// `Char-view` is correctly coupled to `char-buffer`
|
||||
digit_char_buffer.set('2');
|
||||
assert_eq!( digit_char_view.get_view().unwrap().get(), '2' );
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn digit_projection_char_to_u8() {
|
||||
let ctx = Arc::new(RwLock::new(Context::new()));
|
||||
crate::editors::digit::init_ctx( ctx.clone() );
|
||||
|
||||
let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
|
||||
|
||||
rt_digit.insert_leaf(
|
||||
Context::parse(&ctx, "Char"),
|
||||
ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') )
|
||||
);
|
||||
|
||||
//<><><><>
|
||||
// add another representation
|
||||
|
||||
ctx.read().unwrap().morphisms.apply_morphism(
|
||||
rt_digit.clone(),
|
||||
&Context::parse(&ctx, "<Digit 16>~Char"),
|
||||
&Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8")
|
||||
);
|
||||
|
||||
let digit_u8_view = rt_digit
|
||||
.descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap()
|
||||
.view_u8();
|
||||
|
||||
assert_eq!( digit_u8_view.get_view().unwrap().get(), 5 as u8 );
|
||||
|
||||
|
||||
// projection behaves accordingly , when buffer is changed
|
||||
|
||||
let mut digit_char_buffer = rt_digit
|
||||
.descend( Context::parse(&ctx, "Char") ).unwrap()
|
||||
.singleton_buffer::<char>();
|
||||
|
||||
digit_char_buffer.set('2');
|
||||
assert_eq!( digit_u8_view.get_view().unwrap().get(), 2 as u8 );
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn digit_projection_u8_to_char() {
|
||||
let ctx = Arc::new(RwLock::new(Context::new()));
|
||||
crate::editors::digit::init_ctx( ctx.clone() );
|
||||
|
||||
let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
|
||||
|
||||
rt_digit.insert_leaf(
|
||||
Context::parse(&ctx, "ℤ_256~machine::UInt8"),
|
||||
ReprLeaf::from_singleton_buffer( SingletonBuffer::new(5 as u8) )
|
||||
);
|
||||
|
||||
//<><><><>
|
||||
// add another representation
|
||||
|
||||
ctx.read().unwrap().morphisms.apply_morphism(
|
||||
rt_digit.clone(),
|
||||
&Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8"),
|
||||
&Context::parse(&ctx, "<Digit 16>~Char")
|
||||
);
|
||||
|
||||
let digit_u8_view = rt_digit
|
||||
.descend(Context::parse(&ctx, "Char")).unwrap()
|
||||
.view_char();
|
||||
|
||||
assert_eq!( digit_u8_view.get_view().unwrap().get(), '5' );
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn char_buffered_projection() {
|
||||
let ctx = Arc::new(RwLock::new(Context::new()));
|
||||
crate::editors::digit::init_ctx( ctx.clone() );
|
||||
|
||||
let mut rt_digit = ReprTree::new_arc( Context::parse(&ctx, "<Digit 16>") );
|
||||
|
||||
rt_digit.insert_leaf(
|
||||
Context::parse(&ctx, "ℤ_256~machine::UInt8"),
|
||||
ReprLeaf::from_singleton_buffer( SingletonBuffer::new(8 as u8) )
|
||||
);
|
||||
|
||||
let mut digit_u8_buffer = rt_digit
|
||||
.descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap()
|
||||
.singleton_buffer::<u8>();
|
||||
|
||||
assert_eq!( digit_u8_buffer.get(), 8 );
|
||||
|
||||
rt_digit.insert_leaf(
|
||||
Context::parse(&ctx, "Char"),
|
||||
ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') )
|
||||
);
|
||||
|
||||
let digit_char_buf = rt_digit
|
||||
.descend(Context::parse(&ctx, "Char")).unwrap()
|
||||
.singleton_buffer::<char>();
|
||||
let digit_char_view = rt_digit
|
||||
.descend(Context::parse(&ctx, "Char")).unwrap()
|
||||
.view_char();
|
||||
|
||||
// before setting up the morphism, char-view remains as initialized
|
||||
assert_eq!( digit_char_buf.get(), '5' );
|
||||
assert_eq!( digit_char_view.get_view().unwrap().get(), '5' );
|
||||
|
||||
// now we attach the char-repr to the u8-repr
|
||||
ctx.read().unwrap().morphisms.apply_morphism(
|
||||
rt_digit.clone(),
|
||||
&Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8"),
|
||||
&Context::parse(&ctx, "<Digit 16>~Char")
|
||||
);
|
||||
|
||||
// char buffer and view should now follow the u8-buffer
|
||||
assert_eq!( digit_char_view.get_view().unwrap().get(), '8' );
|
||||
assert_eq!( digit_char_buf.get(), '8' );
|
||||
|
||||
// now u8-buffer changes, and char-buffer should change accordingly
|
||||
digit_u8_buffer.set(3);
|
||||
assert_eq!( digit_u8_buffer.get(), 3 );
|
||||
|
||||
// char buffer should follow
|
||||
digit_char_view.0.update();
|
||||
assert_eq!( digit_char_buf.get(), '3' );
|
||||
assert_eq!( digit_char_view.get_view().unwrap().get(), '3' );
|
||||
}
|
||||
|
|
@ -68,20 +68,20 @@ impl TerminalEvent {
|
|||
match self {
|
||||
TerminalEvent::Input(Event::Key(key)) => {
|
||||
if let Some(tree_nav_cmd) = neo2_treenav_keymap(key) {
|
||||
ReprTree::new_leaf(
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&ctx, "TreeNavCmd"),
|
||||
SingletonBuffer::new(tree_nav_cmd).get_port().into()
|
||||
SingletonBuffer::new(tree_nav_cmd)
|
||||
)
|
||||
} else if let Some(tree_nav_cmd) = universal_treenav_keymap(key) {
|
||||
ReprTree::new_leaf(
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&ctx, "TreeNavCmd"),
|
||||
SingletonBuffer::new(tree_nav_cmd).get_port().into()
|
||||
SingletonBuffer::new(tree_nav_cmd)
|
||||
)
|
||||
} else {
|
||||
if let Some(list_cmd) = tty_list_keymap(key) {
|
||||
ReprTree::new_leaf(
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&ctx, "ListCmd"),
|
||||
SingletonBuffer::new(list_cmd).get_port().into()
|
||||
SingletonBuffer::new(list_cmd)
|
||||
)
|
||||
} else {
|
||||
match key {
|
||||
|
@ -89,9 +89,9 @@ impl TerminalEvent {
|
|||
ReprTree::from_char(&ctx, *c)
|
||||
}
|
||||
_ => {
|
||||
ReprTree::new_leaf(
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&ctx, "TerminalEvent"),
|
||||
SingletonBuffer::new(self.clone()).get_port().into()
|
||||
SingletonBuffer::new(self.clone())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -99,9 +99,9 @@ impl TerminalEvent {
|
|||
}
|
||||
}
|
||||
_ => {
|
||||
ReprTree::new_leaf(
|
||||
ReprTree::from_singleton_buffer(
|
||||
Context::parse(&ctx, "TerminalEvent"),
|
||||
SingletonBuffer::new(self.clone()).get_port().into()
|
||||
SingletonBuffer::new(self.clone())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,12 +94,12 @@ impl PTYListStyle {
|
|||
pub fn for_node(node: &mut EditTree, style: (&str, &str, &str)) {
|
||||
node.disp.view
|
||||
.write().unwrap()
|
||||
.insert_branch(ReprTree::new_leaf(
|
||||
.insert_branch(ReprTree::from_view(
|
||||
Context::parse(&node.ctx, "TerminalView"),
|
||||
Self::new(style)
|
||||
.pty_view(
|
||||
&node.get_edit::<ListEditor>().unwrap().read().unwrap()
|
||||
).into()
|
||||
)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -225,6 +225,7 @@ impl PTYListController {
|
|||
rt,
|
||||
self.depth.map(|d| d+1)
|
||||
);
|
||||
/*
|
||||
let mut ne = new_edittree.write().unwrap();
|
||||
match ne.send_cmd_obj(cmd_obj.clone()) {
|
||||
TreeNavResult::Continue => {
|
||||
|
@ -233,9 +234,12 @@ impl PTYListController {
|
|||
TreeNavResult::Continue
|
||||
}
|
||||
TreeNavResult::Exit => {
|
||||
*/
|
||||
TreeNavResult::Exit
|
||||
/*
|
||||
}
|
||||
}
|
||||
*/
|
||||
},
|
||||
ListCursorMode::Select => {
|
||||
if let Some(item) = e.get_item_mut() {
|
||||
|
|
|
@ -17,12 +17,14 @@ use {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
pub fn edittree_make_char_view(
|
||||
node: EditTree
|
||||
) -> EditTree {
|
||||
eprintln!("nested-tty: EditTree make char-view");
|
||||
node.disp.view
|
||||
.write().unwrap()
|
||||
.insert_branch(ReprTree::new_leaf(
|
||||
.insert_branch(ReprTree::from_view(
|
||||
Context::parse(&node.ctx, "TerminalView"),
|
||||
node.get_edit::< nested::editors::char::CharEditor >()
|
||||
.unwrap()
|
||||
|
@ -31,7 +33,6 @@ pub fn edittree_make_char_view(
|
|||
.get_port()
|
||||
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
|
||||
.to_grid()
|
||||
.into(),
|
||||
));
|
||||
|
||||
node
|
||||
|
@ -42,7 +43,7 @@ pub fn edittree_make_digit_view(
|
|||
) -> EditTree {
|
||||
node.disp.view
|
||||
.write().unwrap()
|
||||
.insert_branch(ReprTree::new_leaf(
|
||||
.insert_branch(ReprTree::from_view(
|
||||
Context::parse(&node.ctx, "TerminalView"),
|
||||
node.get_edit::< nested::editors::digit::DigitEditor >()
|
||||
.unwrap()
|
||||
|
@ -56,7 +57,6 @@ pub fn edittree_make_digit_view(
|
|||
}
|
||||
)
|
||||
.to_grid()
|
||||
.into(),
|
||||
));
|
||||
|
||||
node
|
||||
|
|
|
@ -39,13 +39,12 @@ pub trait DisplaySegment {
|
|||
}
|
||||
|
||||
|
||||
use nested::repr_tree::Context;
|
||||
use nested::repr_tree::{Context, ReprTreeExt};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
impl DisplaySegment for nested::edit_tree::EditTree {
|
||||
fn display_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
if let Some( tv_repr ) = self.disp.view
|
||||
.read().unwrap()
|
||||
.descend( Context::parse(&self.ctx, "TerminalView") )
|
||||
{
|
||||
if let Some(port) =
|
||||
|
|
Loading…
Reference in a new issue