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,
|
cgmath::Vector2,
|
||||||
nested::{
|
nested::{
|
||||||
editors::ObjCommander,
|
editors::ObjCommander,
|
||||||
repr_tree::{Context, ReprTree},
|
repr_tree::{Context, ReprTree, ReprTreeExt},
|
||||||
edit_tree::{EditTree}
|
edit_tree::{EditTree}
|
||||||
},
|
},
|
||||||
nested_tty::{
|
nested_tty::{
|
||||||
DisplaySegment, TTYApplication,
|
DisplaySegment, TTYApplication,
|
||||||
TerminalCompositor, TerminalStyle, TerminalView,
|
TerminalCompositor, TerminalStyle, TerminalView,
|
||||||
TerminalAtom
|
TerminalAtom, TerminalEvent
|
||||||
},
|
},
|
||||||
r3vi::{
|
r3vi::{
|
||||||
buffer::{singleton::*, vec::*},
|
buffer::{singleton::*, vec::*},
|
||||||
|
view::{port::UpdateTask}
|
||||||
},
|
},
|
||||||
|
// termion::{},
|
||||||
std::sync::{Arc, RwLock},
|
std::sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,8 +50,8 @@ async fn main() {
|
||||||
// It provides the necessary bridge to the rendering- & input-backend.
|
// It provides the necessary bridge to the rendering- & input-backend.
|
||||||
ctx.write().unwrap().set_edittree_hook(
|
ctx.write().unwrap().set_edittree_hook(
|
||||||
Arc::new(
|
Arc::new(
|
||||||
move |et: Arc<RwLock<EditTree>>, t: laddertypes::TypeTerm| {
|
move |et: &mut EditTree, t: laddertypes::TypeTerm| {
|
||||||
let mut et = et.write().unwrap();
|
// let mut et = et.write().unwrap();
|
||||||
|
|
||||||
if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) {
|
if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) {
|
||||||
*et = nested_tty::editors::edittree_make_char_view(et.clone());
|
*et = nested_tty::editors::edittree_make_char_view(et.clone());
|
||||||
|
@ -95,31 +97,49 @@ async fn main() {
|
||||||
* / | \
|
* / | \
|
||||||
* TTY PixelBuf SDF
|
* 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
|
/* add initial representation
|
||||||
* <Digit 16> ~ Char
|
* <Digit 16> ~ Char
|
||||||
*/
|
*/
|
||||||
rt_digit.write().unwrap()
|
rt_digit.insert_leaf(
|
||||||
.insert_leaf(
|
Context::parse(&ctx, "Char"),
|
||||||
vec![ Context::parse(&ctx, "Char") ].into_iter(),
|
nested::repr_tree::ReprLeaf::from_singleton_buffer( SingletonBuffer::new('5') )
|
||||||
SingletonBuffer::new('4').get_port().into()
|
);
|
||||||
);
|
|
||||||
|
/* 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 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()
|
let edittree_digit = ctx.read().unwrap()
|
||||||
.setup_edittree(
|
.setup_edittree(
|
||||||
rt_digit
|
rt_digit.clone(),
|
||||||
.read().unwrap()
|
r3vi::buffer::singleton::SingletonBuffer::new(0).get_port()
|
||||||
.descend( Context::parse(&ctx, "Char") ).unwrap()
|
);
|
||||||
.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 rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") );
|
||||||
let edittree = ctx.read().unwrap()
|
|
||||||
.setup_edittree(rt_string.clone(), r3vi::buffer::singleton::SingletonBuffer::new(0).get_port());
|
let edittree_list = ctx.read().unwrap()
|
||||||
|
.setup_edittree(
|
||||||
|
rt_string.clone(),
|
||||||
|
r3vi::buffer::singleton::SingletonBuffer::new(0).get_port());
|
||||||
|
|
||||||
/* setup terminal
|
/* setup terminal
|
||||||
*/
|
*/
|
||||||
|
@ -127,9 +147,22 @@ async fn main() {
|
||||||
/* event handler
|
/* event handler
|
||||||
*/
|
*/
|
||||||
let ctx = ctx.clone();
|
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| {
|
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(
|
comp.push(
|
||||||
edittree_digit.read().unwrap().display_view()
|
edittree_digit.get().display_view()
|
||||||
.offset(Vector2::new(0,2))
|
.offset(Vector2::new(2,2))
|
||||||
);
|
);
|
||||||
|
|
||||||
let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type());
|
let label_str = ctx.read().unwrap().type_term_to_str(&rt_digit.read().unwrap().get_type());
|
||||||
comp.push(
|
comp.push(
|
||||||
nested_tty::make_label(&label_str)
|
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))
|
.offset(Vector2::new(0, 1))
|
||||||
);
|
);
|
||||||
|
|
||||||
comp.push(
|
comp.push(
|
||||||
edittree.read().unwrap().display_view()
|
digit_u8_buffer.get_port().map(
|
||||||
.offset(Vector2::new(0,4))
|
|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());
|
let label_str = ctx.read().unwrap().type_term_to_str(&rt_string.read().unwrap().get_type());
|
||||||
comp.push(
|
comp.push(
|
||||||
nested_tty::make_label(&label_str)
|
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::{
|
view::{
|
||||||
OuterViewPort,
|
OuterViewPort,
|
||||||
singleton::*,
|
singleton::*,
|
||||||
|
port::UpdateTask
|
||||||
},
|
},
|
||||||
buffer::singleton::*
|
buffer::singleton::*
|
||||||
},
|
},
|
||||||
laddertypes::{TypeTerm},
|
laddertypes::{TypeTerm},
|
||||||
crate::{
|
crate::{
|
||||||
repr_tree::{Context, ReprTree},
|
repr_tree::{Context, ReprTree, ReprTreeExt},
|
||||||
edit_tree::{EditTree, TreeNavResult},
|
edit_tree::{EditTree, TreeNavResult},
|
||||||
editors::ObjCommander,
|
editors::ObjCommander,
|
||||||
},
|
},
|
||||||
|
@ -17,7 +18,6 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
|
pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
|
||||||
|
|
||||||
let morphtype =
|
let morphtype =
|
||||||
crate::repr_tree::MorphismType {
|
crate::repr_tree::MorphismType {
|
||||||
src_type: Context::parse(&ctx, "Char"),
|
src_type: Context::parse(&ctx, "Char"),
|
||||||
|
@ -37,19 +37,25 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
|
||||||
|
|
||||||
/* Create EditTree object
|
/* 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(),
|
ctx.clone(),
|
||||||
SingletonBuffer::new('>'),
|
char_buf,
|
||||||
r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
|
r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Insert EditTree into ReprTree
|
eprintln!("insert Char~EditTree");
|
||||||
*/
|
rt.write().unwrap()
|
||||||
let mut rt = rt.write().unwrap();
|
.insert_branch(
|
||||||
rt.insert_leaf(
|
ReprTree::from_singleton_buffer(
|
||||||
vec![ Context::parse(&ctx, "EditTree") ].into_iter(),
|
Context::parse(&ctx, "EditTree"),
|
||||||
SingletonBuffer::new( Arc::new(RwLock::new( edittree_char )) ).get_port().into()
|
SingletonBuffer::new(edittree)
|
||||||
);
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -105,7 +111,7 @@ impl CharEditor {
|
||||||
data: SingletonBuffer<char>,
|
data: SingletonBuffer<char>,
|
||||||
depth: OuterViewPort<dyn SingletonView<Item = usize>>
|
depth: OuterViewPort<dyn SingletonView<Item = usize>>
|
||||||
) -> EditTree {
|
) -> EditTree {
|
||||||
let data = SingletonBuffer::new('\0');
|
//let data = SingletonBuffer::new('\0');
|
||||||
let ctx = ctx0.clone();
|
let ctx = ctx0.clone();
|
||||||
let editor = Arc::new(RwLock::new(CharEditor{ ctx, data: data.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 {
|
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>> {
|
||||||
let buf = r3vi::buffer::singleton::SingletonBuffer::new(self);
|
ReprTree::from_singleton_buffer(
|
||||||
ReprTree::new_leaf(
|
Context::parse(ctx, "ListCmd"),
|
||||||
Context::parse(ctx, "ListCmd"),
|
r3vi::buffer::singleton::SingletonBuffer::new(self)
|
||||||
buf.get_port().into()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use {
|
||||||
r3vi::{view::{OuterViewPort, singleton::*}, buffer::singleton::*},
|
r3vi::{view::{OuterViewPort, singleton::*}, buffer::singleton::*},
|
||||||
laddertypes::{TypeTerm},
|
laddertypes::{TypeTerm},
|
||||||
crate::{
|
crate::{
|
||||||
repr_tree::{Context},
|
repr_tree::{Context, ReprTree},
|
||||||
editors::list::{ListEditor}//, PTYListController, PTYListStyle}
|
editors::list::{ListEditor}//, PTYListController, PTYListStyle}
|
||||||
},
|
},
|
||||||
std::sync::{Arc, RwLock}
|
std::sync::{Arc, RwLock}
|
||||||
|
@ -13,6 +13,7 @@ use {
|
||||||
pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
|
pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
|
||||||
ctx.write().unwrap().add_list_typename("List".into());
|
ctx.write().unwrap().add_list_typename("List".into());
|
||||||
ctx.write().unwrap().add_varname("Item");
|
ctx.write().unwrap().add_varname("Item");
|
||||||
|
|
||||||
let mt = crate::repr_tree::MorphismType {
|
let mt = crate::repr_tree::MorphismType {
|
||||||
src_type: Context::parse(&ctx, "<List Item>"),
|
src_type: Context::parse(&ctx, "<List Item>"),
|
||||||
dst_type: Context::parse(&ctx, "<List Item>~EditTree")
|
dst_type: Context::parse(&ctx, "<List Item>~EditTree")
|
||||||
|
@ -21,9 +22,10 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
|
||||||
mt,
|
mt,
|
||||||
{
|
{
|
||||||
let ctx = ctx.clone();
|
let ctx = ctx.clone();
|
||||||
move |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 edittree_list = ListEditor::new(
|
let mut edittree_list = ListEditor::new(
|
||||||
ctx.clone(),
|
ctx.clone(),
|
||||||
item_type.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()
|
r3vi::buffer::singleton::SingletonBuffer::<usize>::new(0).get_port()
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut rt = rt.write().unwrap();
|
src_rt.write().unwrap().insert_branch(
|
||||||
rt.insert_leaf(
|
ReprTree::from_singleton_buffer(
|
||||||
vec![ Context::parse(&ctx, "EditTree") ].into_iter(),
|
Context::parse(&ctx, "EditTree"),
|
||||||
SingletonBuffer::new( Arc::new(RwLock::new( edittree_list )) ).get_port().into()
|
SingletonBuffer::new(edittree_list)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
eprintln!("no item type");
|
eprintln!("no item type");
|
||||||
|
|
|
@ -101,7 +101,6 @@ impl ListEditor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_node(mut self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree {
|
pub fn into_node(mut self, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> EditTree {
|
||||||
let data = self.get_data();
|
|
||||||
let ctx = self.ctx.clone();
|
let ctx = self.ctx.clone();
|
||||||
|
|
||||||
self.depth = depth.clone();
|
self.depth = depth.clone();
|
||||||
|
@ -155,7 +154,7 @@ impl ListEditor {
|
||||||
|x| x.read().unwrap().clone()
|
|x| x.read().unwrap().clone()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
|
pub fn get_data(&self) -> Arc<RwLock<ReprTree>> {
|
||||||
let data_view = self.get_data_port();
|
let data_view = self.get_data_port();
|
||||||
ReprTree::new_leaf(
|
ReprTree::new_leaf(
|
||||||
|
@ -163,7 +162,7 @@ impl ListEditor {
|
||||||
data_view.into()
|
data_view.into()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
pub fn get_item(&self) -> Option<EditTree> {
|
pub fn get_item(&self) -> Option<EditTree> {
|
||||||
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;
|
||||||
|
@ -309,22 +308,23 @@ impl ListEditor {
|
||||||
let mut b = item.ctrl.spillbuf.write().unwrap();
|
let mut b = item.ctrl.spillbuf.write().unwrap();
|
||||||
|
|
||||||
let rt = ReprTree::new_arc(self.typ.clone());
|
let rt = ReprTree::new_arc(self.typ.clone());
|
||||||
let new_edittree = self.ctx.read().unwrap()
|
let edittree = self.ctx.read().unwrap()
|
||||||
.setup_edittree(
|
.setup_edittree(
|
||||||
rt,
|
rt,
|
||||||
self.depth.map(|d| d+1)
|
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());
|
tail_node.goto(TreeCursor::home());
|
||||||
|
|
||||||
for node in b.iter() {
|
for node in b.iter() {
|
||||||
tail_node
|
tail_node
|
||||||
.send_cmd_obj(
|
.send_cmd_obj(
|
||||||
ReprTree::new_leaf(
|
ReprTree::from_singleton_buffer(
|
||||||
Context::parse(&self.ctx, "NestedNode"),
|
Context::parse(&self.ctx, "EditTree"),
|
||||||
SingletonBuffer::<EditTree>::new(
|
SingletonBuffer::<EditTree>::new(
|
||||||
node.read().unwrap().clone()
|
node.read().unwrap().clone()
|
||||||
).get_port().into()
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -340,7 +340,7 @@ impl ListEditor {
|
||||||
drop(tail_node);
|
drop(tail_node);
|
||||||
|
|
||||||
self.insert(
|
self.insert(
|
||||||
new_edittree
|
edittree.value.clone()
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -376,11 +376,11 @@ 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(
|
||||||
ReprTree::new_leaf(
|
ReprTree::from_singleton_buffer(
|
||||||
Context::parse(&self.ctx, "NestedNode"),
|
Context::parse(&self.ctx, "EditTree"),
|
||||||
SingletonBuffer::<EditTree>::new(
|
SingletonBuffer::<EditTree>::new(
|
||||||
x.read().unwrap().clone()
|
x.read().unwrap().clone()
|
||||||
).get_port().into()
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -435,11 +435,11 @@ impl ListEditor {
|
||||||
|
|
||||||
for x in data.iter() {
|
for x in data.iter() {
|
||||||
cur_editor.send_cmd_obj(
|
cur_editor.send_cmd_obj(
|
||||||
ReprTree::new_leaf(
|
ReprTree::from_singleton_buffer(
|
||||||
Context::parse(&self.ctx, "NestedNode"),
|
Context::parse(&self.ctx, "EditTree"),
|
||||||
SingletonBuffer::<EditTree>::new(
|
SingletonBuffer::<EditTree>::new(
|
||||||
x.read().unwrap().clone()
|
x.read().unwrap().clone()
|
||||||
).get_port().into()
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ use {
|
||||||
r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}},
|
r3vi::{view::{OuterViewPort, singleton::*}, buffer::{singleton::*}},
|
||||||
laddertypes::{TypeDict, TypeTerm, TypeID},
|
laddertypes::{TypeDict, TypeTerm, TypeID},
|
||||||
crate::{
|
crate::{
|
||||||
repr_tree::{ReprTree, MorphismType, GenericReprTreeMorphism, MorphismBase},
|
repr_tree::{ReprTree, ReprTreeExt, MorphismType, GenericReprTreeMorphism, MorphismBase},
|
||||||
edit_tree::EditTree
|
edit_tree::EditTree
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
|
@ -29,7 +29,7 @@ pub struct Context {
|
||||||
pub list_types: Vec< TypeID >,
|
pub list_types: Vec< TypeID >,
|
||||||
pub meta_chars: Vec< char >,
|
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
|
/// recursion
|
||||||
parent: Option<Arc<RwLock<Context>>>,
|
parent: Option<Arc<RwLock<Context>>>,
|
||||||
|
@ -64,7 +64,7 @@ impl Context {
|
||||||
Context::with_parent(None)
|
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;
|
self.edittree_hook = hook;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ impl Context {
|
||||||
|
|
||||||
pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> Arc<RwLock<ReprTree>> {
|
pub fn make_repr(ctx: &Arc<RwLock<Self>>, t: &TypeTerm) -> Arc<RwLock<ReprTree>> {
|
||||||
let rt = Arc::new(RwLock::new(ReprTree::new( TypeTerm::unit() )));
|
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
|
rt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,30 +180,32 @@ impl Context {
|
||||||
&self,
|
&self,
|
||||||
rt: Arc<RwLock<ReprTree>>,
|
rt: Arc<RwLock<ReprTree>>,
|
||||||
depth: OuterViewPort<dyn SingletonView<Item = usize>>
|
depth: OuterViewPort<dyn SingletonView<Item = usize>>
|
||||||
) -> Arc<RwLock<EditTree>> {
|
) -> SingletonBuffer<EditTree> {
|
||||||
let ladder = TypeTerm::Ladder(vec![
|
let ladder = TypeTerm::Ladder(vec![
|
||||||
rt.read().unwrap().get_type().clone(),
|
rt.read().unwrap().get_type().clone(),
|
||||||
self.type_term_from_str("EditTree").expect("")
|
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.clone(),
|
||||||
|
&rt.get_type(),
|
||||||
&ladder
|
&ladder
|
||||||
);
|
);
|
||||||
|
|
||||||
let new_edittree = rt
|
eprintln!("get repr-node of editTree");
|
||||||
.read().unwrap()
|
if let Some(new_edittree) =
|
||||||
.descend(
|
rt.descend(self.type_term_from_str("EditTree").unwrap())
|
||||||
self.type_term_from_str("EditTree").expect("")
|
{
|
||||||
).unwrap()
|
let buf = new_edittree.singleton_buffer::<EditTree>();
|
||||||
.read().unwrap()
|
(*self.edittree_hook)(
|
||||||
.get_view::<dyn SingletonView<Item = Arc<RwLock<EditTree>> >>()
|
&mut *buf.get_mut(),
|
||||||
.unwrap()
|
rt.read().unwrap().get_type().clone()
|
||||||
.get();
|
);
|
||||||
|
buf
|
||||||
(*self.edittree_hook)( new_edittree.clone(), rt.read().unwrap().get_type().clone() );
|
} else {
|
||||||
|
unreachable!();
|
||||||
new_edittree
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,27 +1,50 @@
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod morphism;
|
pub mod morphism;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
context::{Context},
|
context::{Context},
|
||||||
morphism::{MorphismType, GenericReprTreeMorphism, MorphismBase}
|
morphism::{MorphismType, GenericReprTreeMorphism, MorphismBase}
|
||||||
};
|
};
|
||||||
|
|
||||||
use {
|
use {
|
||||||
r3vi::view::{AnyOuterViewPort, OuterViewPort, View, singleton::*},
|
r3vi::{
|
||||||
|
view::{
|
||||||
|
ViewPort, OuterViewPort,
|
||||||
|
AnyViewPort, AnyInnerViewPort, AnyOuterViewPort,
|
||||||
|
port::UpdateTask,
|
||||||
|
View,
|
||||||
|
singleton::*, sequence::*
|
||||||
|
},
|
||||||
|
buffer::{singleton::*, vec::*}
|
||||||
|
},
|
||||||
laddertypes::{TypeTerm},
|
laddertypes::{TypeTerm},
|
||||||
std::{
|
std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
|
any::Any
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ReprTree {
|
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,
|
type_tag: TypeTerm,
|
||||||
port: Option<AnyOuterViewPort>,
|
|
||||||
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
|
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 {
|
pub trait ReprTreeExt {
|
||||||
fn get_type(&self) -> TypeTerm;
|
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 insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>);
|
||||||
|
|
||||||
fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<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_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>>;
|
||||||
fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>>;
|
fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>>;
|
||||||
fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>>;
|
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>> {
|
impl ReprTreeExt for Arc<RwLock<ReprTree>> {
|
||||||
|
@ -57,8 +344,8 @@ impl ReprTreeExt for Arc<RwLock<ReprTree>> {
|
||||||
self.read().unwrap().get_type().clone()
|
self.read().unwrap().get_type().clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
self.write().unwrap().insert_leaf(type_ladder, port)
|
self.write().unwrap().insert_leaf(type_ladder.into().get_lnf_vec().into_iter(), leaf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) {
|
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>>> {
|
fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
|
||||||
self.read().unwrap().descend(target_type)
|
ReprTree::descend( self, target_type )
|
||||||
}
|
|
||||||
|
|
||||||
fn descend_ladder(&self, ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
|
|
||||||
ReprTree::descend_ladder(self, ladder)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
|
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>> {
|
fn view_u64(&self) -> OuterViewPort<dyn SingletonView<Item = u64>> {
|
||||||
self.read().unwrap().view_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 {
|
use {
|
||||||
laddertypes::{TypeTerm, TypeID},
|
laddertypes::{TypeTerm, TypeID},
|
||||||
|
r3vi::view::AnyOuterViewPort,
|
||||||
crate::{
|
crate::{
|
||||||
repr_tree::{ReprTree},
|
repr_tree::{ReprTree, ReprTreeExt, ReprLeaf},
|
||||||
},
|
},
|
||||||
std::{
|
std::{
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
|
@ -20,8 +21,9 @@ pub struct MorphismType {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GenericReprTreeMorphism {
|
pub struct GenericReprTreeMorphism {
|
||||||
morph_type: MorphismType,
|
morph_type: MorphismType,
|
||||||
repr_tree_op: Arc<
|
setup_projection: Arc<
|
||||||
dyn Fn( Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> )
|
dyn Fn( &mut Arc<RwLock<ReprTree>>, &HashMap<TypeID, TypeTerm> )
|
||||||
|
// -> Result< ReprLeaf, () >
|
||||||
+ Send + Sync
|
+ Send + Sync
|
||||||
>
|
>
|
||||||
}
|
}
|
||||||
|
@ -43,12 +45,15 @@ impl MorphismBase {
|
||||||
pub fn add_morphism(
|
pub fn add_morphism(
|
||||||
&mut self,
|
&mut self,
|
||||||
morph_type: MorphismType,
|
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(
|
self.morphisms.push(
|
||||||
GenericReprTreeMorphism {
|
GenericReprTreeMorphism {
|
||||||
morph_type,
|
morph_type,
|
||||||
repr_tree_op: Arc::new(repr_tree_op)
|
setup_projection: Arc::new(setup_projection)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -75,14 +80,15 @@ impl MorphismBase {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn morph(
|
pub fn apply_morphism(
|
||||||
&self,
|
&self,
|
||||||
repr_tree: Arc<RwLock<ReprTree>>,
|
mut repr_tree: Arc<RwLock<ReprTree>>,
|
||||||
target_type: &TypeTerm
|
src_type: &TypeTerm,
|
||||||
|
dst_type: &TypeTerm
|
||||||
) {
|
) {
|
||||||
let t = repr_tree.read().unwrap().get_type().clone();
|
// let t = repr_tree.read().unwrap().get_type().clone();
|
||||||
if let Some((m, σ)) = self.find_morphism( &t, target_type ) {
|
if let Some((m, σ)) = self.find_morphism( &src_type, dst_type ) {
|
||||||
(m.repr_tree_op)( repr_tree.clone(), &σ );
|
(m.setup_projection)( &mut repr_tree, &σ );
|
||||||
} else {
|
} else {
|
||||||
eprintln!("could not find morphism");
|
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 {
|
match self {
|
||||||
TerminalEvent::Input(Event::Key(key)) => {
|
TerminalEvent::Input(Event::Key(key)) => {
|
||||||
if let Some(tree_nav_cmd) = neo2_treenav_keymap(key) {
|
if let Some(tree_nav_cmd) = neo2_treenav_keymap(key) {
|
||||||
ReprTree::new_leaf(
|
ReprTree::from_singleton_buffer(
|
||||||
Context::parse(&ctx, "TreeNavCmd"),
|
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) {
|
} else if let Some(tree_nav_cmd) = universal_treenav_keymap(key) {
|
||||||
ReprTree::new_leaf(
|
ReprTree::from_singleton_buffer(
|
||||||
Context::parse(&ctx, "TreeNavCmd"),
|
Context::parse(&ctx, "TreeNavCmd"),
|
||||||
SingletonBuffer::new(tree_nav_cmd).get_port().into()
|
SingletonBuffer::new(tree_nav_cmd)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
if let Some(list_cmd) = tty_list_keymap(key) {
|
if let Some(list_cmd) = tty_list_keymap(key) {
|
||||||
ReprTree::new_leaf(
|
ReprTree::from_singleton_buffer(
|
||||||
Context::parse(&ctx, "ListCmd"),
|
Context::parse(&ctx, "ListCmd"),
|
||||||
SingletonBuffer::new(list_cmd).get_port().into()
|
SingletonBuffer::new(list_cmd)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
match key {
|
match key {
|
||||||
|
@ -89,9 +89,9 @@ impl TerminalEvent {
|
||||||
ReprTree::from_char(&ctx, *c)
|
ReprTree::from_char(&ctx, *c)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
ReprTree::new_leaf(
|
ReprTree::from_singleton_buffer(
|
||||||
Context::parse(&ctx, "TerminalEvent"),
|
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"),
|
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)) {
|
pub fn for_node(node: &mut EditTree, style: (&str, &str, &str)) {
|
||||||
node.disp.view
|
node.disp.view
|
||||||
.write().unwrap()
|
.write().unwrap()
|
||||||
.insert_branch(ReprTree::new_leaf(
|
.insert_branch(ReprTree::from_view(
|
||||||
Context::parse(&node.ctx, "TerminalView"),
|
Context::parse(&node.ctx, "TerminalView"),
|
||||||
Self::new(style)
|
Self::new(style)
|
||||||
.pty_view(
|
.pty_view(
|
||||||
&node.get_edit::<ListEditor>().unwrap().read().unwrap()
|
&node.get_edit::<ListEditor>().unwrap().read().unwrap()
|
||||||
).into()
|
)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,7 @@ impl PTYListController {
|
||||||
rt,
|
rt,
|
||||||
self.depth.map(|d| d+1)
|
self.depth.map(|d| d+1)
|
||||||
);
|
);
|
||||||
|
/*
|
||||||
let mut ne = new_edittree.write().unwrap();
|
let mut ne = new_edittree.write().unwrap();
|
||||||
match ne.send_cmd_obj(cmd_obj.clone()) {
|
match ne.send_cmd_obj(cmd_obj.clone()) {
|
||||||
TreeNavResult::Continue => {
|
TreeNavResult::Continue => {
|
||||||
|
@ -233,9 +234,12 @@ impl PTYListController {
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
}
|
}
|
||||||
TreeNavResult::Exit => {
|
TreeNavResult::Exit => {
|
||||||
|
*/
|
||||||
TreeNavResult::Exit
|
TreeNavResult::Exit
|
||||||
|
/*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
},
|
},
|
||||||
ListCursorMode::Select => {
|
ListCursorMode::Select => {
|
||||||
if let Some(item) = e.get_item_mut() {
|
if let Some(item) = e.get_item_mut() {
|
||||||
|
|
|
@ -17,12 +17,14 @@ use {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
pub fn edittree_make_char_view(
|
pub fn edittree_make_char_view(
|
||||||
node: EditTree
|
node: EditTree
|
||||||
) -> EditTree {
|
) -> EditTree {
|
||||||
|
eprintln!("nested-tty: EditTree make char-view");
|
||||||
node.disp.view
|
node.disp.view
|
||||||
.write().unwrap()
|
.write().unwrap()
|
||||||
.insert_branch(ReprTree::new_leaf(
|
.insert_branch(ReprTree::from_view(
|
||||||
Context::parse(&node.ctx, "TerminalView"),
|
Context::parse(&node.ctx, "TerminalView"),
|
||||||
node.get_edit::< nested::editors::char::CharEditor >()
|
node.get_edit::< nested::editors::char::CharEditor >()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -31,7 +33,6 @@ pub fn edittree_make_char_view(
|
||||||
.get_port()
|
.get_port()
|
||||||
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
|
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
|
||||||
.to_grid()
|
.to_grid()
|
||||||
.into(),
|
|
||||||
));
|
));
|
||||||
|
|
||||||
node
|
node
|
||||||
|
@ -42,7 +43,7 @@ pub fn edittree_make_digit_view(
|
||||||
) -> EditTree {
|
) -> EditTree {
|
||||||
node.disp.view
|
node.disp.view
|
||||||
.write().unwrap()
|
.write().unwrap()
|
||||||
.insert_branch(ReprTree::new_leaf(
|
.insert_branch(ReprTree::from_view(
|
||||||
Context::parse(&node.ctx, "TerminalView"),
|
Context::parse(&node.ctx, "TerminalView"),
|
||||||
node.get_edit::< nested::editors::digit::DigitEditor >()
|
node.get_edit::< nested::editors::digit::DigitEditor >()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -56,7 +57,6 @@ pub fn edittree_make_digit_view(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.to_grid()
|
.to_grid()
|
||||||
.into(),
|
|
||||||
));
|
));
|
||||||
|
|
||||||
node
|
node
|
||||||
|
|
|
@ -39,13 +39,12 @@ pub trait DisplaySegment {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
use nested::repr_tree::Context;
|
use nested::repr_tree::{Context, ReprTreeExt};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
|
||||||
impl DisplaySegment for nested::edit_tree::EditTree {
|
impl DisplaySegment for nested::edit_tree::EditTree {
|
||||||
fn display_view(&self) -> OuterViewPort<dyn TerminalView> {
|
fn display_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
if let Some( tv_repr ) = self.disp.view
|
if let Some( tv_repr ) = self.disp.view
|
||||||
.read().unwrap()
|
|
||||||
.descend( Context::parse(&self.ctx, "TerminalView") )
|
.descend( Context::parse(&self.ctx, "TerminalView") )
|
||||||
{
|
{
|
||||||
if let Some(port) =
|
if let Some(port) =
|
||||||
|
|
Loading…
Reference in a new issue