begin refactor to node-struct and obj-commmander

This commit is contained in:
Michael Sippel 2022-12-18 01:20:17 +01:00
parent bcbeb2298a
commit 35498a2fa7
Signed by: senvas
GPG key ID: 060F22F65102F95C
19 changed files with 661 additions and 207 deletions

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
core::{OuterViewPort, ViewPort}, core::{OuterViewPort, ViewPort, Context},
list::{ListEditor}, list::{ListEditor},
sequence::{SequenceView, SequenceViewExt}, sequence::{SequenceView, SequenceViewExt},
singleton::{SingletonBuffer, SingletonView}, singleton::{SingletonBuffer, SingletonView},
@ -10,7 +10,7 @@ use {
}, },
tree::{TreeCursor, TreeNav, TreeNavResult}, tree::{TreeCursor, TreeNav, TreeNavResult},
diagnostics::Diagnostics, diagnostics::Diagnostics,
Nested Nested, tree::NestedNode, Commander
}, },
std::sync::Arc, std::sync::Arc,
std::sync::RwLock, std::sync::RwLock,
@ -22,6 +22,23 @@ pub struct CharEditor {
data: SingletonBuffer<Option<char>> data: SingletonBuffer<Option<char>>
} }
impl Commander for CharEditor {
type Cmd = TerminalEvent;
fn send_cmd(&mut self, event: &TerminalEvent) {
match event {
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
self.data.set(Some(*c));
}
TerminalEvent::Input(Event::Key(Key::Backspace))
| TerminalEvent::Input(Event::Key(Key::Delete)) => {
self.data.set(None);
}
_ => {}
}
}
}
impl CharEditor { impl CharEditor {
pub fn new() -> Self { pub fn new() -> Self {
CharEditor { CharEditor {
@ -36,40 +53,32 @@ impl CharEditor {
pub fn get(&self) -> char { pub fn get(&self) -> char {
self.get_port().get_view().unwrap().get().unwrap_or('?') self.get_port().get_view().unwrap().get().unwrap_or('?')
} }
}
impl TreeNav for CharEditor {} pub fn new_node(ctx: &Arc<RwLock<Context>>) -> NestedNode {
impl Diagnostics for CharEditor {} let data = SingletonBuffer::new(None);
impl TerminalEditor for CharEditor { NestedNode::new()
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> { .set_ctx(ctx.clone())
self.data .set_view(data
.get_port() .get_port()
.map(move |c| { .map(move |c| {
TerminalAtom::from( match c {
c.unwrap_or('?') Some(c) => TerminalAtom::from(c),
) None => TerminalAtom::new('*', TerminalStyle::fg_color((255,0,0)))
}
}) })
.to_grid() .to_grid()
} )
.with_cmd(
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { Arc::new(RwLock::new(CharEditor{ data }))
match event { )
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Exit,
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
self.data.set(Some(*c));
TerminalEditorResult::Exit
}
TerminalEvent::Input(Event::Key(Key::Backspace))
| TerminalEvent::Input(Event::Key(Key::Delete)) => {
self.data.set(None);
TerminalEditorResult::Exit
}
_ => TerminalEditorResult::Continue,
}
} }
} }
impl Nested for CharEditor {} use crate::StringGen;
impl StringGen for CharEditor {
fn get_string(&self) -> String {
String::from(self.get())
}
}

View file

@ -36,8 +36,8 @@ impl ReprTree {
Arc::new(RwLock::new(tree)) Arc::new(RwLock::new(tree))
} }
pub fn insert_branch(&mut self, type_tag: TypeTerm, repr: Arc<RwLock<ReprTree>>) { pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) {
self.branches.insert(type_tag, repr); self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone());
} }
pub fn insert_leaf( pub fn insert_leaf(
@ -51,7 +51,7 @@ impl ReprTree {
} else { } else {
let mut next_repr = ReprTree::new(type_term.clone()); let mut next_repr = ReprTree::new(type_term.clone());
next_repr.insert_leaf(type_ladder, port); next_repr.insert_leaf(type_ladder, port);
self.insert_branch(type_term, Arc::new(RwLock::new(next_repr))); self.insert_branch(Arc::new(RwLock::new(next_repr)));
} }
} else { } else {
self.port = Some(port); self.port = Some(port);
@ -73,6 +73,15 @@ impl ReprTree {
) )
} }
pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>>
where
V::Msg: Clone,
{
self.get_port::<V>()?
.get_view()
}
// descend
pub fn downcast(&self, dst_type: &TypeTerm) -> Option<Arc<RwLock<ReprTree>>> { pub fn downcast(&self, dst_type: &TypeTerm) -> Option<Arc<RwLock<ReprTree>>> {
self.branches.get(dst_type).cloned() self.branches.get(dst_type).cloned()
} }
@ -84,6 +93,13 @@ impl ReprTree {
|s, t| s?.read().unwrap().downcast(&t)) |s, t| s?.read().unwrap().downcast(&t))
} }
// ascend
pub fn upcast(rt: &Arc<RwLock<Self>>, type_term: TypeTerm) -> Arc<RwLock<ReprTree>> {
let mut n = Self::new(type_term);
n.insert_branch(rt.clone());
Arc::new(RwLock::new(n))
}
/* /*
pub fn add_iso_repr( pub fn add_iso_repr(
&self, &self,
@ -268,6 +284,7 @@ impl Context {
pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> { pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> {
self.type_dict.read().unwrap().type_term_from_str(&tn) self.type_dict.read().unwrap().type_term_from_str(&tn)
} }
pub fn type_term_to_str(&self, t: &TypeTerm) -> String { pub fn type_term_to_str(&self, t: &TypeTerm) -> String {
self.type_dict.read().unwrap().type_term_to_str(&t) self.type_dict.read().unwrap().type_term_to_str(&t)
} }

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort}, core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort, port::UpdateTask},
grid::{GridView, GridWindowIterator}, grid::{GridView, GridWindowIterator},
index::{IndexArea, IndexView}, index::{IndexArea, IndexView},
projection::ProjectionHelper, projection::ProjectionHelper,
@ -120,8 +120,14 @@ where
if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { if let Some(chunk) = self.chunks.get_mut(&chunk_idx) {
chunk.view = view; chunk.view = view;
self.cast
.notify(&chunk.view.area().map(|pt| pt + chunk.offset)); let old_limit = chunk.limit;
let new_limit = *chunk.view.area().range().end();
self.cast.notify(
&IndexArea::Range(
Point2::new(chunk.offset.x, chunk.offset.y) ..= Point2::new(chunk.offset.x + max(old_limit.x, new_limit.x), chunk.offset.y + max(old_limit.y, new_limit.y) )));
} else { } else {
self.chunks.insert( self.chunks.insert(
chunk_idx, chunk_idx,
@ -168,15 +174,18 @@ where
for chunk_idx in GridWindowIterator::from(top_range.clone()) { for chunk_idx in GridWindowIterator::from(top_range.clone()) {
if let Some(chunk) = self.chunks.get_mut(&chunk_idx) { if let Some(chunk) = self.chunks.get_mut(&chunk_idx) {
let _old_offset = chunk.offset; let old_offset = chunk.offset;
let _old_limit = chunk.limit; let old_limit = chunk.limit;
//chunk.limit = Point2::new( col_widths[chunk_idx.x as usize]-1, row_heights[chunk_idx.y as usize]-1 );
chunk.limit = *chunk.view.area().range().end(); chunk.limit = *chunk.view.area().range().end();
chunk.offset = Vector2::new( chunk.offset = Vector2::new(
(0..chunk_idx.x as usize).map(|x| col_widths[x]).sum(), (0..chunk_idx.x as usize).map(|x| col_widths[x]).sum(),
(0..chunk_idx.y as usize).map(|y| row_heights[y]).sum(), (0..chunk_idx.y as usize).map(|y| row_heights[y]).sum(),
); );
/* /*
if old_offset != chunk.offset { if old_offset != chunk.offset {
self.cast.notify( self.cast.notify(
&IndexArea::Range( &IndexArea::Range(
@ -191,7 +200,7 @@ where
) )
); );
} }
*/ */
} }
} }
@ -214,6 +223,7 @@ where
max(self.limit.y, old_limit.y), max(self.limit.y, old_limit.y),
), ),
)); ));
} }
/// given an index in the flattened sequence, /// given an index in the flattened sequence,

