hecs_hierarchy/
hierarchy.rs

1use std::mem;
2
3use hecs::{Component, DynamicBundle, Entity, QueryBorrow, Without, World};
4use hecs_schedule::{error::Result, GenericWorld};
5
6use crate::{
7    AncestorIter, BreadthFirstIterator, Child, ChildrenIter, DepthFirstIterator, DepthFirstVisitor,
8    Parent,
9};
10
11/// A trait for modifying the worlds hierarchy. Implemented for `hecs::World`>
12pub trait HierarchyMut {
13    /// Attach `child` to `parent`. Parent does not require an existing `Parent component`. Returns
14    /// the passed child.
15    /// *Note*: The entity needs to be explicitly detached before being removed.
16    fn attach<T: Component>(&mut self, child: Entity, parent: Entity) -> Result<Entity>;
17
18    /// Attach a new entity with specified components to `parent`. Parent does not require an existing `Parent component`. Returns
19    /// the passed child.
20    fn attach_new<T: Component, C: DynamicBundle>(
21        &mut self,
22        parent: Entity,
23        components: C,
24    ) -> Result<Entity>;
25
26    /// Detaches all children from entity and detaches entity from parent. Use this before removing
27    /// entities to ensure no loose entity ids.
28    fn detach_all<T: Component>(&mut self, entity: Entity) -> Result<()>;
29
30    /// Detaches all children of parent.
31    fn detach_children<T: Component>(&mut self, parent: Entity) -> Result<Vec<Entity>>;
32    fn despawn_children<T: Component>(&mut self, parent: Entity) -> Result<()>;
33
34    /// Detach the child from tree `T`. The children of `child` will not remain in hierachy, but will
35    /// remain attached to `child`, which means a later attach also will attach the children of `child`
36    /// into the hierarchy. Essentially moving the subtree.
37    fn detach<T: Component>(&mut self, child: Entity) -> Result<()>;
38
39    /// Despawn parent and all children recursively. Essentially despawns a whole subtree including
40    /// root. Does not fail if there are invalid, dangling IDs in tree.
41    fn despawn_all<T: Component>(&mut self, parent: Entity);
42}
43
44/// Non mutating part of hierarchy
45pub trait Hierarchy
46where
47    Self: Sized,
48{
49    /// Returns the parent entity of child.
50    fn parent<T: Component>(&self, child: Entity) -> Result<Entity>;
51
52    fn root<T: Component>(&self, child: Entity) -> Result<Entity>;
53
54    /// Traverses the immediate children of parent. If parent is not a Parent, an empty iterator is
55    /// returned.
56    fn children<T: Component>(&self, parent: Entity) -> ChildrenIter<T>;
57
58    /// Traverse the tree upwards. Iterator does not include the child itself.
59    fn ancestors<T: Component>(&self, child: Entity) -> AncestorIter<T>;
60
61    /// Traverse the tree depth first. Iterator does not include the child itself.
62    fn descendants_depth_first<T: Component>(&self, root: Entity) -> DepthFirstIterator<T>;
63
64    /// Traverse the tree depth first with an acceptance function
65    fn visit<T: Component, F: Fn(&Self, Entity) -> bool + Component>(
66        &self,
67        root: Entity,
68        accept: F,
69    ) -> DepthFirstVisitor<Self, T, F>;
70
71    /// Traverse the tree breadth first. Iterator does not include the child itself.
72    fn descendants_breadth_first<T: Component>(
73        &self,
74        root: Entity,
75    ) -> BreadthFirstIterator<Self, T>;
76
77    /// Returns an iterator over all root objects in the world
78    fn roots<T: Component>(&self) -> Result<QueryBorrow<Without<&Parent<T>, &Child<T>>>>;
79}
80
81impl HierarchyMut for World {
82    fn attach<T: Component>(&mut self, child: Entity, parent: Entity) -> Result<Entity> {
83        let mut maybe_p = self.try_get_mut::<Parent<T>>(parent);
84        if let Ok(ref mut p) = maybe_p {
85            p.num_children += 1;
86            let prev = p.last_child;
87            p.last_child = child;
88
89            if p.num_children == 1 {
90                mem::drop(maybe_p);
91                self.try_insert(child, (Child::<T>::new(parent, child, child),))?;
92            } else {
93                let mut prev_data = self.try_get_mut::<Child<T>>(prev)?;
94                let next = prev_data.next;
95                prev_data.next = child;
96
97                mem::drop(prev_data);
98                mem::drop(maybe_p);
99
100                // Update backward linking
101                {
102                    let mut next_data = self.try_get_mut::<Child<T>>(next)?;
103                    next_data.prev = child;
104                }
105
106                self.try_insert(child, (Child::<T>::new(parent, next, prev),))?;
107            }
108
109            return Ok(child);
110        }
111
112        mem::drop(maybe_p);
113
114        // Parent component didn't exist
115        self.try_insert(parent, (Parent::<T>::new(1, child),))?;
116
117        self.try_insert(child, (Child::<T>::new(parent, child, child),))?;
118
119        Ok(child)
120    }
121
122    fn attach_new<T: Component, C: DynamicBundle>(
123        &mut self,
124        parent: Entity,
125        components: C,
126    ) -> Result<Entity> {
127        let child = self.spawn(components);
128        self.attach::<T>(child, parent)
129    }
130
131    fn detach_all<T: Component>(&mut self, entity: Entity) -> Result<()> {
132        self.detach_children::<T>(entity)?;
133        self.detach::<T>(entity)?;
134        Ok(())
135    }
136
137    /// Detaches all children of parent.
138    fn detach_children<T: Component>(&mut self, parent: Entity) -> Result<Vec<Entity>> {
139        let children = self.children::<T>(parent).collect::<Vec<Entity>>();
140
141        children.iter().try_for_each(|child| -> Result<_> {
142            self.try_remove_one::<Child<T>>(*child)?;
143            Ok(())
144        })?;
145
146        self.remove_one::<Parent<T>>(parent).unwrap();
147
148        Ok(children)
149    }
150
151    /// Detaches all children of parent.
152    fn despawn_children<T: Component>(&mut self, parent: Entity) -> Result<()> {
153        let children = self.children::<T>(parent).collect::<Vec<Entity>>();
154
155        children
156            .iter()
157            .for_each(|child| self.despawn_all::<Child<T>>(*child));
158
159        self.remove_one::<Parent<T>>(parent).unwrap();
160
161        Ok(())
162    }
163
164    fn detach<T: Component>(&mut self, child: Entity) -> Result<()> {
165        let data = self.try_get_mut::<Child<T>>(child)?;
166        let parent = data.parent;
167        let prev = data.prev;
168        let next = data.next;
169
170        mem::drop(data);
171
172        self.try_get_mut::<Child<T>>(prev)?.next = next;
173        self.try_get_mut::<Child<T>>(next)?.prev = prev;
174
175        let mut parent = self.try_get_mut::<Parent<T>>(parent)?;
176        parent.num_children -= 1;
177        if parent.last_child == child {
178            parent.last_child = prev;
179        }
180
181        Ok(())
182    }
183
184    fn despawn_all<T: Component>(&mut self, parent: Entity) {
185        let to_despawn = self
186            .descendants_depth_first::<T>(parent)
187            .collect::<Vec<_>>();
188
189        // Detach from parent if necessary
190        let _ = self.detach::<T>(parent);
191
192        // Should not panic since we just
193        to_despawn.iter().for_each(|entity| {
194            let _ = self.despawn(*entity);
195        });
196
197        let _ = self.despawn(parent);
198    }
199}
200
201impl<W: GenericWorld> Hierarchy for W {
202    fn parent<T: Component>(&self, child: Entity) -> Result<Entity> {
203        self.try_get::<Child<T>>(child).map(|child| child.parent)
204    }
205
206    fn root<T: Component>(&self, child: Entity) -> Result<Entity> {
207        let mut cur = child;
208        loop {
209            match self.parent::<T>(cur) {
210                Ok(val) => cur = val,
211                Err(hecs_schedule::Error::MissingComponent(_, _)) => break,
212                Err(val) => return Err(val),
213            }
214        }
215
216        Ok(cur)
217    }
218
219    fn children<T: Component>(&self, parent: Entity) -> ChildrenIter<T> {
220        self.try_get::<Parent<T>>(parent)
221            .and_then(|parent| {
222                let first_child = parent.first_child(self)?;
223
224                Ok(ChildrenIter::new(
225                    self,
226                    parent.num_children,
227                    Some(first_child),
228                ))
229            })
230            .unwrap_or_else(move |_| {
231                // Return an iterator that does nothing.
232                ChildrenIter::new(self, 0, None)
233            })
234    }
235
236    fn ancestors<T: Component>(&self, child: Entity) -> AncestorIter<T> {
237        AncestorIter::new(self, child)
238    }
239
240    fn descendants_depth_first<T: Component>(&self, root: Entity) -> DepthFirstIterator<T> {
241        DepthFirstIterator::new(self, root)
242    }
243
244    /// Traverse the tree breadth first. Iterator does not include the child itself.
245    fn descendants_breadth_first<T: Component>(
246        &self,
247        root: Entity,
248    ) -> BreadthFirstIterator<Self, T> {
249        BreadthFirstIterator::new(self, root)
250    }
251
252    fn visit<T: Component, F: Fn(&Self, Entity) -> bool + Component>(
253        &self,
254        root: Entity,
255        accept: F,
256    ) -> DepthFirstVisitor<Self, T, F> {
257        DepthFirstVisitor::new(self, root, accept)
258    }
259
260    fn roots<T: Component>(&self) -> Result<QueryBorrow<Without<&Parent<T>, &Child<T>>>> {
261        Ok(self.try_query::<&Parent<T>>()?.without::<&Child<T>>())
262    }
263}
264
265trait WorldExt {
266    fn try_insert(&mut self, e: Entity, c: impl DynamicBundle) -> Result<()>;
267    fn try_remove_one<C: Component>(&mut self, e: Entity) -> Result<C>;
268}
269
270impl WorldExt for World {
271    fn try_insert(&mut self, e: Entity, c: impl DynamicBundle) -> Result<()> {
272        self.insert(e, c)
273            .map_err(|_| hecs_schedule::Error::NoSuchEntity(e))
274    }
275
276    fn try_remove_one<C: Component>(&mut self, e: Entity) -> Result<C> {
277        self.remove_one::<C>(e)
278            .map_err(|_| hecs_schedule::Error::NoSuchEntity(e))
279    }
280}
281
282/// A query for defininig a compatible subworld for [Hierarchy]
283pub type HierarchyQuery<'a, T> = (&'a Parent<T>, &'a Child<T>);