use BumpBox<Any> and FromAnyValue instead of sync bounds

This commit is contained in:
Evan Almloff committed 2023-01-02 14:40:25 -06:00
1 parent 64db1def9f
commit 51dba50c04
20 files changed
+184 -200

No files matched your search

+39 -25
View File
@@ -1,44 +1,44 @@
use crate::{state::State, tree::NodeId};
use dioxus_core::{AnyValueContainer, AttributeValue, ElementId};
use dioxus_core::{AnyValue, BorrowedAttributeValue, ElementId};
use rustc_hash::{FxHashMap, FxHashSet};
use std::fmt::Debug;
/// The node is stored client side and stores only basic data about the node.
#[derive(Debug, Clone)]
pub struct Node<S: State> {
pub struct Node<S: State, V: FromAnyValue = ()> {
/// The transformed state of the node.
pub state: S,
/// The raw data for the node
pub node_data: NodeData,
pub node_data: NodeData<V>,
}
#[derive(Debug, Clone)]
pub struct NodeData {
pub struct NodeData<V: FromAnyValue = ()> {
/// The id of the node
pub node_id: NodeId,
/// The id of the node in the vdom.
pub element_id: Option<ElementId>,
/// Additional inforation specific to the node type
pub node_type: NodeType,
pub node_type: NodeType<V>,
}
/// A type of node with data specific to the node type. The types are a subset of the [VNode] types.
#[derive(Debug, Clone)]
pub enum NodeType {
pub enum NodeType<V: FromAnyValue = ()> {
Text {
text: String,
},
Element {
tag: String,
namespace: Option<String>,
attributes: FxHashMap<OwnedAttributeDiscription, OwnedAttributeValue>,
attributes: FxHashMap<OwnedAttributeDiscription, OwnedAttributeValue<V>>,
listeners: FxHashSet<String>,
},
Placeholder,
}
impl<S: State> Node<S> {
pub(crate) fn new(node_type: NodeType) -> Self {
impl<S: State, V: FromAnyValue> Node<S, V> {
pub(crate) fn new(node_type: NodeType<V>) -> Self {
Node {
state: S::default(),
node_data: NodeData {
@@ -65,52 +65,59 @@ pub struct OwnedAttributeDiscription {
/// An attribute on a DOM node, such as `id="my-thing"` or
/// `href="https://example.com"`.
#[derive(Clone, Copy, Debug)]
pub struct OwnedAttributeView<'a> {
pub struct OwnedAttributeView<'a, V: FromAnyValue = ()> {
/// The discription of the attribute.
pub attribute: &'a OwnedAttributeDiscription,
/// The value of the attribute.
pub value: &'a OwnedAttributeValue,
pub value: &'a OwnedAttributeValue<V>,
}
#[derive(Clone)]
pub enum OwnedAttributeValue {
pub enum OwnedAttributeValue<V: FromAnyValue = ()> {
Text(String),
Float(f64),
Int(i64),
Bool(bool),
Any(AnyValueContainer),
Custom(V),
None,
}
impl Debug for OwnedAttributeValue {
pub trait FromAnyValue {
fn from_any_value(value: &dyn AnyValue) -> Self;
}
impl FromAnyValue for () {
fn from_any_value(_: &dyn AnyValue) -> Self {}
}
impl<V: FromAnyValue> Debug for OwnedAttributeValue<V> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Text(arg0) => f.debug_tuple("Text").field(arg0).finish(),
Self::Float(arg0) => f.debug_tuple("Float").field(arg0).finish(),
Self::Int(arg0) => f.debug_tuple("Int").field(arg0).finish(),
Self::Bool(arg0) => f.debug_tuple("Bool").field(arg0).finish(),
Self::Any(_) => f.debug_tuple("Any").finish(),
Self::Custom(_) => f.debug_tuple("Any").finish(),
Self::None => write!(f, "None"),
}
}
}
impl From<AttributeValue<'_>> for OwnedAttributeValue {
fn from(value: AttributeValue<'_>) -> Self {
impl<V: FromAnyValue> From<BorrowedAttributeValue<'_>> for OwnedAttributeValue<V> {
fn from(value: BorrowedAttributeValue<'_>) -> Self {
match value {
AttributeValue::Text(text) => Self::Text(text.to_string()),
AttributeValue::Float(float) => Self::Float(float),
AttributeValue::Int(int) => Self::Int(int),
AttributeValue::Bool(bool) => Self::Bool(bool),
AttributeValue::Any(any) => Self::Any(any.borrow().as_ref().unwrap().clone()),
AttributeValue::None => Self::None,
_ => Self::None,
BorrowedAttributeValue::Text(text) => Self::Text(text.to_string()),
BorrowedAttributeValue::Float(float) => Self::Float(float),
BorrowedAttributeValue::Int(int) => Self::Int(int),
BorrowedAttributeValue::Bool(bool) => Self::Bool(bool),
BorrowedAttributeValue::Any(any) => Self::Custom(V::from_any_value(any)),
BorrowedAttributeValue::None => Self::None,
}
}
}
impl OwnedAttributeValue {
impl<V: FromAnyValue> OwnedAttributeValue<V> {
pub fn as_text(&self) -> Option<&str> {
match self {
OwnedAttributeValue::Text(text) => Some(text),
@@ -145,4 +152,11 @@ impl OwnedAttributeValue {
_ => None,
}
}
pub fn as_custom(&self) -> Option<&V> {
match self {
OwnedAttributeValue::Custom(custom) => Some(custom),
_ => None,
}
}
}
+8 -6
View File
@@ -1,21 +1,21 @@
use dioxus_core::ElementId;
use crate::{
node::{NodeData, NodeType, OwnedAttributeView},
node::{FromAnyValue, NodeData, NodeType, OwnedAttributeView},
state::union_ordered_iter,
RealNodeId,
};
/// A view into a [VNode] with limited access.
#[derive(Debug)]
pub struct NodeView<'a> {
inner: &'a NodeData,
pub struct NodeView<'a, V: FromAnyValue = ()> {
inner: &'a NodeData<V>,
mask: NodeMask,
}
impl<'a> NodeView<'a> {
impl<'a, V: FromAnyValue> NodeView<'a, V> {
/// Create a new NodeView from a VNode, and mask.
pub fn new(node: &'a NodeData, view: NodeMask) -> Self {
pub fn new(node: &'a NodeData<V>, view: NodeMask) -> Self {
Self {
inner: node,
mask: view,
@@ -55,7 +55,9 @@ impl<'a> NodeView<'a> {
}
/// Get any attributes that are enabled in the mask
pub fn attributes<'b>(&'b self) -> Option<impl Iterator<Item = OwnedAttributeView<'a>> + 'b> {
pub fn attributes<'b>(
&'b self,
) -> Option<impl Iterator<Item = OwnedAttributeView<'a, V>> + 'b> {
match &self.inner.node_type {
NodeType::Element { attributes, .. } => Some(
attributes
+7 -7
View File
@@ -1,6 +1,6 @@
use std::cmp::Ordering;
use crate::node::Node;
use crate::node::{FromAnyValue, Node};
use crate::node_ref::{NodeMask, NodeView};
use crate::passes::{resolve_passes, resolve_passes_single_threaded, AnyPass, DirtyNodeStates};
use crate::tree::TreeView;
@@ -76,7 +76,7 @@ pub(crate) fn union_ordered_iter<'a>(
/// }
/// }
/// ```
pub trait ChildDepState {
pub trait ChildDepState<V: FromAnyValue = ()> {
/// The context is passed to the [ChildDepState::reduce] when it is resolved.
type Ctx;
/// A state from each child node that this node depends on. Typically this is Self, but it could be any state that is within the state tree.
@@ -87,7 +87,7 @@ pub trait ChildDepState {
/// Resolve the state current node's state from the state of the children, the state of the node, and some external context.
fn reduce<'a>(
&mut self,
node: NodeView<'a>,
node: NodeView<'a, V>,
children: impl Iterator<Item = <Self::DepState as ElementBorrowable>::ElementBorrowed<'a>>,
ctx: &Self::Ctx,
) -> bool
@@ -138,7 +138,7 @@ pub trait ChildDepState {
/// }
/// }
/// ```
pub trait ParentDepState {
pub trait ParentDepState<V: FromAnyValue = ()> {
/// The context is passed to the [ParentDepState::reduce] when it is resolved.
type Ctx;
/// A state from from the parent node that this node depends on. Typically this is Self, but it could be any state that is within the state tree.
@@ -149,7 +149,7 @@ pub trait ParentDepState {
/// Resolve the state current node's state from the state of the parent node, the state of the node, and some external context.
fn reduce<'a>(
&mut self,
node: NodeView<'a>,
node: NodeView<'a, V>,
parent: Option<<Self::DepState as ElementBorrowable>::ElementBorrowed<'a>>,
ctx: &Self::Ctx,
) -> bool;
@@ -193,7 +193,7 @@ pub trait ParentDepState {
/// }
/// }
/// ```
pub trait NodeDepState {
pub trait NodeDepState<V: FromAnyValue = ()> {
/// Depstate must be a tuple containing any number of borrowed elements that are either [ChildDepState], [ParentDepState] or [NodeDepState].
type DepState: ElementBorrowable;
/// The state passed to [NodeDepState::reduce] when it is resolved.
@@ -203,7 +203,7 @@ pub trait NodeDepState {
/// Resolve the state current node's state from the state of the sibling states, the state of the node, and some external context.
fn reduce<'a>(
&mut self,
node: NodeView<'a>,
node: NodeView<'a, V>,
node_state: <Self::DepState as ElementBorrowable>::ElementBorrowed<'a>,
ctx: &Self::Ctx,
) -> bool;
-1
View File
@@ -305,7 +305,6 @@ impl<T> TreeView<T> for Tree<T> {
fn parent_child_mut(&mut self, id: NodeId) -> Option<(&mut T, Self::IteratorMut<'_>)> {
// Safety: No node will appear as a child twice
if let Some(children_ids) = self.children_ids(id) {
println!("parent_child_mut: {:?}\n{:?}", id, children_ids);
debug_assert!(!children_ids.iter().any(|child_id| *child_id == id));
let mut borrowed = unsafe {
let as_vec = children_ids.to_vec();
@@ -229,7 +229,7 @@ impl PersistantElementIter {
#[derive(Default, Clone, Debug)]
struct Empty {}
impl State for Empty {
const PASSES: &'static [crate::AnyPass<crate::node::Node<Self>>] = &[];
const PASSES: &'static [crate::AnyPass<crate::node::Node<Self, ()>>] = &[];
const MASKS: &'static [crate::NodeMask] = &[];
}