View file

@ -65,7 +65,8 @@ impl TerminalEditor for DigitEditor {
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
match event { match event {
TerminalEvent::Input(Event::Key(Key::Char(' '))) TerminalEvent::Input(Event::Key(Key::Ctrl('x')))
| TerminalEvent::Input(Event::Key(Key::Char(' ')))
| TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Exit, | TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Exit,
TerminalEvent::Input(Event::Key(Key::Char(c))) => { TerminalEvent::Input(Event::Key(Key::Char(c))) => {
self.data.set(Some(*c)); self.data.set(Some(*c));
@ -116,7 +117,7 @@ impl PosIntEditor {
digits_editor: PTYListEditor::new( digits_editor: PTYListEditor::new(
Box::new(move || Arc::new(RwLock::new(DigitEditor::new(radix)))) as Box<dyn Fn() -> Arc<RwLock<DigitEditor>> + Send + Sync>, Box::new(move || Arc::new(RwLock::new(DigitEditor::new(radix)))) as Box<dyn Fn() -> Arc<RwLock<DigitEditor>> + Send + Sync>,
SeqDecorStyle::Hex, SeqDecorStyle::Hex,
' ', None,
0 0
), ),
} }
@ -195,7 +196,8 @@ impl TerminalEditor for PosIntEditor {
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult { fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
match event { match event {
TerminalEvent::Input(Event::Key(Key::Char(' '))) TerminalEvent::Input(Event::Key(Key::Ctrl('x')))
| TerminalEvent::Input(Event::Key(Key::Char(' ')))
| TerminalEvent::Input(Event::Key(Key::Char('\n'))) => { | TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
self.digits_editor.up(); self.digits_editor.up();
TerminalEditorResult::Exit TerminalEditorResult::Exit

View file

@ -16,10 +16,19 @@ pub struct RadixProjection {
impl RadixProjection { impl RadixProjection {
pub fn new( pub fn new(
// static parameters
//---
src_radix: usize, src_radix: usize,
dst_radix: usize, dst_radix: usize,
//---
// dynamic parameters
//---
// input
src_digits: OuterViewPort<dyn SequenceView<Item = usize>>, src_digits: OuterViewPort<dyn SequenceView<Item = usize>>,
// output
dst_digits: InnerViewPort<RwLock<Vec<usize>>>, dst_digits: InnerViewPort<RwLock<Vec<usize>>>,
//---
) -> Arc<RwLock<Self>> { ) -> Arc<RwLock<Self>> {
dst_digits.0.add_update_hook(Arc::new(src_digits.0.clone())); dst_digits.0.add_update_hook(Arc::new(src_digits.0.clone()));
let proj = Arc::new(RwLock::new(RadixProjection { let proj = Arc::new(RwLock::new(RadixProjection {

View file

@ -27,6 +27,7 @@ pub mod diagnostics;
pub mod char_editor; pub mod char_editor;
pub mod integer; pub mod integer;
pub mod make_editor; pub mod make_editor;
pub mod type_term_editor;
// display // display
pub mod color; pub mod color;
@ -36,16 +37,50 @@ pub fn magic_header() {
eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>"); eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>");
} }
use crate::terminal::{TerminalEditor}; pub trait Commander {
use crate::diagnostics::{Diagnostics}; type Cmd;
use crate::tree::{TreeNav, TreeType};
fn send_cmd(&mut self, cmd: &Self::Cmd);
}
use std::sync::{Arc, RwLock};
use crate::{
core::context::ReprTree,
singleton::SingletonView
};
pub trait ObjCommander {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>);
}
//impl<Cmd: 'static, T: Commander<Cmd>> ObjCommander for T {
impl<C: Commander> ObjCommander for C
where C::Cmd: 'static
{
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
self.send_cmd(
&cmd_obj.read().unwrap()
.get_port::<dyn SingletonView<Item = C::Cmd>>().unwrap()
.get_view().unwrap()
.get()
);
}
}
pub trait StringGen {
fn get_string(&self) -> String;
}
use crate::terminal::TerminalEditor;
use crate::{tree::{TreeNav}, diagnostics::Diagnostics};
pub trait Nested pub trait Nested
: TerminalEditor : TerminalEditor
+ TreeNav + TreeNav
// + TreeType // + TreeType
+ Diagnostics + Diagnostics
+ Send + Send
+ Sync + Sync
+ std::any::Any
{} {}

View file

@ -27,7 +27,7 @@ pub struct ListEditor<ItemEditor>
where ItemEditor: Nested + ?Sized + Send + Sync + 'static where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{ {
pub(super) cursor: SingletonBuffer<ListCursor>, pub(super) cursor: SingletonBuffer<ListCursor>,
pub(super) data: VecBuffer<Arc<RwLock<ItemEditor>>>, pub(crate) data: VecBuffer<Arc<RwLock<ItemEditor>>>,
pub(super) make_item_editor: Box<dyn Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync>, pub(super) make_item_editor: Box<dyn Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync>,
pub(super) depth: usize, pub(super) depth: usize,

View file

@ -28,7 +28,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{ {
pub editor: ListEditor<ItemEditor>, pub editor: ListEditor<ItemEditor>,
split_char: char, split_char: Option<char>,
style: SeqDecorStyle, style: SeqDecorStyle,
depth: usize, depth: usize,
@ -42,7 +42,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
pub fn new( pub fn new(
make_item_editor: impl Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync + 'static, make_item_editor: impl Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync + 'static,
style: SeqDecorStyle, style: SeqDecorStyle,
split_char: char, split_char: Option<char>,
depth: usize depth: usize
) -> Self { ) -> Self {
Self::from_editor(ListEditor::new(make_item_editor, depth), style, split_char, depth) Self::from_editor(ListEditor::new(make_item_editor, depth), style, split_char, depth)
@ -51,7 +51,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
pub fn from_editor( pub fn from_editor(
editor: ListEditor<ItemEditor>, editor: ListEditor<ItemEditor>,
style: SeqDecorStyle, style: SeqDecorStyle,
split_char: char, split_char: Option<char>,
depth: usize depth: usize
) -> Self { ) -> Self {
let port = editor let port = editor
@ -140,15 +140,15 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
let mut ne = new_edit.write().unwrap(); let mut ne = new_edit.write().unwrap();
ne.goto(TreeCursor::home()); ne.goto(TreeCursor::home());
match ne.handle_terminal_event(event) { ne.handle_terminal_event(event);
TerminalEditorResult::Exit => {
if self.split_char.is_none() {
self.editor.cursor.set(ListCursor { self.editor.cursor.set(ListCursor {
mode: ListCursorMode::Insert, mode: ListCursorMode::Insert,
idx: Some(idx as isize + 1), idx: Some(idx as isize + 1),
}); });
} }
_ => {}
}
TerminalEditorResult::Continue TerminalEditorResult::Continue
} }
}, },
@ -161,36 +161,41 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
} }
TerminalEvent::Input(Event::Key(Key::Char(c))) => { TerminalEvent::Input(Event::Key(Key::Char(c))) => {
if *c == self.split_char { if Some(*c) == self.split_char {
let c = self.editor.cursor.get(); let c = self.editor.cursor.get();
self.editor.goto(TreeCursor::none()); self.editor.goto(TreeCursor::none());
self.editor.cursor.set(ListCursor { self.editor.cursor.set(ListCursor {
mode: ListCursorMode::Insert, mode: ListCursorMode::Insert,
idx: Some(1 + c.idx.unwrap_or(0)) idx: Some(1 + c.idx.unwrap_or(0))
}); });
TerminalEditorResult::Continue
} else { } else {
if let Some(e) = self.editor.get_item() { if let Some(e) = self.editor.get_item() {
match e.write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c)))) { e.write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c))));
TerminalEditorResult::Exit => { //match
if self.split_char.is_none() {
// TerminalEditorResult::Exit =>
{
self.editor.cursor.set(ListCursor { self.editor.cursor.set(ListCursor {
mode: ListCursorMode::Insert, mode: ListCursorMode::Insert,
idx: Some(idx as isize + 1), idx: Some(idx as isize + 1),
}); });
} }
TerminalEditorResult::Continue => { // TerminalEditorResult::Continue => {
// }
} }
} }
TerminalEditorResult::Exit
} }
} }
TerminalEditorResult::Continue
}
ev => { ev => {
if let Some(e) = self.editor.get_item() { if let Some(e) = self.editor.get_item() {
match e.write().unwrap().handle_terminal_event(ev) { match e.write().unwrap().handle_terminal_event(ev) {
TerminalEditorResult::Exit => { TerminalEditorResult::Exit => {
match ev { match ev {
TerminalEvent::Input(Event::Key(Key::Ctrl('x'))) => {
return TerminalEditorResult::Exit
}
TerminalEvent::Input(Event::Key(Key::Backspace)) => { TerminalEvent::Input(Event::Key(Key::Backspace)) => {
self.editor.data.remove(idx as usize); self.editor.data.remove(idx as usize);
self.editor.cursor.set(ListCursor { self.editor.cursor.set(ListCursor {
@ -268,18 +273,32 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
} }
} }
/*
impl<ItemEditor> TreeType for PTYListEditor<ItemEditor>
where ItemEditor: Nested + TreeType + ?Sized + Send + Sync + 'static
{
fn get_type(&self, addr: &Vec<usize>) -> TypeTerm {
TypeTerm::new(0)
}
}
*/
impl<ItemEditor> Nested for PTYListEditor<ItemEditor> impl<ItemEditor> Nested for PTYListEditor<ItemEditor>
where ItemEditor: Nested + ?Sized + Send + Sync + 'static where ItemEditor: Nested + ?Sized + Send + Sync + 'static
{} {}
use crate::{ use crate::{
char_editor::CharEditor, char_editor::CharEditor,
sequence::SequenceViewExt sequence::SequenceViewExt,
StringGen
}; };
impl PTYListEditor<CharEditor> { impl<ItemEditor: StringGen + Nested + Send + Sync> StringGen for PTYListEditor<ItemEditor> {
pub fn get_string(&self) -> String {
self.get_data_port().map(|ce| ce.read().unwrap().get()).get_view().unwrap().iter().collect::<String>() fn get_string(&self) -> String {
self.get_data_port()
.map(|ce| ce.read().unwrap().get_string())
.get_view().unwrap()
.iter().collect::<String>()
} }
} }

View file

@ -1,4 +1,3 @@
use { use {
crate::{ crate::{
core::{TypeTerm, TypeLadder, Context, OuterViewPort}, core::{TypeTerm, TypeLadder, Context, OuterViewPort},
@ -17,38 +16,6 @@ use {
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
}; };
enum RhsNode {
Sum (
Arc<RwLock< PTYListEditor< RhsNode > >>
),
Product (
Arc<RwLock< PTYListEditor< RhsNode > >>
),
String(
Arc<RwLock< PTYListEditor< CharEditor > >>
)
}
impl TreeNav for RhsNode {}
impl TerminalEditor for RhsNode {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
make_label("todo")
}
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
TerminalEditorResult::Continue
}
}
impl Diagnostics for RhsNode {}
impl Nested for RhsNode {}
struct GrammarRuleEditor {
lhs: Arc<RwLock<PTYListEditor<CharEditor>>>,
rhs: Arc<RwLock<PTYListEditor<RhsNode>>>
}
pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> { pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
@ -56,7 +23,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
"Char", Arc::new( "Char", Arc::new(
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| { |ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
Some( Some(
Arc::new(RwLock::new(CharEditor::new())) Arc::new(RwLock::new(CharEditor::new_node(&ctx)))
as Arc<RwLock<dyn Nested + Send + Sync>>) as Arc<RwLock<dyn Nested + Send + Sync>>)
} }
) )
@ -70,7 +37,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
id, args id, args
} => { } => {
if args.len() > 0 { if args.len() > 0 {
// todod factor style out of type arGS // todo: factor style out of type arGS
let style = if args.len() > 1 { let style = if args.len() > 1 {
match args[1] { match args[1] {
TypeTerm::Num(0) => SeqDecorStyle::Plain, TypeTerm::Num(0) => SeqDecorStyle::Plain,
@ -82,23 +49,23 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
TypeTerm::Num(6) => SeqDecorStyle::Path, TypeTerm::Num(6) => SeqDecorStyle::Path,
_ => SeqDecorStyle::HorizontalSexpr _ => SeqDecorStyle::HorizontalSexpr
} }
}else { } else {
SeqDecorStyle::HorizontalSexpr SeqDecorStyle::HorizontalSexpr
}; };
let delim = if args.len() > 1 { let delim = if args.len() > 1 {
match args[1] { match args[1] {
TypeTerm::Num(0) => ' ', TypeTerm::Num(0) => Some(' '),
TypeTerm::Num(1) => ' ', TypeTerm::Num(1) => Some(' '),
TypeTerm::Num(2) => '\n', TypeTerm::Num(2) => Some('\n'),
TypeTerm::Num(3) => '"', TypeTerm::Num(3) => None,
TypeTerm::Num(4) => ',', TypeTerm::Num(4) => Some(','),
TypeTerm::Num(5) => ',', TypeTerm::Num(5) => Some(','),
TypeTerm::Num(6) => '/', TypeTerm::Num(6) => Some('/'),
_ => '\0' _ => None
} }
}else { }else {
'\0' None
}; };
Some( Some(
@ -168,12 +135,15 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
) )
); );
ctx.write().unwrap().add_typename("TerminalEvent".into());
ctx ctx
} }
pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> { pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent)))); let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
ctx.write().unwrap().add_typename("MachineInt".into());
ctx.write().unwrap().add_typename("Digit".into());
ctx.write().unwrap().add_typename("BigEndian".into()); ctx.write().unwrap().add_typename("BigEndian".into());
ctx.write().unwrap().add_editor_ctor( ctx.write().unwrap().add_editor_ctor(
"PosInt", Arc::new( "PosInt", Arc::new(

10
nested/src/path/mod.rs Normal file
View file

@ -0,0 +1,10 @@
pub struct PathSegmentEditor {
parent: Path,
}
pub struct PathEditor {
}

View file

@ -23,7 +23,7 @@ use {
pub struct SumEditor { pub struct SumEditor {
cur: usize, cur: usize,
editors: Vec< Arc<RwLock<dyn Nested + Send + Sync>> >, pub editors: Vec< Arc<RwLock<dyn Nested + Send + Sync + 'static>> >,
port: ViewPort< dyn TerminalView >, port: ViewPort< dyn TerminalView >,
diag_port: ViewPort< dyn SequenceView<Item = Message> > diag_port: ViewPort< dyn SequenceView<Item = Message> >
@ -31,7 +31,7 @@ pub struct SumEditor {
impl SumEditor { impl SumEditor {
pub fn new( pub fn new(
editors: Vec< Arc<RwLock<dyn Nested + Send + Sync>> > editors: Vec< Arc<RwLock<dyn Nested + Send + Sync + 'static>> >
) -> Self { ) -> Self {
let port = ViewPort::new(); let port = ViewPort::new();
//let mut diag_buf = VecBuffer::new(); //let mut diag_buf = VecBuffer::new();
@ -44,6 +44,10 @@ impl SumEditor {
} }
} }
pub fn get(&self) -> Arc<RwLock<dyn Nested + Send + Sync>> {
self.editors[ self.cur ].clone()
}
pub fn select(&mut self, idx: usize) { pub fn select(&mut self, idx: usize) {
self.cur = idx; self.cur = idx;

View file

@ -24,7 +24,7 @@ use {
}, },
}; };
#[derive(PartialEq, Eq)] #[derive(PartialEq, Eq, Clone)]
pub enum TerminalEvent { pub enum TerminalEvent {
Resize(Vector2<i16>), Resize(Vector2<i16>),
Input(termion::event::Event), Input(termion::event::Event),

9
nested/src/tree/addr.rs Normal file
View file

@ -0,0 +1,9 @@
pub struct TreeAddr(Vec<usize>);
impl From<Vec<usize>> for TreeAddr {
fn from(v: Vec<usize>) -> TreeAddr {
TreeAddr(v)
}
}

View file

@ -1,18 +1,12 @@
pub mod addr;
pub mod cursor; pub mod cursor;
pub mod nav; pub mod nav;
pub mod typeinfo; pub mod node;
pub struct TreeAddr(Vec<usize>);
impl From<Vec<usize>> for TreeAddr {
fn from(v: Vec<usize>) -> TreeAddr {
TreeAddr(v)
}
}
pub use { pub use {
addr::TreeAddr,
cursor::TreeCursor, cursor::TreeCursor,
nav::{TreeNav, TreeNavResult}, nav::{TreeNav, TreeNavResult},
typeinfo::TreeType node::NestedNode
}; };

124
nested/src/tree/node.rs Normal file
View file

@ -0,0 +1,124 @@
use {
std::sync::{Arc, RwLock},
cgmath::Vector2,
crate::{
core::{ViewPort, OuterViewPort, AnyOuterViewPort, context::ReprTree, Context},
singleton::{SingletonView, SingletonBuffer},
sequence::SequenceView,
terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
diagnostics::{Diagnostics, Message},
tree::{TreeNav, TreeCursor, TreeNavResult},
Commander, ObjCommander,
Nested
},
};
pub struct NestedNode {
ctx: Option<Arc<RwLock<Context>>>,
view: Option<OuterViewPort<dyn TerminalView>>,
diag: Option<OuterViewPort<dyn SequenceView<Item = Message>>>,
cmd: Option<Arc<RwLock<dyn ObjCommander + Send + Sync>>>,
tree_nav: Option<Arc<RwLock<dyn TreeNav + Send + Sync>>>,
}
impl ObjCommander for NestedNode {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
if let Some(cmd) = self.cmd.as_ref() {
cmd.write().unwrap().send_cmd_obj(cmd_obj);
}
}
}
impl TerminalEditor for NestedNode {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
self.get_view()
}
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
let buf = SingletonBuffer::new(event.clone());
if let (Some(cmd),Some(ctx)) = (self.cmd.as_ref(),self.ctx.as_ref()) {
cmd.write().unwrap().send_cmd_obj(
ReprTree::new_leaf(
ctx.read().unwrap().type_term_from_str("( TerminalEvent )").unwrap(),
AnyOuterViewPort::from(buf.get_port())
));
}
TerminalEditorResult::Continue
}
}
impl TreeNav for NestedNode {
fn get_cursor(&self) -> TreeCursor {
if let Some(tn) = self.tree_nav.as_ref() {
tn.read().unwrap().get_cursor()
} else {
TreeCursor::default()
}
}
fn get_cursor_warp(&self) -> TreeCursor {
if let Some(tn) = self.tree_nav.as_ref() {
tn.read().unwrap().get_cursor_warp()
} else {
TreeCursor::default()
}
}
fn get_max_depth(&self) -> usize {
0
}
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
if let Some(tn) = self.tree_nav.as_ref() {
tn.write().unwrap().goby(direction)
} else {
TreeNavResult::Exit
}
}
fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
if let Some(tn) = self.tree_nav.as_ref() {
tn.write().unwrap().goto(new_cursor)
} else {
TreeNavResult::Exit
}
}
}
impl Diagnostics for NestedNode {}
impl Nested for NestedNode {}
impl NestedNode {
pub fn new() -> Self {
NestedNode {
ctx: None,
view: None,
diag: None,
cmd: None,
tree_nav: None
}
}
pub fn set_ctx(mut self, ctx: Arc<RwLock<Context>>) -> Self {
self.ctx = Some(ctx);
self
}
pub fn set_view(mut self, view: OuterViewPort<dyn TerminalView>) -> Self {
self.view = Some(view);
self
}
pub fn with_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
self.cmd = Some(cmd);
self
}
pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> {
self.view.clone().unwrap_or(ViewPort::new().into_outer())
}
}

View file

@ -0,0 +1,155 @@
use {
crate::{
core::{ViewPort, OuterViewPort, TypeLadder, Context},
terminal::{TerminalEvent, TerminalView, TerminalEditor, TerminalEditorResult},
sequence::{SequenceView, decorator::SeqDecorStyle},
list::{PTYListEditor},
tree::{TreeNav, TreeCursor, TreeNavResult},
diagnostics::{Diagnostics, Message},
sum::SumEditor,
char_editor::CharEditor,
integer::PosIntEditor,
Nested
},
cgmath::{Vector2, Point2},
termion::event::{Event, Key},
std::{
sync::{Arc, RwLock},
any::Any
}
};
#[derive(Clone)]
enum TypeTermVar {
Any,
Symbol,
Num,
List
}
pub struct TypeTermEditor {
ty: TypeTermVar,
node: SumEditor,
}
impl TypeTermEditor {
pub fn new(ctx: Arc<RwLock<Context>>, depth: usize) -> Self {
TypeTermEditor {
ty: TypeTermVar::Any,
node: SumEditor::new(
vec![
Arc::new(RwLock::new(PTYListEditor::new(
Box::new({
let ctx = ctx.clone();
move || {
Arc::new(RwLock::new(TypeTermEditor::new(ctx.clone(), depth+1)))
}
}),
SeqDecorStyle::HorizontalSexpr,
Some(' '),
depth
))),
Arc::new(RwLock::new(PosIntEditor::new(10))),
Arc::new(RwLock::new(PTYListEditor::new(
Box::new({
let ctx = ctx.clone();
move || {
Arc::new(RwLock::new(CharEditor::new_node(&ctx)))
}
}),
SeqDecorStyle::Plain,
None,
depth
))),
])
}
}
}
impl TreeNav for TypeTermEditor {
fn get_cursor(&self) -> TreeCursor {
self.node.get_cursor()
}
fn get_cursor_warp(&self) -> TreeCursor {
self.node.get_cursor_warp()
}
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
self.node.goby( direction )
}
fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
self.node.goto( new_cursor )
}
}
impl TerminalEditor for TypeTermEditor {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
self.node.get_term_view()
}
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
match event {
TerminalEvent::Input( termion::event::Event::Key(Key::Char(c)) ) => {
match self.ty {
TypeTermVar::Any => {
self.ty =
if *c == '(' {
self.node.select(0);
self.dn();
TypeTermVar::List
} else if c.to_digit(10).is_some() {
self.node.select(1);
self.dn();
self.node.handle_terminal_event( event );
TypeTermVar::Num
} else {
self.node.select(2);
self.dn();
self.node.handle_terminal_event( event );
TypeTermVar::Symbol
};
TerminalEditorResult::Continue
},
_ => {
if *c == '(' {
let mut child = Arc::new(RwLock::new(TypeTermEditor {
ty: self.ty.clone(),
node: SumEditor::new(
vec![
self.node.editors[0].clone(),
self.node.editors[1].clone(),
self.node.editors[2].clone(),
])
}));
self.ty = TypeTermVar::List;
self.node.select(0);
/*
let l = self.node.editors[0].clone();
let l = l.downcast::<RwLock<PTYListEditor<TypeTermEditor>>>().unwrap();
l.write().unwrap().data.push(child);
*/
TerminalEditorResult::Continue
} else {
self.node.handle_terminal_event( event )
}
}
}
},
event => {
self.node.handle_terminal_event( event )
}
}
}
}
impl Diagnostics for TypeTermEditor {
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
self.node.get_msg_port()
}
}
impl Nested for TypeTermEditor {}

View file

@ -2,19 +2,19 @@ extern crate portable_pty;
mod ascii_box; mod ascii_box;
mod monstera; mod monstera;
mod process; //mod process;
mod pty; mod pty;
mod command; //mod command;
mod plot; mod plot;
use { use {
crate::{ crate::{
process::ProcessLauncher, // process::ProcessLauncher,
command::Commander // command::Commander
}, },
cgmath::{Point2, Vector2}, cgmath::{Point2, Vector2},
nested::{ nested::{
core::{port::UpdateTask, Observer, OuterViewPort, View, ViewPort, Context, TypeTerm}, core::{port::UpdateTask, Observer, OuterViewPort, AnyOuterViewPort, View, ViewPort, Context, TypeTerm, ReprTree},
index::IndexArea, index::IndexArea,
list::{ListCursorMode, PTYListEditor}, list::{ListCursorMode, PTYListEditor},
sequence::{SequenceView, decorator::{SeqDecorStyle, Separate}}, sequence::{SequenceView, decorator::{SeqDecorStyle, Separate}},
@ -29,6 +29,7 @@ use {
product::ProductEditor, product::ProductEditor,
sum::SumEditor, sum::SumEditor,
diagnostics::{Diagnostics}, diagnostics::{Diagnostics},
index::{buffer::IndexBuffer},
Nested Nested
}, },
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
@ -43,12 +44,20 @@ async fn main() {
let mut term = Terminal::new(term_port.outer()); let mut term = Terminal::new(term_port.outer());
let term_writer = term.get_writer(); let term_writer = term.get_writer();
let mut portmutex = Arc::new(RwLock::new(()));
// Update Loop // // Update Loop //
let tp = term_port.clone(); let tp = term_port.clone();
async_std::task::spawn(async move { async_std::task::spawn({
let portmutex = portmutex.clone();
async move {
loop { loop {
{
let l = portmutex.write().unwrap();
tp.update(); tp.update();
async_std::task::sleep(std::time::Duration::from_millis(30)).await; }
async_std::task::sleep(std::time::Duration::from_millis(10)).await;
}
} }
}); });
@ -58,16 +67,53 @@ async fn main() {
let ctx = nested::make_editor::init_math_ctx(ctx); let ctx = nested::make_editor::init_math_ctx(ctx);
let ctx = nested::make_editor::init_os_ctx(ctx); let ctx = nested::make_editor::init_os_ctx(ctx);
let mut vb = VecBuffer::<char>::new();
let mut rt_char = ReprTree::new_leaf(
ctx.read().unwrap().type_term_from_str("( List Char )").unwrap(),
AnyOuterViewPort::from(vb.get_port())
);
let mut rt_digit = ReprTree::upcast(&rt_char, ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )").unwrap());
rt_digit.write().unwrap().insert_branch(
ReprTree::new_leaf(
ctx.read().unwrap().type_term_from_str("( List MachineInt )").unwrap(),
AnyOuterViewPort::from(
vb.get_port().to_sequence().map(
|c: &char| {
c.to_digit(10).unwrap()
}
)
)
)
);
/*
ctx.write().unwrap().add_morphism(
MorphismType{
mode: MorphismMode::Iso,
src_type:
},
Box::new(
|repr| {
RadixProjection::new(
)
}
)
);
*/
let c = ctx.clone(); let c = ctx.clone();
let mut process_list_editor = let mut process_list_editor =
PTYListEditor::new( PTYListEditor::new(
Box::new( move || { Box::new( move || {
Arc::new(RwLock::new(Commander::new(ctx.clone()))) Arc::new(RwLock::new(nested::type_term_editor::TypeTermEditor::new(c.clone(), 1)))
// Arc::new(RwLock::new(CharEditor::new_node(&c)))
//Context::make_editor( c.clone(), c.read().unwrap().type_term_from_str("( String )").unwrap(), 1 ).unwrap()
}), }),
SeqDecorStyle::Plain, SeqDecorStyle::Plain,
'\0', Some('\n'),
0 0
); );
async_std::task::spawn(async move { async_std::task::spawn(async move {
let mut table = nested::index::buffer::IndexBuffer::new(); let mut table = nested::index::buffer::IndexBuffer::new();
@ -96,12 +142,49 @@ async fn main() {
(Point2::new(0, 4), (Point2::new(0, 4),
process_list_editor.editor process_list_editor.editor
.get_seg_seq_view() .get_seg_seq_view()
.separate( .enumerate()
make_label(" ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~") .map(
.map_item(|p,a| a.add_style_front(TerminalStyle::fg_color((40,40,40)))) |(n, segment)| {
let mut buf = IndexBuffer::new();
buf.insert_iter(vec![
(Point2::new(0, 0),
make_label(match n+1 {
1 => "I) ",
2 => "II) ",
3 => "III) ",
4 => "IV) ",
5 => "V) ",
6 => "VI) ",
7 => "VII) ",
8 => "IIX) ",
9 => "IX) ",
10 => "X) ",
_ => ""
})),
(Point2::new(1, 0), segment.clone())
]);
buf.get_port()
}
) )
/*
.separate({
let mut buf = IndexBuffer::new();
buf.insert(Point2::new(1,0),
make_label(" ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~")
.map_item(
|p,a|
a.add_style_front(TerminalStyle::fg_color((40,40,40)))
)
);
buf.get_port()
}
)
*/
.to_grid_vertical() .to_grid_vertical()
.flatten()), .flatten()
.flatten()
),
(Point2::new(0, 5), make_label(" ")), (Point2::new(0, 5), make_label(" ")),
(Point2::new(0, 6), magic.clone()), (Point2::new(0, 6), magic.clone()),
@ -165,62 +248,18 @@ async fn main() {
tree_addr: vec![0], tree_addr: vec![0],
}); });
loop { loop {
status_chars.clear();
let cur = process_list_editor.get_cursor();
if cur.tree_addr.len() > 0 {
status_chars.push(TerminalAtom::new(
'@',
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
));
for x in cur.tree_addr {
for c in format!("{}", x).chars() {
status_chars
.push(TerminalAtom::new(c, TerminalStyle::fg_color((0, 100, 20))));
}
status_chars.push(TerminalAtom::new(
'.',
TerminalStyle::fg_color((150, 80,230))
));
}
status_chars.push(TerminalAtom::new(
':',
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
));
for c in match cur.leaf_mode {
ListCursorMode::Insert => "INSERT",
ListCursorMode::Select => "SELECT"
}
.chars()
{
status_chars.push(TerminalAtom::new(
c,
TerminalStyle::fg_color((200, 200, 20)),
));
}
status_chars.push(TerminalAtom::new(
':',
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
));
} else {
for c in "Press <DN> to enter".chars() {
status_chars.push(TerminalAtom::new(
c,
TerminalStyle::fg_color((200, 200, 20)),
));
}
}
let ev = term.next_event().await; let ev = term.next_event().await;
let l = portmutex.write().unwrap();
if let TerminalEvent::Resize(new_size) = ev { if let TerminalEvent::Resize(new_size) = ev {
cur_size.set(new_size); cur_size.set(new_size);
term_port.inner().get_broadcast().notify(&IndexArea::Full); term_port.inner().get_broadcast().notify(&IndexArea::Full);
continue; continue;
} }
/* /*
if let Some(process_editor) = process_list_editor.get_item() { if let Some(process_editor) = process_list_editor.get_item() {
let mut pe = process_editor.write().unwrap(); let mut pe = process_editor.write().unwrap();
@ -284,6 +323,54 @@ async fn main() {
} }
} }
} }
status_chars.clear();
let cur = process_list_editor.get_cursor();
if cur.tree_addr.len() > 0 {
status_chars.push(TerminalAtom::new(
'@',
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
));
for x in cur.tree_addr {
for c in format!("{}", x).chars() {
status_chars
.push(TerminalAtom::new(c, TerminalStyle::fg_color((0, 100, 20))));
}
status_chars.push(TerminalAtom::new(
'.',
TerminalStyle::fg_color((150, 80,230))
));
}
status_chars.push(TerminalAtom::new(
':',
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
));
for c in match cur.leaf_mode {
ListCursorMode::Insert => "INSERT",
ListCursorMode::Select => "SELECT"
}
.chars()
{
status_chars.push(TerminalAtom::new(
c,
TerminalStyle::fg_color((200, 200, 20)),
));
}
status_chars.push(TerminalAtom::new(
':',
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
));
} else {
for c in "Press <DN> to enter".chars() {
status_chars.push(TerminalAtom::new(
c,
TerminalStyle::fg_color((200, 200, 20)),
));
}
}
} }
drop(term); drop(term);

View file

@ -21,7 +21,7 @@ use {
}; };
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
/*
pub struct ProcessArg { pub struct ProcessArg {
editor: editor:
PTYListEditor<CharEditor>, PTYListEditor<CharEditor>,
@ -274,4 +274,4 @@ impl Diagnostics for ProcessLauncher {
} }
impl Nested for ProcessLauncher {} impl Nested for ProcessLauncher {}
*/