Jelajahi Sumber

finish shipyard migration in native-core

Evan Almloff 2 tahun lalu
induk
melakukan
a8566b4e71

+ 1 - 0
Cargo.toml

@@ -17,6 +17,7 @@ members = [
     "packages/rsx",
     "packages/tui",
     "packages/native-core",
+    "packages/native-core-macro",
     "packages/rsx-rosetta",
     "packages/signals",
     "packages/hot-reload",

+ 116 - 12
packages/native-core-macro/src/lib.rs

@@ -1,22 +1,126 @@
 extern crate proc_macro;
 
-mod sorted_slice;
+use std::collections::HashSet;
 
 use proc_macro::TokenStream;
-use quote::{quote, ToTokens, __private::Span};
-use sorted_slice::StrSlice;
-use syn::parenthesized;
-use syn::parse::ParseBuffer;
-use syn::punctuated::Punctuated;
-use syn::{
-    self,
-    parse::{Parse, ParseStream, Result},
-    parse_macro_input, parse_quote, Error, Field, Ident, Token, Type,
-};
+use quote::quote;
+use syn::Type;
 
 /// A helper attribute for deriving `State` for a struct.
 #[proc_macro_attribute]
-pub fn my_attribute(_: TokenStream, input: TokenStream) -> TokenStream {
+pub fn partial_derive_pass(_: TokenStream, input: TokenStream) -> TokenStream {
     let impl_block: syn::ItemImpl = syn::parse(input).unwrap();
+
+    let parent_dependencies = impl_block
+        .items
+        .iter()
+        .find_map(|item| {
+            if let syn::ImplItem::Type(syn::ImplItemType {
+                attrs, ident, ty, ..
+            }) = item
+            {
+                (ident == "ParentDependencies").then_some(ty)
+            } else {
+                None
+            }
+        })
+        .unwrap();
+    let child_dependencies = impl_block
+        .items
+        .iter()
+        .find_map(|item| {
+            if let syn::ImplItem::Type(syn::ImplItemType {
+                attrs, ident, ty, ..
+            }) = item
+            {
+                (ident == "ChildDependencies").then_some(ty)
+            } else {
+                None
+            }
+        })
+        .unwrap();
+    let node_dependencies = impl_block
+        .items
+        .iter()
+        .find_map(|item| {
+            if let syn::ImplItem::Type(syn::ImplItemType {
+                attrs, ident, ty, ..
+            }) = item
+            {
+                (ident == "NodeDependencies").then_some(ty)
+            } else {
+                None
+            }
+        })
+        .unwrap();
+
+    let this_type = &impl_block.self_ty;
+
+    let mut combined_dependencies = HashSet::new();
+
+    match parent_dependencies {
+        Type::Tuple(tuple) => {
+            for type_ in &tuple.elems {
+                combined_dependencies.insert(type_.clone());
+            }
+        }
+        _ => panic!("ParentDependencies must be a tuple"),
+    }
+    match child_dependencies {
+        Type::Tuple(tuple) => {
+            for type_ in &tuple.elems {
+                combined_dependencies.insert(type_.clone());
+            }
+        }
+        _ => panic!("ChildDependencies must be a tuple"),
+    }
+    match node_dependencies {
+        Type::Tuple(tuple) => {
+            for type_ in &tuple.elems {
+                combined_dependencies.insert(type_.clone());
+            }
+        }
+        _ => panic!("NodeDependencies must be a tuple"),
+    }
+    combined_dependencies.insert(*this_type.clone());
+
+    let combined_dependencies = combined_dependencies.into_iter();
+    let combined_dependencies = quote!((#(#combined_dependencies),*));
+
     quote!(#impl_block).into()
 }
+
+// pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
+//     /// This is a tuple of (T: Pass, ..) of states read from the parent required to run this pass
+//     type ParentDependencies: Dependancy;
+//     /// This is a tuple of (T: Pass, ..) of states read from the children required to run this pass
+//     type ChildDependencies: Dependancy;
+//     /// This is a tuple of (T: Pass, ..) of states read from the node required to run this pass
+//     type NodeDependencies: Dependancy;
+//     /// A tuple of all the dependencies combined
+//     type CombinedDependencies: Dependancy;
+//     /// This is a mask of what aspects of the node are required to run this pass
+//     const NODE_MASK: NodeMaskBuilder<'static>;
+//
+//     /// Update this state in a node, returns if the state was updated
+//     fn update<'a>(
+//         &mut self,
+//         node_view: NodeView<V>,
+//         node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
+//         parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
+//         children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+//         context: &SendAnyMap,
+//     ) -> bool;
+//
+//     /// Create a new instance of this state
+//     fn create<'a>(
+//         node_view: NodeView<V>,
+//         node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
+//         parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
+//         children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+//         context: &SendAnyMap,
+//     ) -> Self;
+//
+//     /// Create a workload system for this state
+//     fn workload_system(dependants: FxHashSet<TypeId>) -> WorkloadSystem;
+// }

+ 1 - 0
packages/native-core/Cargo.toml

@@ -29,6 +29,7 @@ lightningcss = "1.0.0-alpha.39"
 
 rayon = "1.6.1"
 shipyard = "0.6.2"
+shipyard_hierarchy = "0.6.0"
 
 
 [dev-dependencies]

+ 2 - 1
packages/native-core/src/dioxus.rs

@@ -1,3 +1,4 @@
+use crate::tree::TreeMut;
 use dioxus_core::{BorrowedAttributeValue, ElementId, Mutations, TemplateNode};
 use rustc_hash::{FxHashMap, FxHashSet};
 use shipyard::Component;
@@ -155,7 +156,7 @@ impl DioxusState {
                     let new_nodes = self.stack.split_off(self.stack.len() - m);
                     let old_node_id = self.element_to_node_id(id);
                     for new in new_nodes {
-                        rdom.tree.insert_before(old_node_id, new);
+                        rdom.tree_mut().insert_before(old_node_id, new);
                     }
                 }
                 SetAttribute {

+ 96 - 140
packages/native-core/src/passes.rs

@@ -1,7 +1,10 @@
 use anymap::AnyMap;
 use parking_lot::RwLock;
 use rustc_hash::{FxHashMap, FxHashSet};
-use shipyard::{Component, IntoBorrow, Unique, View, WorkloadSystem};
+use shipyard::{
+    BorrowInfo, Component, IntoBorrow, IntoWorkloadSystem, Unique, UniqueView, View,
+    WorkloadSystem, World,
+};
 use std::any::{Any, TypeId};
 use std::collections::BTreeMap;
 use std::marker::PhantomData;
@@ -9,7 +12,9 @@ use std::sync::Arc;
 
 use crate::node::FromAnyValue;
 use crate::node_ref::{NodeMaskBuilder, NodeView};
-use crate::SendAnyMap;
+use crate::real_dom::{DirtyNodesResult, SendAnyMapWrapper};
+use crate::tree::{TreeMut, TreeRef, TreeRefView};
+use crate::{FxDashSet, SendAnyMap};
 use crate::{NodeId, NodeMask};
 
 #[derive(Default)]
@@ -108,6 +113,7 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
     type ChildDependencies: Dependancy;
     /// This is a tuple of (T: Pass, ..) of states read from the node required to run this pass
     type NodeDependencies: Dependancy;
+    /// A tuple of all the dependencies combined
     type CombinedDependencies: Dependancy;
     /// This is a mask of what aspects of the node are required to run this pass
     const NODE_MASK: NodeMaskBuilder<'static>;
@@ -130,39 +136,93 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
         children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
         context: &SendAnyMap,
     ) -> Self;
+
+    /// Create a workload system for this state
+    fn workload_system(dependants: FxHashSet<TypeId>) -> WorkloadSystem;
 }
 
-pub trait AnyState<V: FromAnyValue + Send + Sync = ()>: State<V> {
-    fn workload_system() -> WorkloadSystem;
-    //  Box::new(
-    //     move |node_id: NodeId, tree: &mut TreeStateView, context: &SendAnyMap| {
-    //         debug_assert!(!Self::NodeDependencies::type_ids()
-    //             .iter()
-    //             .any(|id| *id == TypeId::of::<Self>()));
-    //         // get all of the states from the tree view
-    //         // Safety: No node has itself as a parent or child.
-    //         let myself: SlabEntry<'static, Self> = unsafe {
-    //             std::mem::transmute(tree.get_slab_mut::<Self>().unwrap().entry(node_id))
-    //         };
-    //         let node_data = tree.get_single::<NodeType<V>>(node_id).unwrap();
-    //         let node = tree.get::<Self::NodeDependencies>(node_id).unwrap();
-    //         let children = tree.children::<Self::ChildDependencies>(node_id);
-    //         let parent = tree.parent::<Self::ParentDependencies>(node_id);
-
-    //         let view = NodeView::new(node_id, node_data, &node_mask);
-    //         if myself.value.is_none() {
-    //             *myself.value = Some(Self::create(view, node, parent, children, context));
-    //             true
-    //         } else {
-    //             myself
-    //                 .value
-    //                 .as_mut()
-    //                 .unwrap()
-    //                 .update(view, node, parent, children, context)
-    //         }
-    //     },
-    // ) as PassCallback
+pub struct RunPassView<'a> {
+    type_id: TypeId,
+    dependants: FxHashSet<TypeId>,
+    pass_direction: PassDirection,
+    tree: TreeRefView<'a>,
+    nodes_updated: UniqueView<'a, DirtyNodesResult>,
+    dirty: UniqueView<'a, DirtyNodeStates>,
+    ctx: UniqueView<'a, SendAnyMapWrapper>,
+}
+
+impl<'a> RunPassView<'a> {
+    pub fn borrow(
+        type_id: TypeId,
+        dependants: FxHashSet<TypeId>,
+        pass_direction: PassDirection,
+        world: &'a World,
+    ) -> Self {
+        Self {
+            type_id,
+            dependants,
+            pass_direction,
+            tree: world.borrow().unwrap(),
+            nodes_updated: world.borrow().unwrap(),
+            dirty: world.borrow().unwrap(),
+            ctx: world.borrow().unwrap(),
+        }
+    }
+}
+
+pub fn run_pass(view: RunPassView, mut update_node: impl FnMut(NodeId, &SendAnyMap) -> bool) {
+    let RunPassView {
+        type_id,
+        dependants,
+        pass_direction,
+        tree,
+        nodes_updated,
+        dirty,
+        ctx,
+    } = view;
+    let ctx = ctx.as_ref();
+    match pass_direction {
+        PassDirection::ParentToChild => {
+            while let Some((height, id)) = dirty.pop_front(type_id) {
+                let id = tree.id_at(id).unwrap();
+                if (update_node)(id, ctx) {
+                    nodes_updated.insert(id);
+                    for id in tree.children_ids(id).unwrap() {
+                        for dependant in &dependants {
+                            dirty.insert(*dependant, id, height + 1);
+                        }
+                    }
+                }
+            }
+        }
+        PassDirection::ChildToParent => {
+            while let Some((height, id)) = dirty.pop_back(type_id) {
+                let id = tree.id_at(id).unwrap();
+                if (update_node)(id, ctx) {
+                    nodes_updated.insert(id);
+                    if let Some(id) = tree.parent_id(id) {
+                        for dependant in &dependants {
+                            dirty.insert(*dependant, id, height - 1);
+                        }
+                    }
+                }
+            }
+        }
+        PassDirection::AnyOrder => {
+            while let Some((height, id)) = dirty.pop_back(type_id) {
+                let id = tree.id_at(id).unwrap();
+                if (update_node)(id, ctx) {
+                    nodes_updated.insert(id);
+                    for dependant in &dependants {
+                        dirty.insert(*dependant, id, height);
+                    }
+                }
+            }
+        }
+    }
+}
 
+pub trait AnyState<V: FromAnyValue + Send + Sync = ()>: State<V> {
     fn to_type_erased() -> TypeErasedPass<V>
     where
         Self: Sized,
@@ -174,9 +234,9 @@ pub trait AnyState<V: FromAnyValue + Send + Sync = ()>: State<V> {
             parent_dependant: !Self::parent_type_ids().is_empty(),
             child_dependant: !Self::child_type_ids().is_empty(),
             dependants: FxHashSet::default(),
-            mask: node_mask.clone(),
+            mask: node_mask,
             pass_direction: Self::pass_direction(),
-            workload: Some(Self::workload_system()),
+            workload: Self::workload_system,
             phantom: PhantomData,
         }
     }
@@ -224,58 +284,11 @@ pub struct TypeErasedPass<V: FromAnyValue + Send = ()> {
     pub(crate) combined_dependancy_type_ids: FxHashSet<TypeId>,
     pub(crate) dependants: FxHashSet<TypeId>,
     pub(crate) mask: NodeMask,
-    pub(crate) workload: Option<WorkloadSystem>,
+    pub(crate) workload: fn(FxHashSet<TypeId>) -> WorkloadSystem,
     pub(crate) pass_direction: PassDirection,
     phantom: PhantomData<V>,
 }
 
-// impl<V: FromAnyValue + Send> TypeErasedPass<V> {
-//     fn resolve(
-//         &self,
-//         mut tree: TreeStateView,
-//         dirty: &DirtyNodeStates,
-//         nodes_updated: &FxDashSet<NodeId>,
-//         ctx: &SendAnyMap,
-//     ) {
-//         match self.pass_direction {
-//             PassDirection::ParentToChild => {
-//                 while let Some((height, id)) = dirty.pop_front(self.this_type_id) {
-//                     if (self.pass)(id, &mut tree, ctx) {
-//                         nodes_updated.insert(id);
-//                         for id in tree.children_ids(id).unwrap() {
-//                             for dependant in &self.dependants {
-//                                 dirty.insert(*dependant, *id, height + 1);
-//                             }
-//                         }
-//                     }
-//                 }
-//             }
-//             PassDirection::ChildToParent => {
-//                 while let Some((height, id)) = dirty.pop_back(self.this_type_id) {
-//                     if (self.pass)(id, &mut tree, ctx) {
-//                         nodes_updated.insert(id);
-//                         if let Some(id) = tree.parent_id(id) {
-//                             for dependant in &self.dependants {
-//                                 dirty.insert(*dependant, id, height - 1);
-//                             }
-//                         }
-//                     }
-//                 }
-//             }
-//             PassDirection::AnyOrder => {
-//                 while let Some((height, id)) = dirty.pop_back(self.this_type_id) {
-//                     if (self.pass)(id, &mut tree, ctx) {
-//                         nodes_updated.insert(id);
-//                         for dependant in &self.dependants {
-//                             dirty.insert(*dependant, id, height);
-//                         }
-//                     }
-//                 }
-//             }
-//         }
-//     }
-// }
-
 #[derive(Debug)]
 pub enum PassDirection {
     ParentToChild,
@@ -300,7 +313,7 @@ impl<'a> AnyMapLike<'a> for &'a SendAnyMap {
 }
 
 pub trait Dependancy {
-    type ElementBorrowed<'a>: IntoBorrow;
+    type ElementBorrowed<'a>: IntoBorrow + BorrowInfo;
 
     fn type_ids() -> Box<[TypeId]> {
         Box::new([])
@@ -330,60 +343,3 @@ impl_dependancy!(A, B, C, D, E, F, G);
 impl_dependancy!(A, B, C, D, E, F, G, H);
 impl_dependancy!(A, B, C, D, E, F, G, H, I);
 impl_dependancy!(A, B, C, D, E, F, G, H, I, J);
-
-// pub fn resolve_passes<V: FromAnyValue + Send + Sync>(
-//     dom: &mut RealDom<V>,
-//     dirty_nodes: DirtyNodeStates,
-//     ctx: SendAnyMap,
-//     parallel: bool,
-// ) -> FxDashSet<NodeId> {
-//     let passes = &dom.dirty_nodes.passes;
-//     let mut resolved_passes: FxHashSet<TypeId> = FxHashSet::default();
-//     let mut resolving = Vec::new();
-//     let nodes_updated = Arc::new(FxDashSet::default());
-//     let ctx = Arc::new(ctx);
-//     let mut pass_indexes_remaining: Vec<_> = (0..passes.len()).collect::<Vec<_>>();
-//     while !pass_indexes_remaining.is_empty() {
-//         let mut currently_in_use = FxHashSet::<TypeId>::default();
-//         let dynamically_borrowed_tree = dom.tree.dynamically_borrowed();
-//         rayon::in_place_scope(|s| {
-//             let mut i = 0;
-//             while i < pass_indexes_remaining.len() {
-//                 let passes_idx = pass_indexes_remaining[i];
-//                 let pass = &passes[passes_idx];
-//                 let pass_id = pass.this_type_id;
-//                 // check if the pass is ready to be run
-//                 if pass.combined_dependancy_type_ids.iter().all(|d| {
-//                     (resolved_passes.contains(d) || *d == pass_id) && !currently_in_use.contains(d)
-//                 }) {
-//                     pass_indexes_remaining.remove(i);
-//                     resolving.push(pass_id);
-//                     currently_in_use.insert(pass.this_type_id);
-//                     let tree_view = dynamically_borrowed_tree.view(
-//                         pass.combined_dependancy_type_ids
-//                             .iter()
-//                             .filter(|id| **id != pass.this_type_id)
-//                             .copied()
-//                             .chain(std::iter::once(TypeId::of::<NodeType<V>>())),
-//                         [pass.this_type_id],
-//                     );
-//                     let dirty_nodes = dirty_nodes.clone();
-//                     let nodes_updated = nodes_updated.clone();
-//                     let ctx = ctx.clone();
-//                     if parallel {
-//                         s.spawn(move |_| {
-//                             pass.resolve(tree_view, &dirty_nodes, &nodes_updated, &ctx);
-//                         });
-//                     } else {
-//                         pass.resolve(tree_view, &dirty_nodes, &nodes_updated, &ctx);
-//                     }
-//                 } else {
-//                     i += 1;
-//                 }
-//             }
-//         });
-//         resolved_passes.extend(resolving.iter().copied());
-//         resolving.clear()
-//     }
-//     std::sync::Arc::try_unwrap(nodes_updated).unwrap()
-// }

+ 129 - 65
packages/native-core/src/real_dom.rs

@@ -1,10 +1,8 @@
 use rustc_hash::{FxHashMap, FxHashSet};
 use shipyard::error::GetStorage;
 use shipyard::track::Untracked;
-use shipyard::{
-    Component, Get, IntoBorrow, ScheduledWorkload, System, Unique, View, ViewMut, Workload,
-    WorkloadSystem,
-};
+use shipyard::{Component, Get, IntoBorrow, ScheduledWorkload, Unique, View, ViewMut, Workload};
+use shipyard::{SystemModificator, World};
 use std::any::TypeId;
 use std::collections::VecDeque;
 use std::ops::{Deref, DerefMut};
@@ -17,17 +15,33 @@ use crate::node_ref::{NodeMask, NodeMaskBuilder};
 use crate::node_watcher::NodeWatcher;
 use crate::passes::{DirtyNodeStates, TypeErasedPass};
 use crate::prelude::AttributeMaskBuilder;
-use crate::tree::Tree;
+use crate::tree::{TreeMut, TreeMutView, TreeRef, TreeRefView};
 use crate::NodeId;
 use crate::{FxDashSet, SendAnyMap};
 
 #[derive(Unique)]
-struct SendAnyMapWrapper(SendAnyMap);
+pub struct SendAnyMapWrapper(SendAnyMap);
+
+impl Deref for SendAnyMapWrapper {
+    type Target = SendAnyMap;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
 
 #[derive(Unique, Default)]
-struct DirtyNodes(FxDashSet<NodeId>);
+pub struct DirtyNodesResult(FxDashSet<NodeId>);
 
-pub(crate) struct NodesDirty<V: FromAnyValue + Send + Sync> {
+impl Deref for DirtyNodesResult {
+    type Target = FxDashSet<NodeId>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+pub struct NodesDirty<V: FromAnyValue + Send + Sync> {
     passes_updated: FxHashMap<NodeId, FxHashSet<TypeId>>,
     nodes_updated: FxHashMap<NodeId, NodeMask>,
     pub(crate) passes: Box<[TypeErasedPass<V>]>,
@@ -76,31 +90,27 @@ type NodeWatchers<V> = Arc<RwLock<Vec<Box<dyn NodeWatcher<V> + Send + Sync>>>>;
 /// # Custom values
 /// To allow custom values to be passed into attributes implement FromAnyValue on a type that can represent your custom value and specify the V generic to be that type. If you have many different custom values, it can be useful to use a enum type to represent the varients.
 pub struct RealDom<V: FromAnyValue + Send + Sync = ()> {
-    pub(crate) tree: Tree,
+    pub(crate) world: World,
     nodes_listening: FxHashMap<String, FxHashSet<NodeId>>,
     pub(crate) dirty_nodes: NodesDirty<V>,
     node_watchers: NodeWatchers<V>,
     workload: ScheduledWorkload,
+    root_id: NodeId,
     phantom: std::marker::PhantomData<V>,
 }
 
 impl<V: FromAnyValue + Send + Sync> RealDom<V> {
     pub fn new(mut passes: Box<[TypeErasedPass<V>]>) -> RealDom<V> {
-        let mut tree = Tree::new();
-        let mut workload = Workload::new("Main Workload");
-        for pass in &mut *passes {
-            let system = pass.workload.take().unwrap();
-            workload = workload.with_system(system);
-        }
+        let workload = construct_workload(&mut passes);
         let (workload, _) = workload.build().unwrap();
-        let root_id = tree.root();
+        let mut world = World::new();
         let root_node: NodeType<V> = NodeType::Element(ElementNode {
             tag: "Root".to_string(),
             namespace: Some("Root".to_string()),
             attributes: FxHashMap::default(),
             listeners: FxHashSet::default(),
         });
-        tree.insert(root_id, root_node);
+        let root_id = world.add_entity(root_node);
 
         // resolve dependants for each pass
         for i in 1..passes.len() {
@@ -122,7 +132,7 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
         nodes_updated.insert(root_id, NodeMaskBuilder::ALL.build());
 
         RealDom {
-            tree,
+            world,
             nodes_listening: FxHashMap::default(),
             dirty_nodes: NodesDirty {
                 passes_updated,
@@ -131,19 +141,27 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
             },
             node_watchers: Default::default(),
             workload,
+            root_id,
             phantom: std::marker::PhantomData,
         }
     }
 
+    pub fn tree_mut(&self) -> TreeMutView {
+        self.world.borrow().unwrap()
+    }
+
+    pub fn tree_ref(&self) -> TreeRefView {
+        self.world.borrow().unwrap()
+    }
+
     pub fn create_node(&mut self, node: NodeType<V>) -> NodeMut<'_, V> {
-        let mut node_entry = self.tree.create_node();
-        let id = node_entry.id();
+        let id = self.world.add_entity(node);
+        self.tree_mut().create_node(id);
         self.dirty_nodes
             .passes_updated
             .entry(id)
             .or_default()
             .extend(self.dirty_nodes.passes.iter().map(|x| x.this_type_id));
-        node_entry.insert(node);
         let watchers = self.node_watchers.clone();
         for watcher in &*watchers.read().unwrap() {
             watcher.on_node_added(NodeMut::new(id, self));
@@ -157,7 +175,7 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
         if let Some(nodes) = self.nodes_listening.get(event) {
             let mut listening: Vec<_> = nodes
                 .iter()
-                .map(|id| (*id, self.tree.height(*id).unwrap()))
+                .map(|id| (*id, self.tree_ref().height(*id).unwrap()))
                 .collect();
             listening.sort_by(|(_, h1), (_, h2)| h1.cmp(h2).reverse());
             listening
@@ -171,26 +189,29 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
 
     /// Returns the id of the root node.
     pub fn root_id(&self) -> NodeId {
-        self.tree.root()
+        self.root_id
     }
 
     pub fn get(&self, id: NodeId) -> Option<NodeRef<'_, V>> {
-        self.tree.contains(id).then_some(NodeRef { id, dom: self })
+        self.tree_ref()
+            .contains(id)
+            .then_some(NodeRef { id, dom: self })
     }
 
     pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<'_, V>> {
-        self.tree.contains(id).then(|| NodeMut::new(id, self))
+        let contains = { self.tree_ref().contains(id) };
+        contains.then(|| NodeMut::new(id, self))
     }
 
     fn borrow_raw<'a, B: IntoBorrow>(&'a self) -> Result<B, GetStorage>
     where
         B::Borrow: shipyard::Borrow<'a, View = B>,
     {
-        self.tree.nodes.borrow()
+        self.world.borrow()
     }
 
     fn borrow_node_type_mut(&self) -> Result<ViewMut<NodeType<V>>, GetStorage> {
-        self.tree.nodes.borrow()
+        self.world.borrow()
     }
 
     /// Update the state of the dom, after appling some mutations. This will keep the nodes in the dom up to date with their VNode counterparts.
@@ -202,34 +223,36 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
         let nodes_updated = std::mem::take(&mut self.dirty_nodes.nodes_updated);
         let dirty_nodes =
             DirtyNodeStates::with_passes(self.dirty_nodes.passes.iter().map(|p| p.this_type_id));
+        let tree = self.tree_ref();
         for (node_id, passes) in passes {
             // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
-            if let Some(height) = self.tree.height(node_id) {
+            if let Some(height) = tree.height(node_id) {
                 for pass in passes {
                     dirty_nodes.insert(pass, node_id, height);
                 }
             }
         }
 
-        let _ = self.tree.remove_unique::<DirtyNodeStates>();
-        let _ = self.tree.remove_unique::<SendAnyMapWrapper>();
-        self.tree.add_unique(dirty_nodes);
-        self.tree.add_unique(SendAnyMapWrapper(ctx));
-        self.tree.add_unique(DirtyNodes::default());
+        let _ = self.world.remove_unique::<DirtyNodeStates>();
+        let _ = self.world.remove_unique::<SendAnyMapWrapper>();
+        self.world.add_unique(dirty_nodes);
+        self.world.add_unique(SendAnyMapWrapper(ctx));
+        self.world.add_unique(DirtyNodesResult::default());
 
-        self.workload.run_with_world(&self.tree.nodes).unwrap();
+        self.workload.run_with_world(&self.world).unwrap();
 
-        let dirty = self.tree.remove_unique::<DirtyNodes>().unwrap();
+        let dirty = self.world.remove_unique::<DirtyNodesResult>().unwrap();
 
         (dirty.0, nodes_updated)
     }
 
     pub fn traverse_depth_first(&self, 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);
-                if let Some(children) = self.tree.children_ids(id) {
+                if let Some(children) = tree.children_ids(id) {
                     stack.extend(children.iter().copied().rev());
                 }
             }
@@ -239,10 +262,11 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
     pub fn traverse_breadth_first(&self, 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);
-                if let Some(children) = self.tree.children_ids(id) {
+                if let Some(children) = tree.children_ids(id) {
                     for id in children {
                         queue.push_back(id);
                     }
@@ -254,8 +278,10 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
     pub fn traverse_depth_first_mut(&mut self, mut f: impl FnMut(NodeMut<V>)) {
         let mut stack = vec![self.root_id()];
         while let Some(id) = stack.pop() {
-            if let Some(children) = self.tree.children_ids(id) {
-                let children = children.iter().copied().rev().collect::<Vec<_>>();
+            let tree = self.tree_ref();
+            if let Some(mut children) = tree.children_ids(id) {
+                drop(tree);
+                children.reverse();
                 if let Some(node) = self.get_mut(id) {
                     let node = node;
                     f(node);
@@ -269,8 +295,9 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
         let mut queue = VecDeque::new();
         queue.push_back(self.root_id());
         while let Some(id) = queue.pop_front() {
-            if let Some(children) = self.tree.children_ids(id) {
-                let children = children.to_vec();
+            let tree = self.tree_ref();
+            if let Some(children) = tree.children_ids(id) {
+                drop(tree);
                 if let Some(node) = self.get_mut(id) {
                     f(node);
                     for id in children {
@@ -349,7 +376,7 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
 
     #[inline]
     fn child_ids(&self) -> Option<Vec<NodeId>> {
-        self.real_dom().tree.children_ids(self.id())
+        self.real_dom().tree_ref().children_ids(self.id())
     }
 
     #[inline]
@@ -368,7 +395,7 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
 
     #[inline]
     fn parent_id(&self) -> Option<NodeId> {
-        self.real_dom().tree.parent_id(self.id())
+        self.real_dom().tree_ref().parent_id(self.id())
     }
 
     #[inline]
@@ -382,7 +409,7 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
     #[inline]
     fn next(&self) -> Option<NodeRef<V>> {
         let parent = self.parent_id()?;
-        let children = self.real_dom().tree.children_ids(parent)?;
+        let children = self.real_dom().tree_ref().children_ids(parent)?;
         let index = children.iter().position(|id| *id == self.id())?;
         if index + 1 < children.len() {
             Some(NodeRef {
@@ -397,7 +424,7 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
     #[inline]
     fn prev(&self) -> Option<NodeRef<V>> {
         let parent = self.parent_id()?;
-        let children = self.real_dom().tree.children_ids(parent)?;
+        let children = self.real_dom().tree_ref().children_ids(parent)?;
         let index = children.iter().position(|id| *id == self.id())?;
         if index > 0 {
             Some(NodeRef {
@@ -411,7 +438,7 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
 
     #[inline]
     fn height(&self) -> u16 {
-        self.real_dom().tree.height(self.id()).unwrap()
+        self.real_dom().tree_ref().height(self.id()).unwrap()
     }
 }
 
@@ -501,13 +528,13 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
             .entry(self.id)
             .or_default()
             .insert(TypeId::of::<T>());
-        self.dom.tree.insert(self.id, value);
+        self.dom.world.add_component(self.id, value);
     }
 
     #[inline]
     pub fn next_mut(self) -> Option<NodeMut<'a, V>> {
         let parent = self.parent_id()?;
-        let children = self.dom.tree.children_ids(parent)?;
+        let children = self.dom.tree_mut().children_ids(parent)?;
         let index = children.iter().position(|id| *id == self.id)?;
         if index + 1 < children.len() {
             Some(NodeMut::new(children[index + 1], self.dom))
@@ -519,7 +546,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
     #[inline]
     pub fn prev_mut(self) -> Option<NodeMut<'a, V>> {
         let parent = self.parent_id()?;
-        let children = self.dom.tree.children_ids(parent)?;
+        let children = self.dom.tree_ref().children_ids(parent)?;
         let index = children.iter().position(|id| *id == self.id)?;
         if index > 0 {
             Some(NodeMut::new(children[index - 1], self.dom))
@@ -532,29 +559,31 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
     pub fn add_child(&mut self, child: NodeId) {
         self.dom.dirty_nodes.mark_child_changed(self.id);
         self.dom.dirty_nodes.mark_parent_added_or_removed(child);
-        self.dom.tree.add_child(self.id, child);
+        self.dom.tree_mut().add_child(self.id, child);
         NodeMut::new(child, self.dom).mark_moved();
     }
 
     #[inline]
     pub fn insert_after(&mut self, old: NodeId) {
         let id = self.id();
-        if let Some(parent_id) = self.dom.tree.parent_id(old) {
+        let parent_id = { self.dom.tree_ref().parent_id(old) };
+        if let Some(parent_id) = parent_id {
             self.dom.dirty_nodes.mark_child_changed(parent_id);
             self.dom.dirty_nodes.mark_parent_added_or_removed(id);
         }
-        self.dom.tree.insert_after(old, id);
+        self.dom.tree_mut().insert_after(old, id);
         self.mark_moved();
     }
 
     #[inline]
     pub fn insert_before(&mut self, old: NodeId) {
         let id = self.id();
-        if let Some(parent_id) = self.dom.tree.parent_id(old) {
+        let parent_id = { self.dom.tree_ref().parent_id(old) };
+        if let Some(parent_id) = parent_id {
             self.dom.dirty_nodes.mark_child_changed(parent_id);
             self.dom.dirty_nodes.mark_parent_added_or_removed(id);
         }
-        self.dom.tree.insert_before(old, id);
+        self.dom.tree_mut().insert_before(old, id);
         self.mark_moved();
     }
 
@@ -563,11 +592,11 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
         let id = self.id();
         {
             let RealDom {
-                tree,
+                world,
                 nodes_listening,
                 ..
             } = &mut self.dom;
-            let mut view: ViewMut<NodeType<V>> = tree.nodes.borrow().unwrap();
+            let mut view: ViewMut<NodeType<V>> = world.borrow().unwrap();
             if let NodeType::Element(ElementNode { listeners, .. })
             | NodeType::Text(TextNode { listeners, .. }) = (&mut view).get(id).unwrap()
             {
@@ -578,7 +607,8 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
             }
         }
         self.mark_removed();
-        if let Some(parent_id) = self.real_dom_mut().tree.parent_id(id) {
+        let parent_id = { self.dom.tree_ref().parent_id(id) };
+        if let Some(parent_id) = parent_id {
             self.real_dom_mut()
                 .dirty_nodes
                 .mark_child_changed(parent_id);
@@ -589,7 +619,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
                 self.dom.get_mut(child).unwrap().remove();
             }
         }
-        self.dom.tree.remove_single(id);
+        self.dom.tree_mut().remove_single(id);
     }
 
     #[inline]
@@ -604,19 +634,19 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
                 .mark_parent_added_or_removed(new);
         }
         let id = self.id();
-        self.dom.tree.replace(id, new);
+        self.dom.tree_mut().replace(id, new);
     }
 
     #[inline]
     pub fn add_event_listener(&mut self, event: &str) {
         let id = self.id();
         let RealDom {
-            tree,
+            world,
             dirty_nodes,
             nodes_listening,
             ..
         } = &mut self.dom;
-        let mut view: ViewMut<NodeType<V>> = tree.nodes.borrow().unwrap();
+        let mut view: ViewMut<NodeType<V>> = world.borrow().unwrap();
         let node_type: &mut NodeType<V> = (&mut view).get(self.id).unwrap();
         if let NodeType::Element(ElementNode { listeners, .. })
         | NodeType::Text(TextNode { listeners, .. }) = node_type
@@ -640,12 +670,12 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
     pub fn remove_event_listener(&mut self, event: &str) {
         let id = self.id();
         let RealDom {
-            tree,
+            world,
             dirty_nodes,
             nodes_listening,
             ..
         } = &mut self.dom;
-        let mut view: ViewMut<NodeType<V>> = tree.nodes.borrow().unwrap();
+        let mut view: ViewMut<NodeType<V>> = world.borrow().unwrap();
         let node_type: &mut NodeType<V> = (&mut view).get(self.id).unwrap();
         if let NodeType::Element(ElementNode { listeners, .. })
         | NodeType::Text(TextNode { listeners, .. }) = node_type
@@ -674,9 +704,9 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
     pub fn node_type_mut(&mut self) -> NodeTypeMut<'_, V> {
         let id = self.id();
         let RealDom {
-            tree, dirty_nodes, ..
+            world, dirty_nodes, ..
         } = &mut self.dom;
-        let view: ViewMut<NodeType<V>> = tree.nodes.borrow().unwrap();
+        let view: ViewMut<NodeType<V>> = world.borrow().unwrap();
         let node_type = ViewEntryMut::new(view, id);
         match &*node_type {
             NodeType::Element(_) => NodeTypeMut::Element(ElementNodeMut {
@@ -857,3 +887,37 @@ impl<V: FromAnyValue + Send + Sync> ElementNodeMut<'_, V> {
         &self.element().listeners
     }
 }
+
+fn construct_workload<V: FromAnyValue + Send + Sync>(passes: &mut [TypeErasedPass<V>]) -> Workload {
+    let mut workload = Workload::new("Main Workload");
+    let mut unresloved_workloads = passes
+        .iter_mut()
+        .enumerate()
+        .map(|(i, pass)| {
+            let workload = Some((pass.workload)(pass.dependants.clone()));
+            (i, pass, workload)
+        })
+        .collect::<Vec<_>>();
+    // set all the labels
+    for (id, _, workload) in &mut unresloved_workloads {
+        *workload = Some(workload.take().unwrap().tag(id.to_string()));
+    }
+    // mark any dependancies
+    for i in 0..unresloved_workloads.len() {
+        let (_, pass, _) = &unresloved_workloads[i];
+        for ty_id in pass.combined_dependancy_type_ids.clone() {
+            let &(dependancy_id, _, _) = unresloved_workloads
+                .iter()
+                .find(|(_, pass, _)| pass.this_type_id == ty_id)
+                .unwrap();
+            let (_, _, workload) = &mut unresloved_workloads[i];
+            *workload = workload
+                .take()
+                .map(|workload| workload.tag(dependancy_id.to_string()));
+        }
+    }
+    for (_, _, mut workload_system) in unresloved_workloads {
+        workload = workload.with_system(workload_system.take().unwrap());
+    }
+    workload
+}

+ 68 - 88
packages/native-core/src/tree.rs

@@ -1,63 +1,65 @@
 use crate::NodeId;
-use shipyard::{Component, EntitiesView, EntityId, Get, Unique, View, ViewMut, World};
+use shipyard::{Component, EntitiesViewMut, Get, View, ViewMut};
 use std::fmt::Debug;
 
 #[derive(PartialEq, Eq, Clone, Debug, Component)]
-pub(crate) struct Node {
+pub struct Node {
     parent: Option<NodeId>,
     children: Vec<NodeId>,
     height: u16,
 }
 
-#[derive(Debug)]
-pub(crate) struct Tree {
-    pub(crate) nodes: World,
-    root: NodeId,
+pub type TreeRefView<'a> = View<'a, Node>;
+pub type TreeMutView<'a> = (EntitiesViewMut<'a>, ViewMut<'a, Node>);
+
+pub trait TreeRef {
+    fn parent_id(&self, id: NodeId) -> Option<NodeId>;
+    fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>>;
+    fn height(&self, id: NodeId) -> Option<u16>;
+    fn contains(&self, id: NodeId) -> bool;
 }
 
-impl Tree {
-    pub fn new() -> Self {
-        let mut nodes = World::default();
-        let node = Node {
-            parent: None,
-            children: Vec::new(),
-            height: 0,
-        };
-        let root = nodes.add_entity((node,));
-        Self { nodes, root }
-    }
+pub trait TreeMut: TreeRef {
+    fn remove(&mut self, id: NodeId);
+    fn remove_single(&mut self, id: NodeId);
+    fn set_height(&mut self, node: NodeId, height: u16);
+    fn create_node(&mut self, id: NodeId);
+    fn add_child(&mut self, parent: NodeId, new: NodeId);
+    fn replace(&mut self, old_id: NodeId, new_id: NodeId);
+    fn insert_before(&mut self, old_id: NodeId, new_id: NodeId);
+    fn insert_after(&mut self, old_id: NodeId, new_id: NodeId);
+}
 
-    pub fn add_unique<T: Unique + Send + Sync>(&mut self, data: T) {
-        self.nodes.add_unique(data);
+impl<'a> TreeRef for TreeRefView<'a> {
+    fn parent_id(&self, id: NodeId) -> Option<NodeId> {
+        self.get(id).unwrap().parent
     }
 
-    pub fn remove_unique<T: Unique + Send + Sync>(
-        &mut self,
-    ) -> Result<T, shipyard::error::UniqueRemove> {
-        self.nodes.remove_unique::<T>()
+    fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
+        Some(self.get(id).unwrap().children.clone())
     }
 
-    fn node_data(&self) -> View<Node> {
-        self.nodes.borrow().unwrap()
+    fn height(&self, id: NodeId) -> Option<u16> {
+        Some(self.get(id).unwrap().height)
     }
 
-    fn node_data_mut(&self) -> ViewMut<Node> {
-        self.nodes.borrow().unwrap()
+    fn contains(&self, id: NodeId) -> bool {
+        self.get(id).is_ok()
     }
+}
 
-    pub fn remove(&mut self, id: NodeId) {
-        fn recurse(tree: &mut Tree, id: NodeId) {
+impl<'a> TreeMut for TreeMutView<'a> {
+    fn remove(&mut self, id: NodeId) {
+        fn recurse<'a>(tree: &mut TreeMutView<'a>, id: NodeId) {
             let children = tree.children_ids(id);
             if let Some(children) = children {
                 for child in children {
                     recurse(tree, child);
                 }
             }
-
-            tree.nodes.delete_entity(id);
         }
         {
-            let mut node_data_mut = self.node_data_mut();
+            let mut node_data_mut = &mut self.1;
             if let Some(parent) = node_data_mut.get(id).unwrap().parent {
                 let parent = (&mut node_data_mut).get(parent).unwrap();
                 parent.children.retain(|&child| child != id);
@@ -67,21 +69,19 @@ impl Tree {
         recurse(self, id);
     }
 
-    pub fn remove_single(&mut self, id: NodeId) {
+    fn remove_single(&mut self, id: NodeId) {
         {
-            let mut node_data_mut = self.node_data_mut();
+            let mut node_data_mut = &mut self.1;
             if let Some(parent) = node_data_mut.get(id).unwrap().parent {
                 let parent = (&mut node_data_mut).get(parent).unwrap();
                 parent.children.retain(|&child| child != id);
             }
         }
-
-        self.nodes.delete_entity(id);
     }
 
     fn set_height(&mut self, node: NodeId, height: u16) {
         let children = {
-            let mut node_data_mut = self.node_data_mut();
+            let mut node_data_mut = &mut self.1;
             let mut node = (&mut node_data_mut).get(node).unwrap();
             node.height = height;
             node.children.clone()
@@ -91,19 +91,23 @@ impl Tree {
         }
     }
 
-    pub fn create_node(&mut self) -> NodeBuilder<'_> {
-        let node = self.nodes.add_entity((Node {
-            parent: None,
-            children: Vec::new(),
-            height: 0,
-        },));
-        NodeBuilder { tree: self, node }
+    fn create_node(&mut self, id: NodeId) {
+        let (entities, node_data_mut) = self;
+        entities.add_component(
+            id,
+            node_data_mut,
+            Node {
+                parent: None,
+                children: Vec::new(),
+                height: 0,
+            },
+        );
     }
 
-    pub fn add_child(&mut self, parent: NodeId, new: NodeId) {
+    fn add_child(&mut self, parent: NodeId, new: NodeId) {
         let height;
         {
-            let mut node_state = self.node_data_mut();
+            let mut node_state = &mut self.1;
             (&mut node_state).get(new).unwrap().parent = Some(parent);
             let parent = (&mut node_state).get(parent).unwrap();
             parent.children.push(new);
@@ -112,9 +116,9 @@ impl Tree {
         self.set_height(new, height);
     }
 
-    pub fn replace(&mut self, old_id: NodeId, new_id: NodeId) {
+    fn replace(&mut self, old_id: NodeId, new_id: NodeId) {
         {
-            let mut node_state = self.node_data_mut();
+            let mut node_state = &mut self.1;
             // update the parent's link to the child
             if let Some(parent_id) = node_state.get(old_id).unwrap().parent {
                 let parent = (&mut node_state).get(parent_id).unwrap();
@@ -125,7 +129,6 @@ impl Tree {
                     }
                 }
                 let height = parent.height + 1;
-                drop(node_state);
                 self.set_height(new_id, height);
             }
         }
@@ -133,8 +136,8 @@ impl Tree {
         self.remove(old_id);
     }
 
-    pub fn insert_before(&mut self, old_id: NodeId, new_id: NodeId) {
-        let mut node_state = self.node_data_mut();
+    fn insert_before(&mut self, old_id: NodeId, new_id: NodeId) {
+        let mut node_state = &mut self.1;
         let old_node = node_state.get(old_id).unwrap();
         let parent_id = old_node.parent.expect("tried to insert before root");
         (&mut node_state).get(new_id).unwrap().parent = Some(parent_id);
@@ -146,12 +149,11 @@ impl Tree {
             .unwrap();
         parent.children.insert(index, new_id);
         let height = parent.height + 1;
-        drop(node_state);
         self.set_height(new_id, height);
     }
 
-    pub fn insert_after(&mut self, old_id: NodeId, new_id: NodeId) {
-        let mut node_state = self.node_data_mut();
+    fn insert_after(&mut self, old_id: NodeId, new_id: NodeId) {
+        let mut node_state = &mut self.1;
         let old_node = node_state.get(old_id).unwrap();
         let parent_id = old_node.parent.expect("tried to insert before root");
         (&mut node_state).get(new_id).unwrap().parent = Some(parent_id);
@@ -163,36 +165,29 @@ impl Tree {
             .unwrap();
         parent.children.insert(index + 1, new_id);
         let height = parent.height + 1;
-        drop(node_state);
         self.set_height(new_id, height);
     }
+}
 
-    pub fn insert<T: Component + Sync + Send>(&mut self, id: NodeId, value: T) {
-        self.nodes.add_component(id, value);
-    }
-
-    pub fn contains(&self, id: NodeId) -> bool {
-        self.nodes.borrow::<EntitiesView>().unwrap().is_alive(id)
-    }
-
-    pub fn root(&self) -> NodeId {
-        self.root
-    }
-
-    pub fn parent_id(&self, id: NodeId) -> Option<NodeId> {
-        let node_data = self.node_data();
+impl<'a> TreeRef for TreeMutView<'a> {
+    fn parent_id(&self, id: NodeId) -> Option<NodeId> {
+        let node_data = &self.1;
         node_data.get(id).unwrap().parent
     }
 
-    pub fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
-        let node_data = self.node_data();
+    fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
+        let node_data = &self.1;
         node_data.get(id).map(|node| node.children.clone()).ok()
     }
 
-    pub fn height(&self, id: NodeId) -> Option<u16> {
-        let node_data = self.node_data();
+    fn height(&self, id: NodeId) -> Option<u16> {
+        let node_data = &self.1;
         node_data.get(id).map(|node| node.height).ok()
     }
+
+    fn contains(&self, id: NodeId) -> bool {
+        self.1.get(id).is_ok()
+    }
 }
 
 #[test]
@@ -326,18 +321,3 @@ fn deletion() {
     assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
     assert_eq!(tree.get::<i32>(after), None);
 }
-
-pub struct NodeBuilder<'a> {
-    tree: &'a mut Tree,
-    node: EntityId,
-}
-
-impl<'a> NodeBuilder<'a> {
-    pub fn insert<T: Component + Send + Sync>(&mut self, component: T) {
-        self.tree.insert(self.node, component);
-    }
-
-    pub fn id(&self) -> EntityId {
-        self.node
-    }
-}