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
11pub trait HierarchyMut {
13 fn attach<T: Component>(&mut self, child: Entity, parent: Entity) -> Result<Entity>;
17
18 fn attach_new<T: Component, C: DynamicBundle>(
21 &mut self,
22 parent: Entity,
23 components: C,
24 ) -> Result<Entity>;
25
26 fn detach_all<T: Component>(&mut self, entity: Entity) -> Result<()>;
29
30 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 fn detach<T: Component>(&mut self, child: Entity) -> Result<()>;
38
39 fn despawn_all<T: Component>(&mut self, parent: Entity);
42}
43
44pub trait Hierarchy
46where
47 Self: Sized,
48{
49 fn parent<T: Component>(&self, child: Entity) -> Result<Entity>;
51
52 fn root<T: Component>(&self, child: Entity) -> Result<Entity>;
53
54 fn children<T: Component>(&self, parent: Entity) -> ChildrenIter<T>;
57
58 fn ancestors<T: Component>(&self, child: Entity) -> AncestorIter<T>;
60
61 fn descendants_depth_first<T: Component>(&self, root: Entity) -> DepthFirstIterator<T>;
63
64 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 fn descendants_breadth_first<T: Component>(
73 &self,
74 root: Entity,
75 ) -> BreadthFirstIterator<Self, T>;
76
77 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 {
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 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 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 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 let _ = self.detach::<T>(parent);
191
192 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 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 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
282pub type HierarchyQuery<'a, T> = (&'a Parent<T>, &'a Child<T>);