소스 검색

Fix: some stuff related to event listeners. POC for lifecyel

Jonathan Kelley 4 년 전
부모
커밋
5b7887d
6개의 변경된 파일103개의 추가작업 그리고 24개의 파일을 삭제
  1. 11 1
      packages/core/src/patch.rs
  2. 9 2
      packages/core/src/scope.rs
  3. 4 5
      packages/core/src/virtual_dom.rs
  4. 58 12
      packages/web/examples/rsxt.rs
  5. 20 3
      packages/web/src/interpreter.rs
  6. 1 1
      packages/web/src/lib.rs

+ 11 - 1
packages/core/src/patch.rs

@@ -146,13 +146,17 @@ pub struct EditMachine<'lock> {
     pub traversal: Traversal,
     next_temporary: u32,
     forcing_new_listeners: bool,
-
+    
+    // // if the current node is a "known" node
+    // // any actions that modify this node should update the mapping
+    // current_known: Option<u32>,
     pub emitter: EditList<'lock>,
 }
 
 impl<'lock> EditMachine<'lock> {
     pub fn new() -> Self {
         Self {
+            // current_known: None,
             traversal: Traversal::new(),
             next_temporary: 0,
             forcing_new_listeners: false,
@@ -283,6 +287,11 @@ impl<'a> EditMachine<'a> {
         debug_assert!(self.traversal_is_committed());
         // debug!("emit: replace_with()");
         self.emitter.push(Edit::ReplaceWith {});
+        // if let Some(id) = self.current_known {
+        //     // update mapping
+        //     self.emitter.push(Edit::MakeKnown{node: id});
+        //     self.current_known = None;
+        // }
         // self.emitter.replace_with();
     }
 
@@ -377,6 +386,7 @@ impl<'a> EditMachine<'a> {
 
     pub fn load_known_root(&mut self, id: u32) {
         log::debug!("emit: TraverseToKnown({:?})", id);
+        // self.current_known = Some(id);
         self.emitter.push(Edit::TraverseToKnown { node: id })
     }
 

+ 9 - 2
packages/core/src/scope.rs

@@ -73,6 +73,12 @@ impl Scope {
         }
     }
 
+    pub fn update_caller<'creator_node>(&mut self, caller: Weak<OpaqueComponent<'creator_node>>) {
+        let broken_caller: Weak<OpaqueComponent<'static>> = unsafe { std::mem::transmute(caller) };
+
+        self.caller = broken_caller;
+    }
+
     /// Create a new context and run the component with references from the Virtual Dom
     /// This function downcasts the function pointer based on the stored props_type
     ///
@@ -115,13 +121,14 @@ impl Scope {
         - Public API cannot drop or destructure VNode
         */
 
-        frame.head_node = node_slot.as_ref()
+        frame.head_node = node_slot
+            .as_ref()
             // .deref()
             .borrow_mut()
             .take()
             .expect("Viewing did not happen");
 
-            Ok(())
+        Ok(())
     }
 
     // A safe wrapper around calling listeners

+ 4 - 5
packages/core/src/virtual_dom.rs

@@ -3,7 +3,7 @@
 use crate::{error::Error, innerlude::*};
 use crate::{patch::Edit, scope::Scope};
 use generational_arena::Arena;
-use std::{any::TypeId, borrow::Borrow, rc::{Rc, Weak}};
+use std::{any::TypeId, borrow::{Borrow, BorrowMut}, rc::{Rc, Weak}};
 use thiserror::private::AsDynError;
 
 // We actually allocate the properties for components in their parent's properties
@@ -119,21 +119,20 @@ impl VirtualDom {
                         diff_machine.change_list.load_known_root(id);
                         
                         diff_machine.diff_node(c.old_frame(), c.new_frame());
-                        diff_machine.change_list.save_known_root(id);
+                        // diff_machine.change_list.save_known_root(id);
                     }
                 }
                 LifeCycleEvent::PropsChanged { caller, id, scope } => {
                     let idx = scope.upgrade().unwrap().as_ref().borrow().unwrap();
 
-                    // We're modifying the component arena while holding onto references into the assoiated bump arenas of its children
-                    // those references are stable, even if the component arena moves around in memory, thanks to the bump arenas.
-                    // However, there is no way to convey this to rust, so we need to use unsafe to pierce through the lifetime.
                     unsafe {
                         let p = &mut *(very_unsafe_components);
                         // todo, hook up the parent/child indexes properly
                         // let idx = p.insert_with(|f| Scope::new(caller, f, None));
                         let c = p.get_mut(idx).unwrap();                        
+                        c.update_caller(caller);
                         c.run_scope()?;
+                        // c.caller = caller;
 
                         diff_machine.change_list.load_known_root(id);
 

+ 58 - 12
packages/web/examples/rsxt.rs

@@ -40,10 +40,56 @@ static Example: FC<ExampleProps> = |ctx, props| {
             }
             
             // CustomButton { name: sub, set_name: Box::new(move || set_name("jack")) }
-            CustomButton { name: "Jack!", set_name: Box::new(move || set_name("jack")) }
-            CustomButton { name: "Jill!", set_name: Box::new(move || set_name("jill")) }
-            CustomButton { name: "Bill!", set_name: Box::new(move || set_name("Bill")) }
-            CustomButton { name: "Reset!", set_name: Box::new(move || set_name(props.initial_name)) }
+            CustomButton { name: "Jack!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bob!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Dill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Crack!", set_name: Box::new(set_name) }
+            CustomButton { name: "back!", set_name: Box::new(set_name) }
+            CustomButton { name: "cheder!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jack!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bob!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Dill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Crack!", set_name: Box::new(set_name) }
+            CustomButton { name: "back!", set_name: Box::new(set_name) }
+            CustomButton { name: "cheder!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jack!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bob!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Dill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Crack!", set_name: Box::new(set_name) }
+            CustomButton { name: "back!", set_name: Box::new(set_name) }
+            CustomButton { name: "cheder!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jack!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bob!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Dill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Crack!", set_name: Box::new(set_name) }
+            CustomButton { name: "back!", set_name: Box::new(set_name) }
+            CustomButton { name: "cheder!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jack!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bob!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Dill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Crack!", set_name: Box::new(set_name) }
+            CustomButton { name: "back!", set_name: Box::new(set_name) }
+            CustomButton { name: "cheder!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jack!", set_name: Box::new(set_name) }
+            CustomButton { name: "Jill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bob!", set_name: Box::new(set_name) }
+            CustomButton { name: "Bill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Dill!", set_name: Box::new(set_name) }
+            CustomButton { name: "Crack!", set_name: Box::new(set_name) }
+            CustomButton { name: "back!", set_name: Box::new(set_name) }
+            CustomButton { name: "cheder!", set_name: Box::new(set_name) }
+            // CustomButton { name: "Bill!", set_name: Box::new(move || set_name("Bill")) }
+            // CustomButton { name: "Reset!", set_name: Box::new(move || set_name(props.initial_name)) }
 
         }
     })
