diff --git a/packages/core/src/any_props.rs b/packages/core/src/any_props.rs index 52a235972..274cd9c4a 100644 --- a/packages/core/src/any_props.rs +++ b/packages/core/src/any_props.rs @@ -61,7 +61,7 @@ impl

VProps

{ } } -impl AnyProps for VProps

{ +impl AnyProps for VProps

{ fn memoize(&self, other: &dyn Any) -> bool { match other.downcast_ref::() { Some(other) => (self.memo)(&self.props, &other.props), diff --git a/packages/core/src/arena.rs b/packages/core/src/arena.rs index 3aa82712f..712bc0b3d 100644 --- a/packages/core/src/arena.rs +++ b/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, - }); + // 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) - } - } - } + // 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); + // self.scopes.remove(id.0); } fn drop_scope_inner(&mut self, node: &VNode) { diff --git a/packages/core/src/create.rs b/packages/core/src/create.rs index 06cb07603..0c347d56d 100644 --- a/packages/core/src/create.rs +++ b/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, + 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, + 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 } diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index 61cb8e178..18c67ded7 100644 --- a/packages/core/src/diff.rs +++ b/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, ¤t_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, + 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, + 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::>(); 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, - parent: Option, + 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, - 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, - parent: Option, + 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, 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()); } } } diff --git a/packages/core/src/error_boundary.rs b/packages/core/src/error_boundary.rs index 44c42606c..e2b81338b 100644 --- a/packages/core/src/error_boundary.rs +++ b/packages/core/src/error_boundary.rs @@ -264,7 +264,7 @@ impl Throw for Option { #[derive(Clone)] pub struct ErrorHandler(Rc Element>); -impl Element> From for ErrorHandler { +impl Element + 'static> From for ErrorHandler { fn from(value: F) -> Self { Self(Rc::new(value)) } diff --git a/packages/core/src/mutations.rs b/packages/core/src/mutations.rs index 0493194f2..3d2ba049c 100644 --- a/packages/core/src/mutations.rs +++ b/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, name: &'static str, id: ElementId) {} + fn create_event_listener(&mut self, _: &'static str, _: ElementId) {} - fn remove_event_listener(&mut self, name: &'static str, id: ElementId) {} + fn remove_event_listener(&mut self, _: &'static str, _: ElementId) {} - fn remove_node(&mut self, id: ElementId) {} + fn remove_node(&mut self, _: ElementId) {} + + fn push_root(&mut self, _: ElementId) {} } diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index ae310ab54..774fe5856 100644 --- a/packages/core/src/nodes.rs +++ b/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() diff --git a/packages/core/src/scope_context.rs b/packages/core/src/scope_context.rs index d1cece18c..f6da0189e 100644 --- a/packages/core/src/scope_context.rs +++ b/packages/core/src/scope_context.rs @@ -270,7 +270,7 @@ impl ScopeContext { /// } /// ``` #[allow(clippy::mut_from_ref)] - pub fn use_hook(&self, initializer: impl FnOnce() -> State) -> &mut State { + pub fn use_hook(&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::() + let raw_ref: & dyn Any = inn.as_ref(); + raw_ref.downcast_ref ::().cloned() }) .expect( r#" diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs index 3aba1f912..958aa8ee1 100644 --- a/packages/core/src/scopes.rs +++ b/packages/core/src/scopes.rs @@ -310,7 +310,7 @@ impl<'src> ScopeState { } /// Create a new [`EventHandler`] from an [`FnMut`] - pub fn event_handler(&self, f: impl FnMut(T) + 'static) -> EventHandler { + pub fn event_handler(&self, mut f: impl FnMut(T) + 'static) -> EventHandler { let callback = RefCell::new(Some(Box::new(move |event: T| { f(event); }) as Box));