From 4c0e9da2d31272abc9609438731e23da85e1f3c7 Mon Sep 17 00:00:00 2001
From: Michael Sippel <micha@fragmental.art>
Date: Sat, 3 Aug 2024 15:44:04 +0200
Subject: [PATCH] fixup examples

also fix behaviour of insert_leaf() & attach_leaf_to() when type of current repr-node occurs inside the type of the leaf
---
 examples/tty-02-digit/src/main.rs         | 25 ++++---
 examples/tty-03-string/src/main.rs        | 38 +++++++---
 lib-nested-core/src/editors/digit/ctx.rs  | 11 +--
 lib-nested-core/src/editors/list/ctx.rs   | 57 +++------------
 lib-nested-core/src/repr_tree/mod.rs      | 86 +++++++++++------------
 lib-nested-core/src/repr_tree/morphism.rs |  2 +-
 6 files changed, 101 insertions(+), 118 deletions(-)

diff --git a/examples/tty-02-digit/src/main.rs b/examples/tty-02-digit/src/main.rs
index 61603b1..c7df17e 100644
--- a/examples/tty-02-digit/src/main.rs
+++ b/examples/tty-02-digit/src/main.rs
@@ -72,13 +72,16 @@ async fn main() {
     ctx.read().unwrap().morphisms.apply_morphism(
         rt_digit.clone(),
         &Context::parse(&ctx, "<Digit 16>~Char"),
-        &Context::parse(&ctx, "<Digit 16>~ℤ_256~machine::UInt8")
+        &Context::parse(&ctx, "<Digit 16>~ℤ_2^64~machine.UInt64")
+    );
+
+    ctx.read().unwrap().morphisms.apply_morphism(
+        rt_digit.clone(),
+        &Context::parse(&ctx, "<Digit 16>~Char"),
+        &Context::parse(&ctx, "<Digit 16>~EditTree")
     );
 
     /* setup TTY-Display for DigitEditor
-     *
-     * `setup_edittree` will setup the projection
-     *    Char -> Char~EditTree
      *  and call the hook defined above with `set_edittree_hook()`
      *
      */
@@ -86,11 +89,11 @@ async fn main() {
         .setup_edittree(
             rt_digit.clone(),
             SingletonBuffer::new(0).get_port()
-        );
+        ).unwrap();
 
-    let mut digit_u8_buffer = rt_digit
-        .descend(Context::parse(&ctx, "ℤ_256~machine::UInt8")).unwrap()
-        .singleton_buffer::<u8>();
+    let mut digit_u64_buffer = rt_digit
+        .descend(Context::parse(&ctx, "ℤ_2^64~machine.UInt64")).unwrap()
+        .singleton_buffer::<u64>();
 
     /* setup terminal
      */
@@ -101,7 +104,7 @@ async fn main() {
 
         let mut edittree_digit = edittree_digit.clone();
         move |ev| {
-            edittree_digit.get().send_cmd_obj(ev.to_repr_tree(&ctx));
+            edittree_digit.get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx));
         }
     });
 
@@ -128,11 +131,11 @@ async fn main() {
             .offset(Vector2::new(1, 1))
         );
         comp.push(
-            edittree_digit.get().display_view()
+            edittree_digit.get().read().unwrap().display_view()
             .offset(Vector2::new(3,2))
         );
         comp.push(
-            digit_u8_buffer.get_port().map(
+            digit_u64_buffer.get_port().map(
                 |d| nested_tty::make_label(&format!("Digit value={}", d))
             )
             .to_grid()
diff --git a/examples/tty-03-string/src/main.rs b/examples/tty-03-string/src/main.rs
index 0d8f670..dfa84e1 100644
--- a/examples/tty-03-string/src/main.rs
+++ b/examples/tty-03-string/src/main.rs
@@ -25,7 +25,7 @@ use {
     },
     r3vi::{
         buffer::{singleton::*, vec::*},
-        view::{port::UpdateTask, list::*}
+        view::{port::UpdateTask, list::*, sequence::SequenceViewExt}
     },
     std::sync::{Arc, RwLock},
 };
@@ -43,15 +43,32 @@ async fn main() {
 
     /* Create a Representation-Tree of type <List Char>
      */
-    let rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") );
+    let mut rt_string = ReprTree::new_arc( Context::parse(&ctx, "<List Char>") );
 
-    /* Setup an Editor for this ReprTree
-     * (this will add the representation <List Char>~EditTree to the ReprTree)
+    let vec = VecBuffer::<Arc<RwLock<EditTree>>>::new();
+    rt_string.insert_leaf(
+        Context::parse(&ctx, "<List EditTree> ~ <Vec EditTree>"),
+        nested::repr_tree::ReprLeaf::from_vec_buffer( vec.clone() )
+    );
+
+    let v2 = VecBuffer::<char>::new();
+    rt_string.insert_leaf(
+        Context::parse(&ctx, "<Vec Char>"),
+        nested::repr_tree::ReprLeaf::from_vec_buffer( v2.clone() )
+    );
+    ctx.read().unwrap().morphisms.apply_morphism(
+        rt_string.clone(),
+        &Context::parse(&ctx, "<List Char~EditTree> ~ <Vec EditTree>"),
+        &Context::parse(&ctx, "<List Char> ~ EditTree")
+    );
+
+    /* Setup the Editor-View for this ReprTree
      */
     let edittree_list = ctx.read().unwrap()
         .setup_edittree(
             rt_string.clone(),
-            SingletonBuffer::new(0).get_port());
+            SingletonBuffer::new(0).get_port()
+        ).unwrap();
 
     /* In order to get acces to the values that are modified by the Editor,
      * we apply a morphism that, given the List of Edit-Trees, extracts
@@ -71,7 +88,6 @@ async fn main() {
         .get_port::<dyn ListView<char>>()
         .unwrap();
 
-
     /* Lets add another morphism which will store the values
      * of the character-list in a `Vec<char>`
      */
@@ -104,7 +120,7 @@ async fn main() {
          */
         let ctx = ctx.clone();
         move |ev| {
-            edittree_list.get().send_cmd_obj(ev.to_repr_tree(&ctx));
+            edittree_list.get().write().unwrap().send_cmd_obj(ev.to_repr_tree(&ctx));
         }
     });
 
