custom element test passing

This commit is contained in:
Evan Almloff committed 2023-04-12 11:35:57 -05:00
1 parent 43372c7609
commit 4e582d0374
10 files changed
+155 -57

No files matched your search

+25 -10
View File
@@ -153,6 +153,7 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
dependants: Default::default(),
mask: node_mask,
pass_direction: pass_direction::<V, Self>(),
enter_shadow_dom: Self::TRAVERSE_SHADOW_DOM,
workload: Self::workload_system,
phantom: PhantomData,
}
@@ -193,7 +194,6 @@ pub fn run_pass<V: FromAnyValue + Send + Sync>(
dependants: Arc<Dependants>,
pass_direction: PassDirection,
view: RunPassView<V>,
enter_shadow_dom: bool,
mut update_node: impl FnMut(NodeId, &SendAnyMap) -> bool,
) {
let RunPassView {
@@ -232,28 +232,42 @@ pub fn run_pass<V: FromAnyValue + Send + Sync>(
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) struct Dependant {
pub(crate) type_id: TypeId,
pub(crate) enter_shadow_dom: bool,
}
/// The states that depend on this state
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct Dependants {
/// The states in the parent direction that should be invalidated when this state is invalidated
pub parent: Vec<TypeId>,
pub(crate) parent: Vec<Dependant>,
/// The states in the child direction that should be invalidated when this state is invalidated
pub child: Vec<TypeId>,
pub(crate) child: Vec<Dependant>,
/// The states in the node direction that should be invalidated when this state is invalidated
pub node: Vec<TypeId>,
pub(crate) node: Vec<TypeId>,
}
impl Dependants {
fn mark_dirty(&self, dirty: &DirtyNodeStates, id: NodeId, tree: &impl TreeRef, height: u16) {
for dependant in &self.child {
for id in tree.children_ids(id) {
dirty.insert(*dependant, id, height + 1);
for &Dependant {
type_id,
enter_shadow_dom,
} in &self.child
{
for id in tree.children_ids_advanced(id, enter_shadow_dom) {
dirty.insert(type_id, id, height + 1);
}
}
for dependant in &self.parent {
if let Some(id) = tree.parent_id(id) {
dirty.insert(*dependant, id, height - 1);
for &Dependant {
type_id,
enter_shadow_dom,
} in &self.parent
{
if let Some(id) = tree.parent_id_advanced(id, enter_shadow_dom) {
dirty.insert(type_id, id, height - 1);
}
}
@@ -273,6 +287,7 @@ pub struct TypeErasedState<V: FromAnyValue + Send = ()> {
pub(crate) mask: NodeMask,
pub(crate) workload: fn(TypeId, Arc<Dependants>, PassDirection) -> WorkloadSystem,
pub(crate) pass_direction: PassDirection,
pub(crate) enter_shadow_dom: bool,
phantom: PhantomData<V>,
}
+35 -17
View File
@@ -16,7 +16,7 @@ use crate::node::{
};
use crate::node_ref::{NodeMask, NodeMaskBuilder};
use crate::node_watcher::{AttributeWatcher, NodeWatcher};
use crate::passes::{DirtyNodeStates, PassDirection, TypeErasedState};
use crate::passes::{Dependant, DirtyNodeStates, PassDirection, TypeErasedState};
use crate::prelude::AttributeMaskBuilder;
use crate::tree::{TreeMut, TreeMutView, TreeRef, TreeRefView};
use crate::NodeId;
@@ -128,19 +128,25 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
let (current, before) = before.split_last_mut().unwrap();
for state in before.iter_mut().chain(after.iter_mut()) {
let dependants = Arc::get_mut(&mut state.dependants).unwrap();
let current_dependant = Dependant {
type_id: current.this_type_id,
enter_shadow_dom: current.enter_shadow_dom,
};
// If this node depends on the other state as a parent, then the other state should update its children of the current type when it is invalidated
if current
.parent_dependancies_ids
.contains(&state.this_type_id)
&& !dependants.child.contains(&current.this_type_id)
&& !dependants.child.contains(&current_dependant)
{
dependants.child.push(current.this_type_id);
dependants.child.push(current_dependant);
}
// If this node depends on the other state as a child, then the other state should update its parent of the current type when it is invalidated
if current.child_dependancies_ids.contains(&state.this_type_id)
&& !dependants.parent.contains(&current.this_type_id)
&& !dependants.parent.contains(&current_dependant)
{
dependants.parent.push(current.this_type_id);
dependants.parent.push(current_dependant);
}
// If this node depends on the other state as a sibling, then the other state should update its siblings of the current type when it is invalidated
if current.node_dependancies_ids.contains(&state.this_type_id)
@@ -151,15 +157,19 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
}
// If the current state depends on itself, then it should update itself when it is invalidated
let dependants = Arc::get_mut(&mut current.dependants).unwrap();
let current_dependant = Dependant {
type_id: current.this_type_id,
enter_shadow_dom: current.enter_shadow_dom,
};
match current.pass_direction {
PassDirection::ChildToParent => {
if !dependants.parent.contains(&current.this_type_id) {
dependants.parent.push(current.this_type_id);
if !dependants.parent.contains(&current_dependant) {
dependants.parent.push(current_dependant);
}
}
PassDirection::ParentToChild => {
if !dependants.child.contains(&current.this_type_id) {
dependants.child.push(current.this_type_id);
if !dependants.child.contains(&current_dependant) {
dependants.child.push(current_dependant);
}
}
_ => {}
@@ -371,27 +381,27 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
}
/// Traverses the dom in a depth first manner, calling the provided function on each node.
pub fn traverse_depth_first(&self, mut f: impl FnMut(NodeRef<V>)) {
pub fn traverse_depth_first(&self, enter_shadow_doms: bool, mut f: impl FnMut(NodeRef<V>)) {
let mut stack = vec![self.root_id()];
let tree = self.tree_ref();
while let Some(id) = stack.pop() {
if let Some(node) = self.get(id) {
f(node);
let children = tree.children_ids(id);
let children = tree.children_ids_advanced(id, enter_shadow_doms);
stack.extend(children.iter().copied().rev());
}
}
}
/// Traverses the dom in a breadth first manner, calling the provided function on each node.
pub fn traverse_breadth_first(&self, mut f: impl FnMut(NodeRef<V>)) {
pub fn traverse_breadth_first(&self, enter_shadow_doms: bool, mut f: impl FnMut(NodeRef<V>)) {
let mut queue = VecDeque::new();
queue.push_back(self.root_id());
let tree = self.tree_ref();
while let Some(id) = queue.pop_front() {
if let Some(node) = self.get(id) {
f(node);
let children = tree.children_ids(id);
let children = tree.children_ids_advanced(id, enter_shadow_doms);
for id in children {
queue.push_back(id);
}
@@ -400,11 +410,15 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
}
/// Traverses the dom in a depth first manner mutably, calling the provided function on each node.
pub fn traverse_depth_first_mut(&mut self, mut f: impl FnMut(NodeMut<V>)) {
pub fn traverse_depth_first_mut(
&mut self,
enter_shadow_doms: bool,
mut f: impl FnMut(NodeMut<V>),
) {
let mut stack = vec![self.root_id()];
while let Some(id) = stack.pop() {
let tree = self.tree_ref();
let mut children = tree.children_ids(id);
let mut children = tree.children_ids_advanced(id, enter_shadow_doms);
drop(tree);
children.reverse();
if let Some(node) = self.get_mut(id) {
@@ -416,12 +430,16 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
}
/// Traverses the dom in a breadth first manner mutably, calling the provided function on each node.
pub fn traverse_breadth_first_mut(&mut self, mut f: impl FnMut(NodeMut<V>)) {
pub fn traverse_breadth_first_mut(
&mut self,
enter_shadow_doms: bool,
mut f: impl FnMut(NodeMut<V>),
) {
let mut queue = VecDeque::new();
queue.push_back(self.root_id());
while let Some(id) = queue.pop_front() {
let tree = self.tree_ref();
let children = tree.children_ids(id);
let children = tree.children_ids_advanced(id, enter_shadow_doms);
drop(tree);
if let Some(node) = self.get_mut(id) {
f(node);
+40 -7
View File
@@ -11,8 +11,6 @@ pub struct ShadowTree {
pub shadow_roots: Vec<NodeId>,
/// The node that children of the super tree should be inserted under.
pub slot: Option<NodeId>,
/// The node in the super tree that the shadow_tree is attached to.
pub super_tree_root: NodeId,
}
/// A node in a tree.
@@ -35,8 +33,43 @@ pub type TreeMutView<'a> = (EntitiesViewMut<'a>, ViewMut<'a, Node>);
/// A immutable view of a tree.
pub trait TreeRef {
/// Get the id of the parent of the current node, if enter_shadow_dom is true and the current node is a shadow root, the node the shadow root is attached to will be returned
#[inline]
fn parent_id_advanced(&self, id: NodeId, enter_shadow_dom: bool) -> Option<NodeId> {
// If this node is the root of a shadow_tree, return the node the shadow_tree is attached
let light_tree_root = self.light_tree_root(id);
match (light_tree_root, enter_shadow_dom) {
(Some(id), true) => Some(id),
_ => {
let parent_id = self.parent_id(id);
if enter_shadow_dom {
// If this node is attached via a slot, return the slot as the parent instead of the light tree parent
parent_id.map(|id| {
self.shadow_tree(id)
.and_then(|tree| tree.slot)
.unwrap_or(id)
})
} else {
parent_id
}
}
}
}
/// The parent id of the node.
fn parent_id(&self, id: NodeId) -> Option<NodeId>;
/// Get the ids of the children of the current node, if enter_shadow_dom is true and the current node is a shadow slot, the ids of the nodes under the node the shadow slot is attached to will be returned
#[inline]
fn children_ids_advanced(&self, id: NodeId, enter_shadow_dom: bool) -> Vec<NodeId> {
let shadow_tree = self.shadow_tree(id);
let slot_of_light_tree = self.slot_for_light_tree(id);
match (shadow_tree, slot_of_light_tree, enter_shadow_dom) {
// If this node is a shadow root, return the shadow roots
(Some(tree), _, true) => tree.shadow_roots.clone(),
// If this node is a slot, return the children of the node the slot is attached to
(None, Some(id), true) => self.children_ids(id),
_ => self.children_ids(id),
}
}
/// The children ids of the node.
fn children_ids(&self, id: NodeId) -> Vec<NodeId>;
/// The shadow tree tree under the node.
@@ -229,7 +262,6 @@ impl<'a> TreeMut for TreeMutView<'a> {
let light_root_height;
{
let shadow_tree = ShadowTree {
super_tree_root: id,
shadow_roots: shadow_roots.clone(),
slot,
};
@@ -251,6 +283,7 @@ impl<'a> TreeMut for TreeMutView<'a> {
// Now that we have created the shadow_tree, we need to update the height of the shadow_tree roots
for root in shadow_roots {
(&mut self.1).get(root).unwrap().light_tree_root = Some(id);
set_height(self, root, light_root_height + 1);
}
}
@@ -319,7 +352,7 @@ fn set_height(tree: &mut TreeMutView<'_>, node: NodeId, height: u16) {
if let Some(shadow_tree) = shadow_tree {
// Set the height of the shadow_tree roots
for &shadow_root in &shadow_tree.shadow_roots {
set_height(tree, shadow_root, height);
set_height(tree, shadow_root, height + 1);
}
} else {
// Otherwise, we just set the height of the children to be one more than the height of the parent
@@ -362,17 +395,17 @@ impl<'a> TreeRef for TreeMutView<'a> {
fn shadow_tree(&self, id: NodeId) -> Option<&ShadowTree> {
let node_data = &self.1;
node_data.get(id).unwrap().child_subtree.as_ref()
node_data.get(id).ok()?.child_subtree.as_ref()
}
fn slot_for_light_tree(&self, id: NodeId) -> Option<NodeId> {
let node_data = &self.1;
node_data.get(id).unwrap().slot_for_light_tree
node_data.get(id).ok()?.slot_for_light_tree
}
fn light_tree_root(&self, id: NodeId) -> Option<NodeId> {
let node_data = &self.1;
node_data.get(id).unwrap().light_tree_root
node_data.get(id).ok()?.light_tree_root
}
}