Evan Almloff пре 1 година
родитељ
комит
32b15fc851

+ 1 - 1
packages/core/src/any_props.rs

@@ -61,7 +61,7 @@ impl<P> VProps<P> {
     }
 }
 
-impl<P: Clone> AnyProps for VProps<P> {
+impl<P: Clone + 'static> AnyProps for VProps<P> {
     fn memoize(&self, other: &dyn Any) -> bool {
         match other.downcast_ref::<Self>() {
             Some(other) => (self.memo)(&self.props, &other.props),

+ 15 - 16
packages/core/src/arena.rs

@@ -61,22 +61,21 @@ impl VirtualDom {
     //
     // Note: This will not remove any ids from the arena
     pub(crate) fn drop_scope(&mut self, id: ScopeId, recursive: bool) {
-        self.dirty_scopes.remove(&DirtyScope {
-            height: self.scopes[id.0].height(),
-            id,
-        });
-
-        if recursive {
-            if let Some(root) = self.scopes[id.0].try_root_node() {
-                if let RenderReturn::Ready(node) = root {
-                    self.drop_scope_inner(node)
-                }
-            }
-        }
-
-        let scope = &mut self.scopes[id.0];
-
-        self.scopes.remove(id.0);
+        // todo: Do we need this now that we don't have a bunch of unsafe code?
+        // self.dirty_scopes.remove(&DirtyScope {
+        //     height: self.scopes[id.0].height(),
+        //     id,
+        // });
+
+        // if recursive {
+        //     if let Some(root) = self.scopes[id.0].try_root_node() {
+        //         if let RenderReturn::Ready(node) = root {
+        //             self.drop_scope_inner(node)
+        //         }
+        //     }
+        // }
+
+        // self.scopes.remove(id.0);
     }
 
     fn drop_scope_inner(&mut self, node: &VNode) {

+ 9 - 9
packages/core/src/create.rs

@@ -201,7 +201,7 @@ impl VirtualDom {
                     element: template.clone(),
                     scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
                 };
-                self.create_dynamic_node(template_ref, node, to)
+                self.create_dynamic_node(&template_ref, node, to)
             }
             Placeholder(VPlaceholder { id, parent }) => {
                 let template_ref = ElementRef {
@@ -299,7 +299,7 @@ impl VirtualDom {
                 element: template.clone(),
                 scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
             };
-            let m = self.create_dynamic_node(boundary_ref, &template.dynamic_nodes[idx], to);
+            let m = self.create_dynamic_node(&boundary_ref, &template.dynamic_nodes[idx], to);
             if m > 0 {
                 // The path is one shorter because the top node is the root
                 let path = &template.template.get().node_paths[idx][1..];
@@ -479,7 +479,7 @@ impl VirtualDom {
 
     pub(crate) fn create_dynamic_node(
         &mut self,
-        parent: ElementRef,
+        parent: &ElementRef,
         node: &DynamicNode,
         to: &mut impl WriteMutations,
     ) -> usize {
@@ -494,7 +494,7 @@ impl VirtualDom {
 
     fn create_dynamic_text(
         &mut self,
-        parent: ElementRef,
+        parent: &ElementRef,
         text: &VText,
         to: &mut impl WriteMutations,
     ) -> usize {
@@ -514,7 +514,7 @@ impl VirtualDom {
     pub(crate) fn create_placeholder(
         &mut self,
         placeholder: &VPlaceholder,
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) -> usize {
         // Allocate a dynamic element reference for this text node
@@ -524,7 +524,7 @@ impl VirtualDom {
         placeholder.id.set(Some(id));
 
         // Assign the placeholder's parent
-        *placeholder.parent.borrow_mut() = Some(parent);
+        *placeholder.parent.borrow_mut() = Some(parent.clone());
 
         // Assign the ID to the existing node in the template
         to.assign_node_id(&parent.path.path[1..], id);
@@ -535,7 +535,7 @@ impl VirtualDom {
 
     pub(super) fn create_component_node(
         &mut self,
-        parent: Option<ElementRef>,
+        parent: Option<&ElementRef>,
         component: &VComponent,
         to: &mut impl WriteMutations,
     ) -> usize {
@@ -576,13 +576,13 @@ impl VirtualDom {
     fn mount_aborted(
         &mut self,
         placeholder: &VPlaceholder,
-        parent: Option<ElementRef>,
+        parent: Option<&ElementRef>,
         to: &mut impl WriteMutations,
     ) -> usize {
         let id = self.next_element();
         to.create_placeholder(id);
         placeholder.id.set(Some(id));
-        *placeholder.parent.borrow_mut() = parent;
+        *placeholder.parent.borrow_mut() = parent.cloned();
 
         1
     }

+ 45 - 36
packages/core/src/diff.rs

@@ -26,8 +26,8 @@ impl VirtualDom {
         self.runtime.scope_stack.borrow_mut().push(scope);
         let scope_state = &mut self.scopes[scope.0];
         // Load the old and new bump arenas
-        let old = std::mem::replace(&mut scope_state.last_rendered_node, Some(new_nodes)).unwrap();
-        let new = scope_state.last_rendered_node.as_ref().unwrap();
+        let new = &new_nodes;
+        let old = scope_state.last_rendered_node.take().unwrap();
 
         use RenderReturn::{Aborted, Ready};
 
@@ -46,13 +46,20 @@ impl VirtualDom {
 
             // Placeholder becomes something
             // We should also clear the error now
-            (Aborted(l), Ready(r)) => self.replace_placeholder(
-                l,
-                [r],
-                l.parent.borrow().expect("root node should not be none"),
-                to,
-            ),
+            (Aborted(l), Ready(r)) => {
+                let parent = l.parent.take();
+                self.replace_placeholder(
+                    l,
+                    [r],
+                    parent.as_ref().expect("root node should not be none"),
+                    to,
+                )
+            }
         };
+
+        let scope_state = &mut self.scopes[scope.0];
+        scope_state.last_rendered_node = Some(new_nodes);
+
         self.runtime.scope_stack.borrow_mut().pop();
     }
 
@@ -84,6 +91,7 @@ impl VirtualDom {
                     right_template.template.set(template);
                     if template != left_template.template.get() {
                         let parent = left_template.parent.take();
+                        let parent = parent.as_ref();
                         return self.replace(left_template, [right_template], parent, to);
                     }
                 }
@@ -136,7 +144,7 @@ impl VirtualDom {
                     },
                     scope: self.runtime.scope_stack.borrow().last().copied().unwrap(),
                 };
-                self.diff_dynamic_node(left_node, right_node, current_ref, to);
+                self.diff_dynamic_node(left_node, right_node, &current_ref, to);
             });
 
         // Make sure the roots get transferred over while we're here
@@ -153,7 +161,7 @@ impl VirtualDom {
         &mut self,
         left_node: &DynamicNode,
         right_node: &DynamicNode,
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) {
         match (left_node, right_node) {
@@ -190,7 +198,7 @@ impl VirtualDom {
         &mut self,
         left: &VComponent,
         right: &VComponent,
-        parent: Option<ElementRef>,
+        parent: Option<&ElementRef>,
         to: &mut impl WriteMutations,
     ) {
         if std::ptr::eq(left, right) {
@@ -241,7 +249,7 @@ impl VirtualDom {
         &mut self,
         right: &VComponent,
         left: &VComponent,
-        parent: Option<ElementRef>,
+        parent: Option<&ElementRef>,
         to: &mut impl WriteMutations,
     ) {
         let m = self.create_component_node(parent, right, to);
@@ -291,6 +299,7 @@ impl VirtualDom {
     /// ```
     fn light_diff_templates(&mut self, left: &VNode, right: &VNode, to: &mut impl WriteMutations) {
         let parent = left.parent.take();
+        let parent = parent.as_ref();
         match matching_components(left, right) {
             None => self.replace(left, [right], parent, to),
             Some(components) => components
@@ -316,7 +325,7 @@ impl VirtualDom {
         &mut self,
         old: &[VNode],
         new: &[VNode],
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) {
         let new_is_keyed = new[0].key.is_some();
@@ -349,7 +358,7 @@ impl VirtualDom {
         &mut self,
         old: &[VNode],
         new: &[VNode],
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) {
         use std::cmp::Ordering;
@@ -391,7 +400,7 @@ impl VirtualDom {
         &mut self,
         old: &[VNode],
         new: &[VNode],
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) {
         if cfg!(debug_assertions) {
@@ -399,7 +408,7 @@ impl VirtualDom {
             let mut assert_unique_keys = |children: &[VNode]| {
                 keys.clear();
                 for child in children {
-                    let key = child.key;
+                    let key = child.key.clone();
                     debug_assert!(
                         key.is_some(),
                         "if any sibling is keyed, all siblings must be keyed"
@@ -471,7 +480,7 @@ impl VirtualDom {
         &mut self,
         old: &[VNode],
         new: &[VNode],
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) -> Option<(usize, usize)> {
         let mut left_offset = 0;
@@ -531,7 +540,7 @@ impl VirtualDom {
         &mut self,
         old: &[VNode],
         new: &[VNode],
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) {
         /*
@@ -557,8 +566,8 @@ impl VirtualDom {
         */
         // 0. Debug sanity checks
         // Should have already diffed the shared-key prefixes and suffixes.
-        debug_assert_ne!(new.first().map(|i| i.key), old.first().map(|i| i.key));
-        debug_assert_ne!(new.last().map(|i| i.key), old.last().map(|i| i.key));
+        debug_assert_ne!(new.first().map(|i| &i.key), old.first().map(|i| &i.key));
+        debug_assert_ne!(new.last().map(|i| &i.key), old.last().map(|i| &i.key));
 
         // 1. Map the old keys into a numerical ordering based on indices.
         // 2. Create a map of old key to its index
@@ -566,7 +575,7 @@ impl VirtualDom {
         let old_key_to_old_index = old
             .iter()
             .enumerate()
-            .map(|(i, o)| (o.key.unwrap(), i))
+            .map(|(i, o)| (o.key.as_ref().unwrap(), i))
             .collect::<FxHashMap<_, _>>();
 
         let mut shared_keys = FxHashSet::default();
@@ -575,7 +584,7 @@ impl VirtualDom {
         let new_index_to_old_index = new
             .iter()
             .map(|node| {
-                let key = node.key.unwrap();
+                let key = node.key.as_ref().unwrap();
                 if let Some(&index) = old_key_to_old_index.get(&key) {
                     shared_keys.insert(key);
                     index
@@ -604,7 +613,7 @@ impl VirtualDom {
         // remove any old children that are not shared
         // todo: make this an iterator
         for child in old {
-            let key = child.key.unwrap();
+            let key = child.key.as_ref().unwrap();
             if !shared_keys.contains(&key) {
                 self.remove_node(child, true, to);
             }
@@ -706,7 +715,7 @@ impl VirtualDom {
     }
 
     /// Push all the real nodes on the stack
-    fn push_all_real_nodes(&mut self, node: &VNode, to: &mut impl WriteMutations) -> usize {
+    fn push_all_real_nodes(&self, node: &VNode, to: &mut impl WriteMutations) -> usize {
         node.template
             .get()
             .roots
@@ -750,7 +759,7 @@ impl VirtualDom {
     pub(crate) fn create_children<'a>(
         &mut self,
         nodes: impl IntoIterator<Item = &'a VNode>,
-        parent: Option<ElementRef>,
+        parent: Option<&ElementRef>,
         to: &mut impl WriteMutations,
     ) -> usize {
         nodes
@@ -766,7 +775,7 @@ impl VirtualDom {
         &mut self,
         new: &[VNode],
         before: &VNode,
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) {
         let m = self.create_children(new, Some(parent), to);
@@ -778,7 +787,7 @@ impl VirtualDom {
         &mut self,
         new: &[VNode],
         after: &VNode,
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) {
         let m = self.create_children(new, Some(parent), to);
@@ -791,7 +800,7 @@ impl VirtualDom {
         &mut self,
         l: &VPlaceholder,
         r: impl IntoIterator<Item = &'a VNode>,
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) {
         let m = self.create_children(r, Some(parent), to);
@@ -804,7 +813,7 @@ impl VirtualDom {
         &mut self,
         left: &VNode,
         right: impl IntoIterator<Item = &'a VNode>,
-        parent: Option<ElementRef>,
+        parent: Option<&ElementRef>,
         to: &mut impl WriteMutations,
     ) {
         let m = self.create_children(right, parent, to);
@@ -819,14 +828,14 @@ impl VirtualDom {
         &mut self,
         l: &[VNode],
         r: &VPlaceholder,
-        parent: ElementRef,
+        parent: &ElementRef,
         to: &mut impl WriteMutations,
     ) {
         // Create the placeholder first, ensuring we get a dedicated ID for the placeholder
         let placeholder = self.next_element();
 
         r.id.set(Some(placeholder));
-        r.parent.borrow_mut().replace(parent);
+        r.parent.borrow_mut().replace(parent.clone());
 
         to.create_placeholder(placeholder);
 
@@ -984,10 +993,10 @@ impl VirtualDom {
             .expect("VComponents to always have a scope");
 
         // Remove the component from the dom
-        match self.get_scope(scope).unwrap().root_node() {
-            RenderReturn::Ready(t) => self.remove_node(t, gen_muts, to),
+        match self.scopes[scope.0].last_rendered_node.take().unwrap() {
+            RenderReturn::Ready(t) => self.remove_node(&t, gen_muts, to),
             RenderReturn::Aborted(placeholder) => {
-                self.remove_placeholder(placeholder, gen_muts, to)
+                self.remove_placeholder(&placeholder, gen_muts, to)
             }
         };
 
@@ -1027,10 +1036,10 @@ impl VirtualDom {
         }
     }
 
-    pub(crate) fn assign_boundary_ref(&mut self, parent: Option<ElementRef>, child: &VNode) {
+    pub(crate) fn assign_boundary_ref(&mut self, parent: Option<&ElementRef>, child: &VNode) {
         if let Some(parent) = parent {
             // assign the parent of the child
-            child.parent.borrow_mut().replace(parent);
+            child.parent.borrow_mut().replace(parent.clone());
         }
     }
 }

+ 1 - 1
packages/core/src/error_boundary.rs

@@ -264,7 +264,7 @@ impl<T> Throw for Option<T> {
 
 #[derive(Clone)]
 pub struct ErrorHandler(Rc<dyn Fn(CapturedError) -> Element>);
-impl<F: Fn(CapturedError) -> Element> From<F> for ErrorHandler {
+impl<F: Fn(CapturedError) -> Element + 'static> From<F> for ErrorHandler {
     fn from(value: F) -> Self {
         Self(Rc::new(value))
     }

+ 24 - 22
packages/core/src/mutations.rs

@@ -128,13 +128,13 @@ pub trait WriteMutations {
     /// Push the given root node onto our stack.
     ///
     /// Id: The ID of the root node to push.
-    fn push_root(&mut self, id: ElementId) {}
+    fn push_root(&mut self, _id: ElementId);
 
     /// Swap to a new subtree
-    fn swap_subtree(&mut self, subtree_index: usize) {}
+    fn swap_subtree(&mut self, _subtree_index: usize) {}
 
     /// Mark a scope as dirty
-    fn mark_scope_dirty(&mut self, scope_id: ScopeId) {}
+    fn mark_scope_dirty(&mut self, _scope_id: ScopeId) {}
 }
 
 /// A `Mutation` represents a single instruction for the renderer to use to modify the UI tree to match the state
@@ -468,42 +468,44 @@ impl WriteMutations for MutationsVec {
 pub struct NoOpMutations;
 
 impl WriteMutations for NoOpMutations {
-    fn register_template(&mut self, template: Template) {}
+    fn register_template(&mut self, _: Template) {}
 
-    fn append_children(&mut self, id: ElementId, m: usize) {}
+    fn append_children(&mut self, _: ElementId, _: usize) {}
 
-    fn assign_node_id(&mut self, path: &'static [u8], id: ElementId) {}
+    fn assign_node_id(&mut self, _: &'static [u8], _: ElementId) {}
 
-    fn create_placeholder(&mut self, id: ElementId) {}
+    fn create_placeholder(&mut self, _: ElementId) {}
 
-    fn create_text_node(&mut self, value: &str, id: ElementId) {}
+    fn create_text_node(&mut self, _: &str, _: ElementId) {}
 
-    fn hydrate_text_node(&mut self, path: &'static [u8], value: &str, id: ElementId) {}
+    fn hydrate_text_node(&mut self, _: &'static [u8], _: &str, _: ElementId) {}
 
-    fn load_template(&mut self, name: &'static str, index: usize, id: ElementId) {}
+    fn load_template(&mut self, _: &'static str, _: usize, _: ElementId) {}
 
-    fn replace_node_with(&mut self, id: ElementId, m: usize) {}
+    fn replace_node_with(&mut self, _: ElementId, _: usize) {}
 
-    fn replace_placeholder_with_nodes(&mut self, path: &'static [u8], m: usize) {}
+    fn replace_placeholder_with_nodes(&mut self, _: &'static [u8], _: usize) {}
 
-    fn insert_nodes_after(&mut self, id: ElementId, m: usize) {}
+    fn insert_nodes_after(&mut self, _: ElementId, _: usize) {}
 
-    fn insert_nodes_before(&mut self, id: ElementId, m: usize) {}
+    fn insert_nodes_before(&mut self, _: ElementId, _: usize) {}
 
     fn set_attribute(
         &mut self,
-        name: &'static str,
-        ns: Option<&'static str>,
-        value: &AttributeValue,
-        id: ElementId,
+        _: &'static str,
+        _: Option<&'static str>,
+        _: &AttributeValue,
+        _: ElementId,
     ) {
     }
 
-    fn set_node_text(&mut self, value: &str, id: ElementId) {}
+    fn set_node_text(&mut self, _: &str, _: ElementId) {}
+
+    fn create_event_listener(&mut self, _: &'static str, _: ElementId) {}
 
-    fn create_event_listener(&mut self, name: &'static str, id: ElementId) {}
+    fn remove_event_listener(&mut self, _: &'static str, _: ElementId) {}
 
-    fn remove_event_listener(&mut self, name: &'static str, id: ElementId) {}
+    fn remove_node(&mut self, _: ElementId) {}
 
-    fn remove_node(&mut self, id: ElementId) {}
+    fn push_root(&mut self, _: ElementId) {}
 }

+ 1 - 1
packages/core/src/nodes.rs

@@ -690,7 +690,7 @@ where
     I: IntoVNode,
 {
     fn into_dyn_node(self) -> DynamicNode {
-        let mut children: Vec<_> = self.into_iter().map(|node| node.into_vnode()).collect();
+        let children: Vec<_> = self.into_iter().map(|node| node.into_vnode()).collect();
 
         if children.is_empty() {
             DynamicNode::default()

+ 3 - 3
packages/core/src/scope_context.rs

@@ -270,7 +270,7 @@ impl ScopeContext {
     /// }
     /// ```
     #[allow(clippy::mut_from_ref)]
-    pub fn use_hook<State: 'static>(&self, initializer: impl FnOnce() -> State) -> &mut State {
+    pub fn use_hook<State: Clone + 'static>(&self, initializer: impl FnOnce() -> State) -> State {
         let cur_hook = self.hook_index.get();
         let mut hooks = self.hooks.try_borrow_mut().expect("The hook list is already borrowed: This error is likely caused by trying to use a hook inside a hook which violates the rules of hooks.");
 
@@ -282,8 +282,8 @@ impl ScopeContext {
             .get(cur_hook)
             .and_then(|inn| {
                 self.hook_index.set(cur_hook + 1);
-                let raw_ref: &mut dyn Any = inn.as_mut();
-                raw_ref.downcast_mut::<State>()
+                let raw_ref: & dyn Any = inn.as_ref();
+                raw_ref.downcast_ref    ::<State>().cloned()
             })
             .expect(
                 r#"

+ 1 - 1
packages/core/src/scopes.rs

@@ -310,7 +310,7 @@ impl<'src> ScopeState {
     }
 
     /// Create a new [`EventHandler`] from an [`FnMut`]
-    pub fn event_handler<T>(&self, f: impl FnMut(T) + 'static) -> EventHandler<T> {
+    pub fn event_handler<T>(&self, mut f: impl FnMut(T) + 'static) -> EventHandler<T> {
         let callback = RefCell::new(Some(Box::new(move |event: T| {
             f(event);
         }) as Box<dyn FnMut(T)>));