drop any values correctly
This commit is contained in:
1 parent
c245f04c8c
commit
1555500fbd
5 files changed
+23
-13
No files matched your search
@@ -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();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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)))
|
||||
}
|
||||
}
|
||||
@@ -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(),
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user