@@ -51,9 +97,9 @@ static Example: FC<ExampleProps> = |ctx, props| {
 
 #[derive(Props)]
 struct ButtonProps<'src> {
-    name: &'src str,
+    name: &'static str,
     // name: &'src str,
-    set_name: Box< dyn Fn() + 'src>
+    set_name: Box< dyn Fn(&'static str) + 'src>
 }
 impl PartialEq for ButtonProps<'_> {
     fn eq(&self, other: &Self) -> bool {
@@ -63,13 +109,13 @@ impl PartialEq for ButtonProps<'_> {
 
 fn CustomButton<'a>(ctx: Context<'a>, props: &'a ButtonProps<'a>) -> DomTree {
     ctx.render(rsx!{
-        div {
-            button {  
-                class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
-                onmouseover: move |_| (props.set_name)()
-                "{props.name}"
-            }
+        // div {
+        button {  
+            class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
+            onmouseover: move |_| (props.set_name)(props.name)
+            "{props.name}"
         }
+        // }
     })
 }
 

+ 20 - 3
packages/web/src/interpreter.rs

@@ -36,6 +36,8 @@ pub(crate) struct PatchMachine {
     pub(crate) document: Document,
 
     pub(crate) events: EventDelegater,
+
+    pub(crate) current_known: Option<u32>,
 }
 
 #[derive(Debug)]
@@ -95,9 +97,13 @@ impl EventDelegater {
 
                 if let (Some(gi_id), Some(gi_gen), Some(li_idx)) = (gi_id, gi_gen, li_idx) {
                     // Call the trigger
+                    log::debug!("decoded gi_id: {},  gi_gen: {},  li_idx: {}", gi_id,gi_gen,li_idx);
+
+                    let triggered_scope = ScopeIdx::from_raw_parts(gi_id, gi_gen);
                     trigger.0.as_ref()(EventTrigger::new(
                         virtual_event_from_websys_event(event),
-                        scope,
+                        triggered_scope,
+                        // scope,
                         li_idx,
                     ));
                 }
@@ -167,6 +173,7 @@ impl PatchMachine {
         let events = EventDelegater::new(root.clone(), event_callback);
 
         Self {
+            current_known: None,
             known_roots: Default::default(),
             root,
             events,
@@ -250,6 +257,13 @@ impl PatchMachine {
                     panic!("Cannot replace node: {:?}", old_node);
                 }
 
+                // poc to see if this is a valid solution
+                if let Some(id) = self.current_known {
+                    // update mapping
+                    self.known_roots.insert(id, new_node.clone());
+                    self.current_known = None;
+                }
+
                 self.stack.push(new_node);
             }
 
@@ -485,9 +499,12 @@ impl PatchMachine {
                 self.known_roots.insert(node, domnode.clone());
             }
             Edit::TraverseToKnown { node } => {
-                let domnode = self.known_roots.get(&node).expect("Failed to pop know root");
+                let domnode = self
+                    .known_roots
+                    .get(&node)
+                    .expect("Failed to pop know root");
+                self.current_known = Some(node);
                 self.stack.push(domnode.clone());
-
             }
             Edit::RemoveKnown => {}
         }

+ 1 - 1
packages/web/src/lib.rs

@@ -102,7 +102,7 @@ impl WebsysRenderer {
 
             for edit in &edits {
                 log::debug!("edit stream {:?}", edit);
-                log::debug!("Stream stack {:#?}", patch_machine.stack.top());
+                // log::debug!("Stream stack {:#?}", patch_machine.stack.top());
                 patch_machine.handle_edit(edit);
             }