Compare commits

...

3 Commits

Author SHA1 Message Date
Michael Sippel 658f5c1000
refactor ReprTree
- ReprLeaf with In- & Out-Ports
- Optional Buffers
2024-03-15 18:54:45 +01:00
Michael Sippel 03dc9f1133
add ReprTreeExt trait for Arc<Rwlock<>> 2024-03-10 19:27:51 +01:00
Michael Sippel d7d0a46c7b
move digit into separate module 2024-03-10 16:17:24 +01:00
21 changed files with 946 additions and 367 deletions

View File

@ -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},
};
@ -29,7 +31,8 @@ async fn main() {
let ctx = Arc::new(RwLock::new(Context::new()));
nested::editors::char::init_ctx( ctx.clone() );
nested::editors::integer::editor::init_ctx( ctx.clone() );
nested::editors::digit::init_ctx( ctx.clone() );
nested::editors::integer::init_ctx( ctx.clone() );
nested::editors::list::init_ctx( ctx.clone() );
let char_type = Context::parse(&ctx, "Char");
@ -47,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());
@ -85,40 +88,58 @@ async fn main() {
* / | \
* / | \
* / | \
* u32 [ EditTree ] Char
* u32 EditTree Char
* - Editor \
* - Display [ EditTree ]
* - Display EditTree
* / | \ - Editor
* / | \ - Display
* 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
* <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
*/
@ -126,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));
}
}
}
});
@ -149,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))
);
}

View File

@ -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() }));

View 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
}
}

View 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);
}
}
});
}

View 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()
)
}
*/
}

View File

@ -0,0 +1,8 @@
pub mod ctx;
pub mod cmd;
pub mod editor;
pub use editor::DigitEditor;
pub use ctx::init_ctx;

View File

@ -15,39 +15,8 @@ use {
std::sync::{Arc, RwLock}
};
pub fn init_ctx(ctx: &mut Context) {
pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
/*
ctx.add_typename("MachineInt".into());
ctx.add_typename("u32".into());
ctx.add_typename("u64".into());
ctx.add_typename("LittleEndian".into());
ctx.add_typename("BigEndian".into());
ctx.add_node_ctor(
"Digit", Arc::new(
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: OuterViewPort<dyn SingletonView<Item = usize>>| {
match ty {
TypeTerm::App(args) => {
if args.len() > 1 {
match args[1] {
TypeTerm::Num(radix) => {
let node = DigitEditor::new(ctx.clone(), radix as u32).into_node(depth);
Some(
node
)
},
_ => None
}
} else {
None
}
}
_ => None
}
}
)
);
ctx.add_list_typename("PosInt".into());
let pattern = MorphismTypePattern {
src_tyid: ctx.get_typeid("List"),
@ -127,7 +96,8 @@ pub fn init_ctx(ctx: &mut Context) {
}
)
);
*/
*/
/*
ctx.add_typename("Date".into());
ctx.add_typename("ISO-8601".into());
ctx.add_typename("TimeSince".into());
@ -137,5 +107,6 @@ pub fn init_ctx(ctx: &mut Context) {
ctx.add_typename("Duration".into());
ctx.add_typename("Seconds".into());
ctx.add_typename("".into());
*/
}

View File

@ -12,7 +12,11 @@ use {
},
laddertypes::{TypeTerm},
crate::{
editors::{list::{ListCmd}, ObjCommander},
editors::{
digit::DigitEditor,
list::{ListCmd},
ObjCommander
},
repr_tree::{Context, ReprTree},
edit_tree::{EditTree, TreeNav, TreeNavResult, TreeCursor, diagnostics::{Message}},
},
@ -22,160 +26,6 @@ use {
cgmath::{Point2}
};
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 |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_digit = DigitEditor::new(
ctx.clone(),
radix
).into_node(
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_digit)) ).get_port().into()
);
}
}
);
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct DigitEditor {
ctx: Arc<RwLock<Context>>,
radix: u32,
data: SingletonBuffer<Option<char>>,
msg: VecBuffer<Message>,
}
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(Some(c));
} else {
self.data.set(Some(c));
}
}
}
TreeNavResult::Continue
}
}
impl DigitEditor {
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
DigitEditor {
ctx,
radix,
data: SingletonBuffer::new(None),
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.unwrap_or('?').to_digit(radix) {
Ok(d)
} else {
Err(c.unwrap_or('?'))
}
)
}
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::new_leaf(
self.ctx.read().unwrap().type_term_from_str("<Seq u32>").unwrap(),
self.get_data_port().into()
),
self.get_type()
)
}
}
pub struct PosIntEditor {
radix: u32,
digits: EditTree,

View File

@ -5,7 +5,7 @@ pub mod ctx;
pub use {
add::Add,
editor::{DigitEditor, PosIntEditor},
editor::PosIntEditor,
radix::RadixProjection,
ctx::init_ctx
};

View File

@ -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(
Context::parse(ctx, "ListCmd"),
buf.get_port().into()
ReprTree::from_singleton_buffer(
Context::parse(ctx, "ListCmd"),
r3vi::buffer::singleton::SingletonBuffer::new(self)
)
}
}

View File

@ -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");

View File

@ -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()
)
)
);
}

View File

@ -4,6 +4,7 @@ pub mod list;
//pub mod sum;
pub mod char;
pub mod digit;
pub mod integer;
//pub mod typeterm;

View File

@ -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!();
}
}
}

View File

@ -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 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,
port: Option<AnyOuterViewPort>,
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
leaf: Option< ReprLeaf >
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
@ -40,12 +63,95 @@ 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(),
port: None,
branches: HashMap::new(),
leaf: None
}
}
@ -57,100 +163,220 @@ impl ReprTree {
&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 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>,
port: AnyOuterViewPort,
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, port);
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, port);
next_repr.insert_leaf(type_ladder, leaf);
self.insert_branch(Arc::new(RwLock::new(next_repr)));
}
} else {
self.port = Some(port);
self.leaf = Some(leaf)
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
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_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_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(first),
|s, t| s?.read().unwrap().descend(t))
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 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 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>> {
fn get_type(&self) -> TypeTerm {
self.read().unwrap().get_type().clone()
}
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>>) {
self.write().unwrap().insert_branch(repr)
}
fn descend(&self, target_type: impl Into<TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
ReprTree::descend( self, target_type )
}
fn view_char(&self) -> OuterViewPort<dyn SingletonView<Item = char>> {
self.read().unwrap().view_char()
}
fn view_u8(&self) -> OuterViewPort<dyn SingletonView<Item = u8>> {
self.read().unwrap().view_u8()
}
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("")
}
*/
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View File

@ -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");
}

View 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' );
}

View File

@ -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())
)
}
}

View File

@ -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() {

View File

@ -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,9 +43,9 @@ 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::integer::DigitEditor >()
node.get_edit::< nested::editors::digit::DigitEditor >()
.unwrap()
.read()
.unwrap()
@ -56,7 +57,6 @@ pub fn edittree_make_digit_view(
}
)
.to_grid()
.into(),
));
node

View File

@ -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) =