@@ -127,6 +143,7 @@ async fn main() {
 
         comp.push(
             edittree_list.get()
+                .read().unwrap()
                 .display_view()
                 .offset(Vector2::new(3,2)));
 
@@ -145,8 +162,11 @@ async fn main() {
 
     /* Vec<char> to String
      */
-    let string = chars_vec.data
-        .read().unwrap()
+    let string = chars_vec
+        .get_port()
+        .to_sequence()
+        .get_view().unwrap()
+        //.data.read().unwrap()
         .iter().collect::<String>();
 
     eprintln!("value of the editor was: {}\n\n", string);
diff --git a/lib-nested-core/src/editors/digit/ctx.rs b/lib-nested-core/src/editors/digit/ctx.rs
index 538780c..40a7826 100644
--- a/lib-nested-core/src/editors/digit/ctx.rs
+++ b/lib-nested-core/src/editors/digit/ctx.rs
@@ -19,10 +19,10 @@ 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>"),
+                src_type: Context::parse(&ctx, "<Digit Radix>~Char"),
                 dst_type: Context::parse(&ctx, "<Digit Radix>~EditTree")
             };
 
@@ -45,6 +45,9 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
                         if let Some(crt) = src_rt.descend(Context::parse(&ctx, "Char")) {
                             crt
                         } else {
+                            /* TODO: replace this with some formal specification
+                             *       of "required representations"
+                             */
                             let crt = ReprTree::from_singleton_buffer(
                                 Context::parse(&ctx, "Char"),
                                 SingletonBuffer::new('\0')
@@ -70,13 +73,13 @@ pub fn init_ctx( ctx: Arc<RwLock<Context>> ) {
                         .insert_branch(
                             ReprTree::from_singleton_buffer(
                                 Context::parse(&ctx, "EditTree"),
-                                SingletonBuffer::new(edittree)
+                                SingletonBuffer::new(Arc::new(RwLock::new(edittree)))
                             )
                         );
                 }
             }
         );
-*/
+
     let morphtype =
             crate::repr_tree::MorphismType {
                 src_type: Context::parse(&ctx, "<Digit Radix>~Char"),
diff --git a/lib-nested-core/src/editors/list/ctx.rs b/lib-nested-core/src/editors/list/ctx.rs
index d35ec7a..93a47a5 100644
--- a/lib-nested-core/src/editors/list/ctx.rs
+++ b/lib-nested-core/src/editors/list/ctx.rs
@@ -24,49 +24,7 @@ use {
 
 pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
     ctx.write().unwrap().add_varname("Item");
-/*
-    let mt = crate::repr_tree::MorphismType {
-        src_type: Context::parse(&ctx, "<List Char>"),
-        dst_type: Context::parse(&ctx, "<List Char~EditTree>")
-    };
-    ctx.write().unwrap().morphisms.add_morphism(mt, {
-        let ctx = ctx.clone();
-        move |src_rt, σ| {
-            let list_port = src_rt.descend(Context::parse(&ctx, "<List Char>")).expect("descend").get_port::<dyn ListView<char>>().clone();
-            if let Some(list_port) = list_port {
 
-                // for each char, create EditTree
-                let edit_tree_list = 
-                        list_port
-                        .map({
-                            let ctx = ctx.clone();
-                            move |c| {
-                                let item_rt = ReprTree::from_char(&ctx, *c);
-
-                                ctx.read().unwrap().setup_edittree(
-                                    item_rt.clone(),
-                                    SingletonBuffer::new(0).get_port()
-                                );
-
-                                let et = item_rt
-                                    .descend(Context::parse(&ctx, "Char ~ EditTree")).expect("cant descend repr tree")
-                                    .get_port::< dyn SingletonView<Item = EditTree> >().expect("cant get view port (EditTree)")
-                                    .get_view().unwrap()
-                                    .get();
-                                Arc::new(RwLock::new(et))
-                            }
-                        });
-
-                src_rt.attach_leaf_to(
-                    Context::parse(&ctx, "<List Char>~<List EditTree>"),
-                    edit_tree_list
-                );
-            } else {
-                eprintln!("morphism missing view port");
-            }
-        }
-    });
-*/
     let mt = crate::repr_tree::MorphismType {
         src_type: Context::parse(&ctx, "<List Item>~<List EditTree>~<Vec EditTree>"),
         dst_type: Context::parse(&ctx, "<List Item>~EditTree")
@@ -93,6 +51,7 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
                 src_rt.insert_leaf(
                     Context::parse(&ctx, "<List Item> ~ EditTree")
                         .apply_substitution(&|id| σ.get(id).cloned()).clone(),
+
                     ReprLeaf::from_singleton_buffer(
                         SingletonBuffer::new(Arc::new(RwLock::new(edittree_list)))
                     )
@@ -123,14 +82,15 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
                 src_rt.insert_leaf(
                     Context::parse(&ctx, "<List Char>"),
                     ReprLeaf::from_view(
-                    edittree_items
+                        edittree_items
                         .map(|edittree_char|
                             edittree_char
                                 .read().unwrap()
                                 .get_edit::<CharEditor>().unwrap()
                                 .read().unwrap()
                                 .get()
-                        ))
+                        )
+                    )
                 );
             }
         }
@@ -148,13 +108,12 @@ pub fn init_ctx(ctx: Arc<RwLock<Context>>) {
         {
             let ctx = ctx.clone();
             move |src_rt, σ| {
+                let list_view = src_rt.view_list::<char>();
+
                 src_rt
                     .attach_leaf_to(
-                        Context::parse(&ctx, "<List Char>~<Vec Char>"),
-                        src_rt
-                            .descend(Context::parse(&ctx, "<List Char>"))
-                            .expect("descend")
-                            .view_list::<char>()
+                        Context::parse(&ctx, "<Vec Char>"),
+                        list_view
                     );
             }
         }
diff --git a/lib-nested-core/src/repr_tree/mod.rs b/lib-nested-core/src/repr_tree/mod.rs
index bad1396..ac1d18b 100644
--- a/lib-nested-core/src/repr_tree/mod.rs
+++ b/lib-nested-core/src/repr_tree/mod.rs
@@ -345,41 +345,6 @@ impl ReprTree {
         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 &rung_type == self.get_type() {
-                if let Some(leaf) = self.leaf.as_mut() {
-                    leaf.attach_to(src_port);
-                } else {
-                    self.leaf = Some(ReprLeaf::from_view(src_port));
-                }
-            } else {
-                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 attach_to<V>(
         &mut self,
         src_port: OuterViewPort<V>
@@ -394,6 +359,36 @@ impl ReprTree {
         }
     }
 
+    /// 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
+    {
+        while let Some(rung_type) = type_ladder.next() {
+            if &rung_type != self.get_type() {
+                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)));
+                }
+                return;
+            }
+        }
+        
+        if let Some(leaf) = self.leaf.as_mut() {
+            leaf.attach_to(src_port);
+        } else {
+            self.leaf = Some(ReprLeaf::from_view(src_port));
+        }
+    }
+
     pub fn detach(&mut self, ctx: &Arc<RwLock<Context>>) {
         if let Some(leaf) = self.leaf.as_mut() {
             if self.type_tag == Context::parse(&ctx, "Char") {
@@ -417,17 +412,20 @@ impl ReprTree {
         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)));
+        while let Some(type_term) = type_ladder.next() {
+            if &type_term != self.get_type() {
+                if let Some(next_repr) = self.branches.get(&type_term) {
+                    next_repr.write().unwrap().insert_leaf(type_ladder, leaf.clone());
+                } else {
+                    let mut next_repr = ReprTree::new(type_term.clone());
+                    next_repr.insert_leaf(type_ladder, leaf.clone());
+                    self.insert_branch(Arc::new(RwLock::new(next_repr)));
+                }
+                return;
             }
-        } else {
-            self.leaf = Some(leaf)
         }
+
+        self.leaf = Some(leaf);
     }
 
     //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
diff --git a/lib-nested-core/src/repr_tree/morphism.rs b/lib-nested-core/src/repr_tree/morphism.rs
index 32db193..1607d6a 100644
--- a/lib-nested-core/src/repr_tree/morphism.rs
+++ b/lib-nested-core/src/repr_tree/morphism.rs
@@ -251,7 +251,7 @@ impl MorphismBase {
 
             Some((m, σ))
         } else {
-            eprintln!("could not find item morphism\n");
+//            eprintln!("could not find item morphism\n");
             None
         }
     }