1
0
Эх сурвалжийг харах

drop any values correctly

= 2 жил өмнө
parent
commit
1555500fbd

+ 9 - 3
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();
+                }
+                _ => (),
             }
         });
     }

+ 3 - 3
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<Option<AnyValueContainer>>),
 
     /// 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<dyn AnyValue>);
 
 #[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)))
     }
 }

+ 1 - 1
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(),
         }))
     }
 

+ 9 - 5
packages/core/src/scopes.rs

@@ -88,7 +88,7 @@ pub struct ScopeState {
     pub(crate) spawned_tasks: FxHashSet<TaskId>,
 
     pub(crate) borrowed_props: RefCell<Vec<*const VComponent<'static>>>,
-    pub(crate) listeners: RefCell<Vec<*const Attribute<'static>>>,
+    pub(crate) attributes_to_drop: RefCell<Vec<*const Attribute<'static>>>,
 
     pub(crate) props: Option<Box<dyn AnyProps<'static>>>,
     pub(crate) placeholder: Cell<Option<ElementId>>,
@@ -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);
+                }
+
+                _ => (),
             }
         }
 

+ 1 - 1
packages/native-core/src/node.rs

@@ -103,7 +103,7 @@ impl From<AttributeValue<'_>> 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,
         }