1use alloc::collections::VecDeque;
2
3use bevy_ecs::{
4 entity::Entity,
5 query::{QueryData, QueryFilter, WorldQuery},
6 system::Query,
7};
8use smallvec::SmallVec;
9
10use crate::{Children, Parent};
11
12pub trait HierarchyQueryExt<'w, 's, D: QueryData, F: QueryFilter> {
14 fn parent(&'w self, entity: Entity) -> Option<Entity>
16 where
17 D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>;
18
19 fn children(&'w self, entity: Entity) -> &'w [Entity]
23 where
24 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>;
25
26 fn root_ancestor(&'w self, entity: Entity) -> Entity
30 where
31 D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>;
32
33 fn iter_leaves(&'w self, entity: Entity) -> impl Iterator<Item = Entity> + 'w
41 where
42 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>;
43
44 fn iter_siblings(&'w self, entity: Entity) -> impl Iterator<Item = Entity>
48 where
49 D::ReadOnly: WorldQuery<Item<'w> = (Option<&'w Parent>, Option<&'w Children>)>;
50
51 fn iter_descendants(&'w self, entity: Entity) -> DescendantIter<'w, 's, D, F>
71 where
72 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>;
73
74 fn iter_descendants_depth_first(
80 &'w self,
81 entity: Entity,
82 ) -> DescendantDepthFirstIter<'w, 's, D, F>
83 where
84 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>;
85
86 fn iter_ancestors(&'w self, entity: Entity) -> AncestorIter<'w, 's, D, F>
105 where
106 D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>;
107}
108
109impl<'w, 's, D: QueryData, F: QueryFilter> HierarchyQueryExt<'w, 's, D, F> for Query<'w, 's, D, F> {
110 fn parent(&'w self, entity: Entity) -> Option<Entity>
111 where
112 <D as QueryData>::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
113 {
114 self.get(entity).map(Parent::get).ok()
115 }
116
117 fn children(&'w self, entity: Entity) -> &'w [Entity]
118 where
119 <D as QueryData>::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
120 {
121 self.get(entity)
122 .map_or(&[] as &[Entity], |children| children)
123 }
124
125 fn root_ancestor(&'w self, entity: Entity) -> Entity
126 where
127 <D as QueryData>::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
128 {
129 match self.get(entity) {
131 Ok(parent) => self.root_ancestor(parent.get()),
132 Err(_) => entity,
133 }
134 }
135
136 fn iter_leaves(&'w self, entity: Entity) -> impl Iterator<Item = Entity>
137 where
138 <D as QueryData>::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
139 {
140 self.iter_descendants_depth_first(entity).filter(|entity| {
141 self.get(*entity)
142 .map(|children| children.is_empty())
144 .unwrap_or(true)
146 })
147 }
148
149 fn iter_siblings(&'w self, entity: Entity) -> impl Iterator<Item = Entity>
150 where
151 D::ReadOnly: WorldQuery<Item<'w> = (Option<&'w Parent>, Option<&'w Children>)>,
152 {
153 self.get(entity)
154 .ok()
155 .and_then(|(maybe_parent, _)| maybe_parent.map(Parent::get))
156 .and_then(|parent| self.get(parent).ok())
157 .and_then(|(_, maybe_children)| maybe_children)
158 .into_iter()
159 .flat_map(move |children| children.iter().filter(move |child| **child != entity))
160 .copied()
161 }
162
163 fn iter_descendants(&'w self, entity: Entity) -> DescendantIter<'w, 's, D, F>
164 where
165 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
166 {
167 DescendantIter::new(self, entity)
168 }
169
170 fn iter_descendants_depth_first(
171 &'w self,
172 entity: Entity,
173 ) -> DescendantDepthFirstIter<'w, 's, D, F>
174 where
175 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
176 {
177 DescendantDepthFirstIter::new(self, entity)
178 }
179
180 fn iter_ancestors(&'w self, entity: Entity) -> AncestorIter<'w, 's, D, F>
181 where
182 D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
183 {
184 AncestorIter::new(self, entity)
185 }
186}
187
188pub struct DescendantIter<'w, 's, D: QueryData, F: QueryFilter>
192where
193 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
194{
195 children_query: &'w Query<'w, 's, D, F>,
196 vecdeque: VecDeque<Entity>,
197}
198
199impl<'w, 's, D: QueryData, F: QueryFilter> DescendantIter<'w, 's, D, F>
200where
201 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
202{
203 pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
205 DescendantIter {
206 children_query,
207 vecdeque: children_query
208 .get(entity)
209 .into_iter()
210 .flatten()
211 .copied()
212 .collect(),
213 }
214 }
215}
216
217impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for DescendantIter<'w, 's, D, F>
218where
219 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
220{
221 type Item = Entity;
222
223 fn next(&mut self) -> Option<Self::Item> {
224 let entity = self.vecdeque.pop_front()?;
225
226 if let Ok(children) = self.children_query.get(entity) {
227 self.vecdeque.extend(children);
228 }
229
230 Some(entity)
231 }
232}
233
234pub struct DescendantDepthFirstIter<'w, 's, D: QueryData, F: QueryFilter>
238where
239 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
240{
241 children_query: &'w Query<'w, 's, D, F>,
242 stack: SmallVec<[Entity; 8]>,
243}
244
245impl<'w, 's, D: QueryData, F: QueryFilter> DescendantDepthFirstIter<'w, 's, D, F>
246where
247 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
248{
249 pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
251 DescendantDepthFirstIter {
252 children_query,
253 stack: children_query
254 .get(entity)
255 .map_or(SmallVec::new(), |children| {
256 children.iter().rev().copied().collect()
257 }),
258 }
259 }
260}
261
262impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for DescendantDepthFirstIter<'w, 's, D, F>
263where
264 D::ReadOnly: WorldQuery<Item<'w> = &'w Children>,
265{
266 type Item = Entity;
267
268 fn next(&mut self) -> Option<Self::Item> {
269 let entity = self.stack.pop()?;
270
271 if let Ok(children) = self.children_query.get(entity) {
272 self.stack.extend(children.iter().rev().copied());
273 }
274
275 Some(entity)
276 }
277}
278
279pub struct AncestorIter<'w, 's, D: QueryData, F: QueryFilter>
281where
282 D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
283{
284 parent_query: &'w Query<'w, 's, D, F>,
285 next: Option<Entity>,
286}
287
288impl<'w, 's, D: QueryData, F: QueryFilter> AncestorIter<'w, 's, D, F>
289where
290 D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
291{
292 pub fn new(parent_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
294 AncestorIter {
295 parent_query,
296 next: Some(entity),
297 }
298 }
299}
300
301impl<'w, 's, D: QueryData, F: QueryFilter> Iterator for AncestorIter<'w, 's, D, F>
302where
303 D::ReadOnly: WorldQuery<Item<'w> = &'w Parent>,
304{
305 type Item = Entity;
306
307 fn next(&mut self) -> Option<Self::Item> {
308 self.next = self.parent_query.get(self.next?).ok().map(Parent::get);
309 self.next
310 }
311}
312
313#[cfg(test)]
314mod tests {
315 use bevy_ecs::{
316 prelude::Component,
317 system::{Query, SystemState},
318 world::World,
319 };
320
321 use crate::{query_extension::HierarchyQueryExt, BuildChildren, Children, Parent};
322
323 #[derive(Component, PartialEq, Debug)]
324 struct A(usize);
325
326 #[test]
327 fn descendant_iter() {
328 let world = &mut World::new();
329
330 let [a0, a1, a2, a3] = core::array::from_fn(|i| world.spawn(A(i)).id());
331
332 world.entity_mut(a0).add_children(&[a1, a2]);
333 world.entity_mut(a1).add_children(&[a3]);
334
335 let mut system_state = SystemState::<(Query<&Children>, Query<&A>)>::new(world);
336 let (children_query, a_query) = system_state.get(world);
337
338 let result: Vec<_> = a_query
339 .iter_many(children_query.iter_descendants(a0))
340 .collect();
341
342 assert_eq!([&A(1), &A(2), &A(3)], result.as_slice());
343 }
344
345 #[test]
346 fn descendant_depth_first_iter() {
347 let world = &mut World::new();
348
349 let [a0, a1, a2, a3] = core::array::from_fn(|i| world.spawn(A(i)).id());
350
351 world.entity_mut(a0).add_children(&[a1, a2]);
352 world.entity_mut(a1).add_children(&[a3]);
353
354 let mut system_state = SystemState::<(Query<&Children>, Query<&A>)>::new(world);
355 let (children_query, a_query) = system_state.get(world);
356
357 let result: Vec<_> = a_query
358 .iter_many(children_query.iter_descendants_depth_first(a0))
359 .collect();
360
361 assert_eq!([&A(1), &A(3), &A(2)], result.as_slice());
362 }
363
364 #[test]
365 fn ancestor_iter() {
366 let world = &mut World::new();
367
368 let [a0, a1, a2] = core::array::from_fn(|i| world.spawn(A(i)).id());
369
370 world.entity_mut(a0).add_children(&[a1]);
371 world.entity_mut(a1).add_children(&[a2]);
372
373 let mut system_state = SystemState::<(Query<&Parent>, Query<&A>)>::new(world);
374 let (parent_query, a_query) = system_state.get(world);
375
376 let result: Vec<_> = a_query.iter_many(parent_query.iter_ancestors(a2)).collect();
377
378 assert_eq!([&A(1), &A(0)], result.as_slice());
379 }
380
381 #[test]
382 fn root_ancestor() {
383 let world = &mut World::new();
384
385 let [a0, a1, a2] = core::array::from_fn(|i| world.spawn(A(i)).id());
386
387 world.entity_mut(a0).add_children(&[a1]);
388 world.entity_mut(a1).add_children(&[a2]);
389
390 let mut system_state = SystemState::<Query<&Parent>>::new(world);
391 let parent_query = system_state.get(world);
392
393 assert_eq!(a0, parent_query.root_ancestor(a2));
394 assert_eq!(a0, parent_query.root_ancestor(a1));
395 assert_eq!(a0, parent_query.root_ancestor(a0));
396 }
397
398 #[test]
399 fn leaf_iter() {
400 let world = &mut World::new();
401
402 let [a0, a1, a2, a3] = core::array::from_fn(|i| world.spawn(A(i)).id());
403
404 world.entity_mut(a0).add_children(&[a1, a2]);
405 world.entity_mut(a1).add_children(&[a3]);
406
407 let mut system_state = SystemState::<(Query<&Children>, Query<&A>)>::new(world);
408 let (children_query, a_query) = system_state.get(world);
409
410 let result: Vec<_> = a_query.iter_many(children_query.iter_leaves(a0)).collect();
411
412 assert_eq!([&A(3), &A(2)], result.as_slice());
413 }
414
415 #[test]
416 fn siblings() {
417 let world = &mut World::new();
418
419 let [a0, a1, a2, a3, a4] = core::array::from_fn(|i| world.spawn(A(i)).id());
420
421 world.entity_mut(a0).add_children(&[a1, a2, a3]);
422 world.entity_mut(a2).add_children(&[a4]);
423
424 let mut system_state =
425 SystemState::<(Query<(Option<&Parent>, Option<&Children>)>, Query<&A>)>::new(world);
426 let (hierarchy_query, a_query) = system_state.get(world);
427
428 let result: Vec<_> = a_query
429 .iter_many(hierarchy_query.iter_siblings(a1))
430 .collect();
431
432 assert_eq!([&A(2), &A(3)], result.as_slice());
433 }
434}