fix any value dropping
This commit is contained in:
1 parent
51dba50c04
commit
c0f9355648
7 files changed
+43
-36
No files matched your search
@@ -160,8 +160,8 @@ impl VirtualDom {
|
|||||||
AttributeValue::Listener(l) => {
|
AttributeValue::Listener(l) => {
|
||||||
_ = l.take();
|
_ = l.take();
|
||||||
}
|
}
|
||||||
AttributeValue::Any(_) => {
|
AttributeValue::Any(a) => {
|
||||||
todo!()
|
_ = a.take();
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ pub use crate::innerlude::{
|
|||||||
/// This includes types like [`Scope`], [`Element`], and [`Component`].
|
/// This includes types like [`Scope`], [`Element`], and [`Component`].
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
fc_to_builder, Component, Element, Event, EventHandler, Fragment, IntoAttributeValue,
|
fc_to_builder, AnyValue, Component, Element, Event, EventHandler, Fragment,
|
||||||
LazyNodes, Properties, Scope, ScopeId, ScopeState, Scoped, TaskId, Template,
|
IntoAttributeValue, LazyNodes, Properties, Scope, ScopeId, ScopeState, Scoped, TaskId,
|
||||||
TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
|
Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,20 +48,7 @@ impl<'a> Mutations<'a> {
|
|||||||
|
|
||||||
/// Push a new mutation into the dom_edits list
|
/// Push a new mutation into the dom_edits list
|
||||||
pub(crate) fn push(&mut self, mutation: Mutation<'static>) {
|
pub(crate) fn push(&mut self, mutation: Mutation<'static>) {
|
||||||
self.edits.push(mutation.downcast_lifetime())
|
self.edits.push(mutation)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Mutations<'static> {
|
|
||||||
pub(crate) fn take<'a>(&mut self) -> Mutations<'a> {
|
|
||||||
Mutations::<'a> {
|
|
||||||
subtree: self.subtree,
|
|
||||||
dirty_scopes: self.dirty_scopes.drain().collect(),
|
|
||||||
templates: self.templates.split_off(0),
|
|
||||||
// Safety: this downcasts the lifetime from 'static to 'a
|
|
||||||
// This is safe because 'static outlives 'a
|
|
||||||
edits: unsafe { std::mem::transmute(self.edits.split_off(0)) },
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,9 +244,3 @@ pub enum Mutation<'a> {
|
|||||||
id: ElementId,
|
id: ElementId,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mutation<'static> {
|
|
||||||
pub(crate) fn downcast_lifetime<'a>(self) -> Mutation<'a> {
|
|
||||||
unsafe { std::mem::transmute(self) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@ use bumpalo::boxed::Box as BumpBox;
|
|||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
cell::{Cell, RefCell, UnsafeCell},
|
cell::{self, Cell, RefCell, UnsafeCell},
|
||||||
fmt::{Arguments, Debug},
|
fmt::{Arguments, Debug},
|
||||||
future::Future,
|
future::Future,
|
||||||
};
|
};
|
||||||
@@ -523,7 +523,7 @@ pub enum AttributeValue<'a> {
|
|||||||
Listener(RefCell<Option<ListenerCb<'a>>>),
|
Listener(RefCell<Option<ListenerCb<'a>>>),
|
||||||
|
|
||||||
/// An arbitrary value that implements PartialEq and is static
|
/// An arbitrary value that implements PartialEq and is static
|
||||||
Any(BumpBox<'a, dyn AnyValue>),
|
Any(RefCell<Option<BumpBox<'a, dyn AnyValue>>>),
|
||||||
|
|
||||||
/// A "none" value, resulting in the removal of an attribute from the dom
|
/// A "none" value, resulting in the removal of an attribute from the dom
|
||||||
None,
|
None,
|
||||||
@@ -557,7 +557,7 @@ pub enum BorrowedAttributeValue<'a> {
|
|||||||
serialize_with = "serialize_any_value"
|
serialize_with = "serialize_any_value"
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
Any(&'a dyn AnyValue),
|
Any(std::cell::Ref<'a, dyn AnyValue>),
|
||||||
|
|
||||||
/// A "none" value, resulting in the removal of an attribute from the dom
|
/// A "none" value, resulting in the removal of an attribute from the dom
|
||||||
None,
|
None,
|
||||||
@@ -573,7 +573,12 @@ impl<'a> From<&'a AttributeValue<'a>> for BorrowedAttributeValue<'a> {
|
|||||||
AttributeValue::Listener(_) => {
|
AttributeValue::Listener(_) => {
|
||||||
panic!("A listener cannot be turned into a borrowed value")
|
panic!("A listener cannot be turned into a borrowed value")
|
||||||
}
|
}
|
||||||
AttributeValue::Any(value) => BorrowedAttributeValue::Any(&**value),
|
AttributeValue::Any(value) => {
|
||||||
|
let value = value.borrow();
|
||||||
|
BorrowedAttributeValue::Any(std::cell::Ref::map(value, |value| {
|
||||||
|
&**value.as_ref().unwrap()
|
||||||
|
}))
|
||||||
|
}
|
||||||
AttributeValue::None => BorrowedAttributeValue::None,
|
AttributeValue::None => BorrowedAttributeValue::None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -606,7 +611,7 @@ impl PartialEq for BorrowedAttributeValue<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
fn serialize_any_value<S>(_: &&dyn AnyValue, _: S) -> Result<S::Ok, S::Error>
|
fn serialize_any_value<S>(_: &cell::Ref<'_, dyn AnyValue>, _: S) -> Result<S::Ok, S::Error>
|
||||||
where
|
where
|
||||||
S: serde::Serializer,
|
S: serde::Serializer,
|
||||||
{
|
{
|
||||||
@@ -614,7 +619,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serialize")]
|
#[cfg(feature = "serialize")]
|
||||||
fn deserialize_any_value<'de, 'a, D>(_: D) -> Result<&'a dyn AnyValue, D::Error>
|
fn deserialize_any_value<'de, 'a, D>(_: D) -> Result<cell::Ref<'a, dyn AnyValue>, D::Error>
|
||||||
where
|
where
|
||||||
D: serde::Deserializer<'de>,
|
D: serde::Deserializer<'de>,
|
||||||
{
|
{
|
||||||
@@ -643,7 +648,11 @@ impl<'a> PartialEq for AttributeValue<'a> {
|
|||||||
(Self::Int(l0), Self::Int(r0)) => l0 == r0,
|
(Self::Int(l0), Self::Int(r0)) => l0 == r0,
|
||||||
(Self::Bool(l0), Self::Bool(r0)) => l0 == r0,
|
(Self::Bool(l0), Self::Bool(r0)) => l0 == r0,
|
||||||
(Self::Listener(_), Self::Listener(_)) => true,
|
(Self::Listener(_), Self::Listener(_)) => true,
|
||||||
(Self::Any(l0), Self::Any(r0)) => l0.any_cmp(&**r0),
|
(Self::Any(l0), Self::Any(r0)) => {
|
||||||
|
let l0 = l0.borrow();
|
||||||
|
let r0 = r0.borrow();
|
||||||
|
l0.as_ref().unwrap().any_cmp(&**r0.as_ref().unwrap())
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -835,6 +844,12 @@ pub trait IntoAttributeValue<'a> {
|
|||||||
fn into_value(self, bump: &'a Bump) -> AttributeValue<'a>;
|
fn into_value(self, bump: &'a Bump) -> AttributeValue<'a>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> IntoAttributeValue<'a> for AttributeValue<'a> {
|
||||||
|
fn into_value(self, _: &'a Bump) -> AttributeValue<'a> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> IntoAttributeValue<'a> for &'a str {
|
impl<'a> IntoAttributeValue<'a> for &'a str {
|
||||||
fn into_value(self, _: &'a Bump) -> AttributeValue<'a> {
|
fn into_value(self, _: &'a Bump) -> AttributeValue<'a> {
|
||||||
AttributeValue::Text(self)
|
AttributeValue::Text(self)
|
||||||
@@ -870,6 +885,6 @@ impl<'a> IntoAttributeValue<'a> for Arguments<'_> {
|
|||||||
|
|
||||||
impl<'a> IntoAttributeValue<'a> for BumpBox<'a, dyn AnyValue> {
|
impl<'a> IntoAttributeValue<'a> for BumpBox<'a, dyn AnyValue> {
|
||||||
fn into_value(self, _: &'a Bump) -> AttributeValue<'a> {
|
fn into_value(self, _: &'a Bump) -> AttributeValue<'a> {
|
||||||
AttributeValue::Any(self)
|
AttributeValue::Any(RefCell::new(Some(self)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ use crate::{
|
|||||||
innerlude::{ErrorBoundary, Scheduler, SchedulerMsg},
|
innerlude::{ErrorBoundary, Scheduler, SchedulerMsg},
|
||||||
lazynodes::LazyNodes,
|
lazynodes::LazyNodes,
|
||||||
nodes::{ComponentReturn, IntoAttributeValue, IntoDynNode, RenderReturn},
|
nodes::{ComponentReturn, IntoAttributeValue, IntoDynNode, RenderReturn},
|
||||||
Attribute, AttributeValue, Element, Event, Properties, TaskId,
|
AnyValue, Attribute, AttributeValue, Element, Event, Properties, TaskId,
|
||||||
};
|
};
|
||||||
use bumpalo::{boxed::Box as BumpBox, Bump};
|
use bumpalo::{boxed::Box as BumpBox, Bump};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
@@ -513,6 +513,17 @@ impl<'src> ScopeState {
|
|||||||
AttributeValue::Listener(RefCell::new(Some(boxed)))
|
AttributeValue::Listener(RefCell::new(Some(boxed)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new [`AttributeValue`] with a value that implements [`AnyValue`]
|
||||||
|
pub fn any_value<T: AnyValue>(&'src self, value: T) -> AttributeValue<'src> {
|
||||||
|
// safety: there's no other way to create a dynamicly-dispatched bump box other than alloc + from-raw
|
||||||
|
// This is the suggested way to build a bumpbox
|
||||||
|
//
|
||||||
|
// In theory, we could just use regular boxes
|
||||||
|
let boxed: BumpBox<'src, dyn AnyValue> =
|
||||||
|
unsafe { BumpBox::from_raw(self.bump().alloc(value)) };
|
||||||
|
AttributeValue::Any(RefCell::new(Some(boxed)))
|
||||||
|
}
|
||||||
|
|
||||||
/// Inject an error into the nearest error boundary and quit rendering
|
/// Inject an error into the nearest error boundary and quit rendering
|
||||||
///
|
///
|
||||||
/// The error doesn't need to implement Error or any specific traits since the boundary
|
/// The error doesn't need to implement Error or any specific traits since the boundary
|
||||||
|
|||||||
@@ -641,7 +641,7 @@ impl VirtualDom {
|
|||||||
|
|
||||||
/// Swap the current mutations with a new
|
/// Swap the current mutations with a new
|
||||||
fn finalize(&mut self) -> Mutations {
|
fn finalize(&mut self) -> Mutations {
|
||||||
self.mutations.take()
|
std::mem::take(&mut self.mutations)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ impl<V: FromAnyValue> From<BorrowedAttributeValue<'_>> for OwnedAttributeValue<V
|
|||||||
BorrowedAttributeValue::Float(float) => Self::Float(float),
|
BorrowedAttributeValue::Float(float) => Self::Float(float),
|
||||||
BorrowedAttributeValue::Int(int) => Self::Int(int),
|
BorrowedAttributeValue::Int(int) => Self::Int(int),
|
||||||
BorrowedAttributeValue::Bool(bool) => Self::Bool(bool),
|
BorrowedAttributeValue::Bool(bool) => Self::Bool(bool),
|
||||||
BorrowedAttributeValue::Any(any) => Self::Custom(V::from_any_value(any)),
|
BorrowedAttributeValue::Any(any) => Self::Custom(V::from_any_value(&*any)),
|
||||||
BorrowedAttributeValue::None => Self::None,
|
BorrowedAttributeValue::None => Self::None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user