Przeglądaj źródła

wip: more clean up

Jonathan Kelley 3 lat temu
rodzic
commit
5a09ec1

+ 6 - 11
packages/core/src/diff.rs

@@ -113,7 +113,7 @@ pub(crate) struct DiffMachine<'bump> {
 }
 
 pub(crate) struct DiffCfg {
-    force_diff: bool,
+    pub force_diff: bool,
 }
 impl Default for DiffCfg {
     fn default() -> Self {
@@ -172,6 +172,7 @@ impl<'bump> DiffMachine<'bump> {
         if let Some(component) = self.vdom.get_scope_mut(id) {
             let (old, new) = (component.frames.wip_head(), component.frames.fin_head());
             self.stack.push(DiffInstruction::Diff { new, old });
+            self.work(|| false);
         }
     }
 
@@ -535,17 +536,11 @@ impl<'bump> DiffMachine<'bump> {
             scope.update_scope_dependencies(new.caller.clone(), ScopeChildren(new.children));
 
             // React doesn't automatically memoize, but we do.
-            let compare = old.comparator.unwrap();
+            let props_are_the_same = old.comparator.unwrap();
 
-            match compare(new) {
-                true => {
-                    // the props are the same... do nothing
-                }
-                false => {
-                    // the props are different...
-                    if scope.run_scope(self.vdom) {
-                        self.diff_node(scope.frames.wip_head(), scope.frames.fin_head());
-                    }
+            if self.cfg.force_diff || !props_are_the_same(new) {
+                if scope.run_scope(self.vdom) {
+                    self.diff_node(scope.frames.wip_head(), scope.frames.fin_head());
                 }
             }
 

+ 2 - 0
packages/core/src/nodes.rs

@@ -488,6 +488,8 @@ impl<'a> NodeFactory<'a> {
                         std::mem::drop(b);
 
                         has_dropped = true;
+                    } else {
+                        panic!("Drop props called twice - this is an internal failure of Dioxus");
                     }
                 }
             });

+ 0 - 4
packages/core/src/scheduler.rs

@@ -566,10 +566,6 @@ impl Scheduler {
         //     EventPriority::Low => self.low_priority.dirty_scopes.insert(scope),
         // };
     }
-
-    fn collect_garbage(&mut self, id: ElementId) {
-        //
-    }
 }
 
 pub(crate) struct PriorityLane {

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

@@ -120,9 +120,10 @@ impl VirtualDom {
     /// let mutations = dom.rebuild();
     /// ```
     pub fn new_with_props<P: Properties + 'static>(root: FC<P>, root_props: P) -> Self {
-        let scheduler = Scheduler::new();
+        let root_fc = Box::new(root);
 
         let root_props: Pin<Box<dyn Any>> = Box::pin(root_props);
+
         let props_ptr = root_props.downcast_ref::<P>().unwrap() as *const P;
 
         let root_caller: Box<dyn Fn(&Scope) -> DomTree> = Box::new(move |scope: &Scope| unsafe {
@@ -130,6 +131,8 @@ impl VirtualDom {
             std::mem::transmute(root(Context { props, scope }))
         });
 
+        let scheduler = Scheduler::new();
+
         let base_scope = scheduler.pool.insert_scope_with_key(|myidx| {
             Scope::new(
                 root_caller.as_ref(),
@@ -143,7 +146,7 @@ impl VirtualDom {
 
         Self {
             root_caller,
-            root_fc: Box::new(root),
+            root_fc,
             base_scope,
             scheduler,
             root_props,
@@ -253,6 +256,37 @@ impl VirtualDom {
     /// Compute a manual diff of the VirtualDOM between states.
     ///
     /// This can be useful when state inside the DOM is remotely changed from the outside, but not propogated as an event.
+    ///
+    /// In this case, every component will be diffed, even if their props are memoized. This method is intended to be used
+    /// to force an update of the DOM when the state of the app is changed outside of the app.
+    ///
+    ///
+    /// # Example
+    /// ```rust
+    /// #[derive(PartialEq, Props)]
+    /// struct AppProps {
+    ///     value: Shared<&'static str>,
+    /// }
+    ///
+    /// static App: FC<AppProps> = |cx| {
+    ///     let val = cx.value.borrow();
+    ///     cx.render(rsx! { div { "{val}" } })
+    /// };
+    ///
+    /// let value = Rc::new(RefCell::new("Hello"));
+    /// let mut dom = VirtualDom::new_with_props(
+    ///     App,
+    ///     AppProps {
+    ///         value: value.clone(),
+    ///     },
+    /// );
+    ///
+    /// let _ = dom.rebuild();
+    ///
+    /// *value.borrow_mut() = "goodbye";
+    ///
+    /// let edits = dom.diff();
+    /// ```
     pub fn diff<'s>(&'s mut self) -> Mutations<'s> {
         let cur_component = self
             .scheduler
@@ -263,6 +297,7 @@ impl VirtualDom {
         if cur_component.run_scope(&self.scheduler.pool) {
             let mut diff_machine: DiffMachine<'s> =
                 DiffMachine::new(Mutations::new(), &mut self.scheduler.pool);
+            diff_machine.cfg.force_diff = true;
             diff_machine.diff_scope(self.base_scope);
             diff_machine.mutations
         } else {

+ 3 - 3
packages/core/tests/lifecycle.rs

@@ -13,6 +13,8 @@ type Shared<T> = Rc<RefCell<T>>;
 
 #[test]
 fn manual_diffing() {
+    test_logging::set_up_logging(IS_LOGGING_ENABLED);
+
     #[derive(PartialEq, Props)]
     struct AppProps {
         value: Shared<&'static str>,
@@ -23,9 +25,7 @@ fn manual_diffing() {
         cx.render(rsx! { div { "{val}" } })
     };
 
-    test_logging::set_up_logging(IS_LOGGING_ENABLED);
-
-    let mut value = Rc::new(RefCell::new("Hello"));
+    let value = Rc::new(RefCell::new("Hello"));
     let mut dom = VirtualDom::new_with_props(
         App,
         AppProps {