Преглед изворни кода

implement removing subtrees

Evan Almloff пре 2 година
родитељ
комит
32945998c3
1 измењених фајлова са 64 додато и 1 уклоњено
  1. 64 1
      packages/native-core/src/tree.rs

+ 64 - 1
packages/native-core/src/tree.rs

@@ -61,6 +61,8 @@ pub trait TreeMut: TreeRef {
     fn insert_after(&mut self, old_id: NodeId, new_id: NodeId);
     /// Creates a new subtree.
     fn create_subtree(&mut self, id: NodeId, shadow_roots: Vec<NodeId>, slot: Option<NodeId>);
+    /// Remove any subtree.
+    fn remove_subtree(&mut self, id: NodeId);
 }
 
 impl<'a> TreeRef for TreeRefView<'a> {
@@ -236,6 +238,36 @@ impl<'a> TreeMut for TreeMutView<'a> {
             set_height(self, root, light_root_height + 1);
         }
     }
+
+    fn remove_subtree(&mut self, id: NodeId) {
+        let (_, node_data_mut) = self;
+
+        if let Ok(node) = node_data_mut.get(id) {
+            if let Some(subtree) = node.child_subtree.take() {
+                // Remove the slot's link to the subtree
+                if let Some(slot) = subtree.slot {
+                    let slot = node_data_mut
+                        .get(slot)
+                        .expect("tried to remove subtree with non-existent slot");
+                    slot.slot_for_supertree = None;
+                }
+
+                let node = node_data_mut.get(id).unwrap();
+
+                // Reset the height of the light root's children
+                let height = node.height;
+                for child in node.children.clone() {
+                    println!("child: {:?}", child);
+                    set_height(self, child, height + 1);
+                }
+
+                // Reset the height of the shadow roots
+                for root in &subtree.shadow_roots {
+                    set_height(self, *root, 0);
+                }
+            }
+        }
+    }
 }
 
 fn child_height(parent: &Node, tree: &impl TreeRef) -> u16 {
@@ -343,7 +375,7 @@ fn creation() {
 }
 
 #[test]
-fn subtree_creation() {
+fn subtree() {
     use shipyard::World;
     #[derive(Component)]
     struct Num(i32);
@@ -369,6 +401,7 @@ fn subtree_creation() {
 
     tree.add_child(shadow_parent_id, shadow_child_id);
 
+    // Check that both trees are correct individually
     assert_eq!(tree.height(parent_id), Some(0));
     assert_eq!(tree.height(child_id), Some(1));
     assert_eq!(tree.parent_id(parent_id), None);
@@ -388,6 +421,36 @@ fn subtree_creation() {
     assert_eq!(tree.height(shadow_parent_id), Some(1));
     assert_eq!(tree.height(shadow_child_id), Some(2));
     assert_eq!(tree.height(child_id), Some(3));
+    assert_eq!(
+        tree.1
+            .get(parent_id)
+            .unwrap()
+            .child_subtree
+            .as_ref()
+            .unwrap()
+            .shadow_roots,
+        &[shadow_parent_id]
+    );
+    assert_eq!(
+        tree.1.get(shadow_child_id).unwrap().slot_for_supertree,
+        Some(parent_id)
+    );
+
+    // Remove shadow tree from main tree
+    tree.remove_subtree(parent_id);
+
+    // Check that both trees are correct individually
+    assert_eq!(tree.height(parent_id), Some(0));
+    assert_eq!(tree.height(child_id), Some(1));
+    assert_eq!(tree.parent_id(parent_id), None);
+    assert_eq!(tree.parent_id(child_id).unwrap(), parent_id);
+    assert_eq!(tree.children_ids(parent_id), &[child_id]);
+
+    assert_eq!(tree.height(shadow_parent_id), Some(0));
+    assert_eq!(tree.height(shadow_child_id), Some(1));
+    assert_eq!(tree.parent_id(shadow_parent_id), None);
+    assert_eq!(tree.parent_id(shadow_child_id).unwrap(), shadow_parent_id);
+    assert_eq!(tree.children_ids(shadow_parent_id), &[shadow_child_id]);
 }
 
 #[test]