From 1555500fbd0f8022aa8025b22df3d4b974a1712b Mon Sep 17 00:00:00 2001 From: = Date: Mon, 26 Dec 2022 10:53:25 -0600 Subject: [PATCH] drop any values correctly --- packages/core/src/arena.rs | 12 +++++++++--- packages/core/src/nodes.rs | 6 +++--- packages/core/src/scope_arena.rs | 2 +- packages/core/src/scopes.rs | 14 +++++++++----- packages/native-core/src/node.rs | 2 +- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/packages/core/src/arena.rs b/packages/core/src/arena.rs index 4cb5d3964..a7d030162 100644 --- a/packages/core/src/arena.rs +++ b/packages/core/src/arena.rs @@ -155,11 +155,17 @@ impl VirtualDom { }); // Now that all the references are gone, we can safely drop our own references in our listeners. - let mut listeners = scope.listeners.borrow_mut(); + let mut listeners = scope.attributes_to_drop.borrow_mut(); listeners.drain(..).for_each(|listener| { let listener = unsafe { &*listener }; - if let AttributeValue::Listener(l) = &listener.value { - _ = l.0.take(); + match &listener.value { + AttributeValue::Listener(l) => { + _ = l.0.take(); + } + AttributeValue::Any(a) => { + _ = a.take(); + } + _ => (), } }); } diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index 7432057fe..c0ac4efd4 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -357,7 +357,7 @@ pub enum AttributeValue<'a> { Listener(ListenerCb<'a>), /// An arbitrary value that implements PartialEq and is static - Any(AnyValueContainer), + Any(RefCell>), /// A "none" value, resulting in the removal of an attribute from the dom None, @@ -392,9 +392,9 @@ impl<'de, 'a> serde::Deserialize<'de> for ListenerCb<'a> { } } -/// A boxed value that implements PartialEq and Any #[derive(Clone)] #[cfg(not(feature = "sync_attributes"))] +/// A boxed value that implements PartialEq, and Any pub struct AnyValueContainer(pub std::rc::Rc); #[derive(Clone)] @@ -732,6 +732,6 @@ impl<'a> IntoAttributeValue<'a> for Arguments<'_> { impl<'a> IntoAttributeValue<'a> for AnyValueContainer { fn into_value(self, _: &'a Bump) -> AttributeValue<'a> { - AttributeValue::Any(self) + AttributeValue::Any(RefCell::new(Some(self))) } } diff --git a/packages/core/src/scope_arena.rs b/packages/core/src/scope_arena.rs index 9c0f96db3..6dd5316d3 100644 --- a/packages/core/src/scope_arena.rs +++ b/packages/core/src/scope_arena.rs @@ -45,7 +45,7 @@ impl VirtualDom { hook_idx: Default::default(), shared_contexts: Default::default(), borrowed_props: Default::default(), - listeners: Default::default(), + attributes_to_drop: Default::default(), })) } diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs index 83428fd7d..7520df942 100644 --- a/packages/core/src/scopes.rs +++ b/packages/core/src/scopes.rs @@ -88,7 +88,7 @@ pub struct ScopeState { pub(crate) spawned_tasks: FxHashSet, pub(crate) borrowed_props: RefCell>>, - pub(crate) listeners: RefCell>>, + pub(crate) attributes_to_drop: RefCell>>, pub(crate) props: Option>>, pub(crate) placeholder: Cell>, @@ -374,11 +374,15 @@ impl<'src> ScopeState { pub fn render(&'src self, rsx: LazyNodes<'src, '_>) -> Element<'src> { let element = rsx.call(self); - let mut listeners = self.listeners.borrow_mut(); + let mut listeners = self.attributes_to_drop.borrow_mut(); for attr in element.dynamic_attrs { - if let AttributeValue::Listener(_) = attr.value { - let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) }; - listeners.push(unbounded); + match attr.value { + AttributeValue::Any(_) | AttributeValue::Listener(_) => { + let unbounded = unsafe { std::mem::transmute(attr as *const Attribute) }; + listeners.push(unbounded); + } + + _ => (), } } diff --git a/packages/native-core/src/node.rs b/packages/native-core/src/node.rs index c471dba11..99777dc27 100644 --- a/packages/native-core/src/node.rs +++ b/packages/native-core/src/node.rs @@ -103,7 +103,7 @@ impl From> for OwnedAttributeValue { AttributeValue::Float(float) => Self::Float(float), AttributeValue::Int(int) => Self::Int(int), AttributeValue::Bool(bool) => Self::Bool(bool), - AttributeValue::Any(any) => Self::Any(any), + AttributeValue::Any(any) => Self::Any(any.borrow().as_ref().unwrap().clone()), AttributeValue::None => Self::None, _ => Self::None, }