clear borrowed props after ensure_drop_safety
This commit is contained in:
1 parent
02456c1068
commit
992ac4a3fb
4 files changed
+20
-13
No files matched your search
@@ -2,6 +2,7 @@ use crate::{
|
|||||||
innerlude::DirtyScope, nodes::RenderReturn, nodes::VNode, virtual_dom::VirtualDom,
|
innerlude::DirtyScope, nodes::RenderReturn, nodes::VNode, virtual_dom::VirtualDom,
|
||||||
AttributeValue, DynamicNode, ScopeId,
|
AttributeValue, DynamicNode, ScopeId,
|
||||||
};
|
};
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
/// An Element's unique identifier.
|
/// An Element's unique identifier.
|
||||||
///
|
///
|
||||||
@@ -13,8 +14,8 @@ pub struct ElementId(pub usize);
|
|||||||
|
|
||||||
/// An Element that can be bubbled to's unique identifier.
|
/// An Element that can be bubbled to's unique identifier.
|
||||||
///
|
///
|
||||||
/// `ElementId` is a `usize` that is unique across the entire VirtualDOM - but not unique across time. If a component is
|
/// `BubbleId` is a `usize` that is unique across the entire VirtualDOM - but not unique across time. If a component is
|
||||||
/// unmounted, then the `ElementId` will be reused for a new component.
|
/// unmounted, then the `BubbleId` will be reused for a new component.
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct BubbleId(pub usize);
|
pub struct BubbleId(pub usize);
|
||||||
@@ -25,7 +26,7 @@ pub struct ElementRef<'a> {
|
|||||||
pub(crate) path: ElementPath,
|
pub(crate) path: ElementPath,
|
||||||
|
|
||||||
// The actual template
|
// The actual template
|
||||||
pub(crate) template: Option<*const VNode<'a>>,
|
pub(crate) template: Option<NonNull<VNode<'a>>>,
|
||||||
|
|
||||||
// The scope the element belongs to
|
// The scope the element belongs to
|
||||||
pub(crate) scope: ScopeId,
|
pub(crate) scope: ScopeId,
|
||||||
@@ -182,9 +183,11 @@ impl VirtualDom {
|
|||||||
*props = None;
|
*props = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let scope = &self.scopes[scope_id.0];
|
||||||
|
scope.borrowed_props.borrow_mut().clear();
|
||||||
|
|
||||||
// Now that all the references are gone, we can safely drop our own references in our listeners.
|
// Now that all the references are gone, we can safely drop our own references in our listeners.
|
||||||
let mut listeners = self.scopes[scope_id.0].attributes_to_drop.borrow_mut();
|
let mut listeners = scope.attributes_to_drop.borrow_mut();
|
||||||
listeners.drain(..).for_each(|listener| {
|
listeners.drain(..).for_each(|listener| {
|
||||||
let listener = unsafe { &*listener };
|
let listener = unsafe { &*listener };
|
||||||
match &listener.value {
|
match &listener.value {
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ impl<'b> VirtualDom {
|
|||||||
path: ElementPath {
|
path: ElementPath {
|
||||||
path: &template.template.get().node_paths[idx],
|
path: &template.template.get().node_paths[idx],
|
||||||
},
|
},
|
||||||
template: Some(template),
|
template: Some(template.into()),
|
||||||
scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
|
scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
|
||||||
};
|
};
|
||||||
self.create_dynamic_node(template_ref, node)
|
self.create_dynamic_node(template_ref, node)
|
||||||
@@ -197,7 +197,7 @@ impl<'b> VirtualDom {
|
|||||||
path: ElementPath {
|
path: ElementPath {
|
||||||
path: &template.template.get().node_paths[idx],
|
path: &template.template.get().node_paths[idx],
|
||||||
},
|
},
|
||||||
template: Some(template),
|
template: Some(template.into()),
|
||||||
scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
|
scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
|
||||||
};
|
};
|
||||||
parent.set(Some(self.next_element_ref(template_ref)));
|
parent.set(Some(self.next_element_ref(template_ref)));
|
||||||
@@ -286,7 +286,7 @@ impl<'b> VirtualDom {
|
|||||||
path: ElementPath {
|
path: ElementPath {
|
||||||
path: &template.template.get().node_paths[idx],
|
path: &template.template.get().node_paths[idx],
|
||||||
},
|
},
|
||||||
template: Some(template),
|
template: Some(template.into()),
|
||||||
scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
|
scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
|
||||||
};
|
};
|
||||||
let m = self.create_dynamic_node(boundary_ref, &template.dynamic_nodes[idx]);
|
let m = self.create_dynamic_node(boundary_ref, &template.dynamic_nodes[idx]);
|
||||||
@@ -340,7 +340,7 @@ impl<'b> VirtualDom {
|
|||||||
let path = &template.template.get().attr_paths[idx];
|
let path = &template.template.get().attr_paths[idx];
|
||||||
let element_ref = ElementRef {
|
let element_ref = ElementRef {
|
||||||
path: ElementPath { path },
|
path: ElementPath { path },
|
||||||
template: Some(template),
|
template: Some(template.into()),
|
||||||
scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
|
scope: self.runtime.current_scope_id().unwrap_or(ScopeId(0)),
|
||||||
};
|
};
|
||||||
self.set_template(id, element_ref);
|
self.set_template(id, element_ref);
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ impl<'b> VirtualDom {
|
|||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each(|(dyn_node_idx, (left_node, right_node))| {
|
.for_each(|(dyn_node_idx, (left_node, right_node))| {
|
||||||
let current_ref = ElementRef {
|
let current_ref = ElementRef {
|
||||||
template: Some(right_template),
|
template: Some(right_template.into()),
|
||||||
path: ElementPath {
|
path: ElementPath {
|
||||||
path: left_template.template.get().node_paths[dyn_node_idx],
|
path: left_template.template.get().node_paths[dyn_node_idx],
|
||||||
},
|
},
|
||||||
@@ -176,7 +176,7 @@ impl<'b> VirtualDom {
|
|||||||
right.id.set(left.id.get());
|
right.id.set(left.id.get());
|
||||||
right.parent.set(left.parent.get());
|
right.parent.set(left.parent.get());
|
||||||
// Update the template
|
// Update the template
|
||||||
self.update_template(left.id.get().unwrap(), parent.template.unwrap());
|
self.update_template(left.id.get().unwrap(), parent.template.unwrap().as_ptr());
|
||||||
},
|
},
|
||||||
(Component(left), Component(right)) => self.diff_vcomponent(left, right, Some(parent)),
|
(Component(left), Component(right)) => self.diff_vcomponent(left, right, Some(parent)),
|
||||||
(Placeholder(left), Fragment(right)) => self.replace_placeholder(left, *right, parent),
|
(Placeholder(left), Fragment(right)) => self.replace_placeholder(left, *right, parent),
|
||||||
|
|||||||
@@ -371,8 +371,12 @@ impl VirtualDom {
|
|||||||
// Loop through each dynamic attribute (in a depth first order) in this template before moving up to the template's parent.
|
// Loop through each dynamic attribute (in a depth first order) in this template before moving up to the template's parent.
|
||||||
while let Some(el_ref) = parent_path {
|
while let Some(el_ref) = parent_path {
|
||||||
// safety: we maintain references of all vnodes in the element slab
|
// safety: we maintain references of all vnodes in the element slab
|
||||||
let template =
|
let template = unsafe {
|
||||||
unsafe { &*el_ref.template.expect("template reference should be valid") };
|
el_ref
|
||||||
|
.template
|
||||||
|
.expect("template reference should be valid")
|
||||||
|
.as_ref()
|
||||||
|
};
|
||||||
let node_template = template.template.get();
|
let node_template = template.template.get();
|
||||||
let target_path = el_ref.path;
|
let target_path = el_ref.path;
|
||||||
|
|
||||||
@@ -422,7 +426,7 @@ impl VirtualDom {
|
|||||||
// Otherwise, we just call the listener on the target element
|
// Otherwise, we just call the listener on the target element
|
||||||
if let Some(el_ref) = parent_path {
|
if let Some(el_ref) = parent_path {
|
||||||
// safety: we maintain references of all vnodes in the element slab
|
// safety: we maintain references of all vnodes in the element slab
|
||||||
let template = unsafe { &*el_ref.template.unwrap() };
|
let template = unsafe { el_ref.template.unwrap().as_ref() };
|
||||||
let node_template = template.template.get();
|
let node_template = template.template.get();
|
||||||
let target_path = el_ref.path;
|
let target_path = el_ref.path;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user