Jonathan Kelley пре 4 година
родитељ
комит
8dc2619
3 измењених фајлова са 57 додато и 28 уклоњено
  1. 33 1
      packages/core/src/scope.rs
  2. 2 21
      packages/core/src/virtual_dom.rs
  3. 22 6
      packages/web/examples/infer.rs

+ 33 - 1
packages/core/src/scope.rs

@@ -43,7 +43,8 @@ pub struct Scope {
     // - is self-refenrential and therefore needs to point into the bump
     //
     // Stores references into the listeners attached to the vnodes
-    pub listeners: RefCell<Vec<*const dyn Fn(crate::events::VirtualEvent)>>,
+    // NEEDS TO BE PRIVATE
+    listeners: RefCell<Vec<*const dyn Fn(crate::events::VirtualEvent)>>,
 
     // Unsafety
     // - is a raw ptr because we need to compare
@@ -94,6 +95,37 @@ impl Scope {
             props,
         }
     }
+
+    // A safe wrapper around calling listeners
+    // calling listeners will invalidate the list of listeners
+    // The listener list will be completely drained because the next frame will write over previous listeners
+    pub fn call_listener(&mut self, trigger: EventTrigger) {
+        let EventTrigger {
+            listener_id,
+            event: source,
+            ..
+        } = trigger;
+
+        unsafe {
+            let listener = self
+                .listeners
+                .borrow()
+                .get(listener_id as usize)
+                .expect("Listener should exist if it was triggered")
+                .as_ref()
+                .unwrap();
+
+            // Run the callback with the user event
+            log::debug!("Running listener");
+            listener(source);
+            log::debug!("Running listener");
+
+            // drain all the event listeners
+            // if we don't, then they'll stick around and become invalid
+            // big big big big safety issue
+            self.listeners.borrow_mut().drain(..);
+        }
+    }
 }
 
 pub struct RawComponent {

+ 2 - 21
packages/core/src/virtual_dom.rs

@@ -125,31 +125,12 @@ impl VirtualDom {
     ///
     /// ```
     pub fn progress_with_event(&mut self, event: EventTrigger) -> Result<EditList<'_>> {
-        let EventTrigger {
-            component_id,
-            listener_id,
-            event: source,
-        } = event;
-
         let component = self
             .components
-            .get_mut(component_id)
+            .get_mut(event.component_id)
             .expect("Component should exist if an event was triggered");
 
-        log::debug!("list: {}", component.listeners.borrow().len());
-
-        let listener = unsafe {
-            component
-                .listeners
-                .borrow()
-                .get(listener_id as usize)
-                .expect("Listener should exist if it was triggered")
-                .as_ref()
-        }
-        .unwrap();
-
-        // Run the callback with the user event
-        listener(source);
+        component.call_listener(event);
 
         // Reset and then build a new diff machine
         // The previous edit list cannot be around while &mut is held

+ 22 - 6
packages/web/examples/infer.rs

@@ -10,16 +10,32 @@ fn main() {
 }
 
 static Example: FC<()> = |ctx, _props| {
+    let (event, set_event) = use_state(&ctx, || None);
+    let event = format!("{:#?}", event);
+
     let handler = move |evt: MouseEvent| {
-        // Awesome!
-        // We get type inference with events
-        dbg!(evt.alt_key);
+        set_event(Some(evt));
     };
 
     ctx.render(rsx! {
-        button {
-            "Hello"
-            onclick: {handler}
+        div {  
+            
+            class: "py-12 px-4 w-full max-w-2xl mx-auto bg-red-100"
+            // class: "py-12 px-4 text-center w-full max-w-2xl mx-auto bg-red-100"
+            span { 
+                class: "text-sm font-semibold"
+                "Dioxus Example: Synthetic Events"
+            }            
+            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"
+                
+                "press me"
+            }
+            pre {
+                onmousemove: {handler}
+                id: "json"
+                "{event}"
+            }
         }
     })
 };