mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-30 08:00:21 +00:00
fix dropping nested scopes
This commit is contained in:
parent
7f4e45de49
commit
8548b324f1
4 changed files with 15 additions and 39 deletions
|
@ -88,7 +88,9 @@ impl VirtualDom {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop a scope and all its children
|
// Drop a scope and all its children
|
||||||
pub(crate) fn drop_scope(&mut self, id: ScopeId) {
|
//
|
||||||
|
// 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 {
|
self.dirty_scopes.remove(&DirtyScope {
|
||||||
height: self.scopes[id.0].height,
|
height: self.scopes[id.0].height,
|
||||||
id,
|
id,
|
||||||
|
@ -96,18 +98,13 @@ impl VirtualDom {
|
||||||
|
|
||||||
self.ensure_drop_safety(id);
|
self.ensure_drop_safety(id);
|
||||||
|
|
||||||
if let Some(root) = self.scopes[id.0].as_ref().try_root_node() {
|
if recursive {
|
||||||
if let RenderReturn::Ready(node) = unsafe { root.extend_lifetime_ref() } {
|
if let Some(root) = self.scopes[id.0].as_ref().try_root_node() {
|
||||||
self.drop_scope_inner(node)
|
if let RenderReturn::Ready(node) = unsafe { root.extend_lifetime_ref() } {
|
||||||
|
self.drop_scope_inner(node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(root) = unsafe { self.scopes[id.0].as_ref().previous_frame().try_load_node() } {
|
|
||||||
if let RenderReturn::Ready(node) = unsafe { root.extend_lifetime_ref() } {
|
|
||||||
self.drop_scope_inner(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.scopes[id.0].props.take();
|
|
||||||
|
|
||||||
let scope = &mut self.scopes[id.0];
|
let scope = &mut self.scopes[id.0];
|
||||||
|
|
||||||
|
@ -121,37 +118,24 @@ impl VirtualDom {
|
||||||
for task_id in scope.spawned_tasks.borrow_mut().drain() {
|
for task_id in scope.spawned_tasks.borrow_mut().drain() {
|
||||||
scope.tasks.remove(task_id);
|
scope.tasks.remove(task_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.scopes.remove(id.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drop_scope_inner(&mut self, node: &VNode) {
|
fn drop_scope_inner(&mut self, node: &VNode) {
|
||||||
node.clear_listeners();
|
|
||||||
node.dynamic_nodes.iter().for_each(|node| match node {
|
node.dynamic_nodes.iter().for_each(|node| match node {
|
||||||
DynamicNode::Component(c) => {
|
DynamicNode::Component(c) => {
|
||||||
if let Some(f) = c.scope.get() {
|
if let Some(f) = c.scope.get() {
|
||||||
self.drop_scope(f);
|
self.drop_scope(f, true);
|
||||||
}
|
}
|
||||||
c.props.take();
|
c.props.take();
|
||||||
}
|
}
|
||||||
DynamicNode::Fragment(nodes) => {
|
DynamicNode::Fragment(nodes) => {
|
||||||
nodes.iter().for_each(|node| self.drop_scope_inner(node))
|
nodes.iter().for_each(|node| self.drop_scope_inner(node))
|
||||||
}
|
}
|
||||||
DynamicNode::Placeholder(t) => {
|
DynamicNode::Placeholder(_) => {}
|
||||||
if let Some(id) = t.id.get() {
|
DynamicNode::Text(_) => {}
|
||||||
self.try_reclaim(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DynamicNode::Text(t) => {
|
|
||||||
if let Some(id) = t.id.get() {
|
|
||||||
self.try_reclaim(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
for id in &node.root_ids {
|
|
||||||
if id.0 != 0 {
|
|
||||||
self.try_reclaim(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Descend through the tree, removing any borrowed props and listeners
|
/// Descend through the tree, removing any borrowed props and listeners
|
||||||
|
|
|
@ -934,7 +934,7 @@ impl<'b> VirtualDom {
|
||||||
*comp.props.borrow_mut() = unsafe { std::mem::transmute(props) };
|
*comp.props.borrow_mut() = unsafe { std::mem::transmute(props) };
|
||||||
|
|
||||||
// Now drop all the resouces
|
// Now drop all the resouces
|
||||||
self.drop_scope(scope);
|
self.drop_scope(scope, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_first_element(&self, node: &'b VNode<'b>) -> ElementId {
|
fn find_first_element(&self, node: &'b VNode<'b>) -> ElementId {
|
||||||
|
|
|
@ -195,14 +195,6 @@ impl<'a> VNode<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clear_listeners(&self) {
|
|
||||||
for attr in self.dynamic_attrs {
|
|
||||||
if let AttributeValue::Listener(l) = &attr.value {
|
|
||||||
l.borrow_mut().take();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A static layout of a UI tree that describes a set of dynamic and static nodes.
|
/// A static layout of a UI tree that describes a set of dynamic and static nodes.
|
||||||
|
|
|
@ -682,6 +682,6 @@ impl VirtualDom {
|
||||||
impl Drop for VirtualDom {
|
impl Drop for VirtualDom {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// Simply drop this scope which drops all of its children
|
// Simply drop this scope which drops all of its children
|
||||||
self.drop_scope(ScopeId(0));
|
self.drop_scope(ScopeId(0), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue