@@ -5,16 +5,54 @@ use bevy_ecs::{
5
5
query:: { QueryData , QueryFilter , WorldQuery } ,
6
6
system:: Query ,
7
7
} ;
8
+ use smallvec:: SmallVec ;
8
9
9
10
use crate :: { Children , Parent } ;
10
11
11
12
/// An extension trait for [`Query`] that adds hierarchy related methods.
12
13
pub trait HierarchyQueryExt < ' w , ' s , D : QueryData , F : QueryFilter > {
14
+ /// Returns the parent [`Entity`] of the given `entity`, if any.
15
+ fn parent ( & ' w self , entity : Entity ) -> Option < Entity >
16
+ where
17
+ D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Parent > ;
18
+
19
+ /// Returns a slice over the [`Children`] of the given `entity`.
20
+ ///
21
+ /// This may be empty if the `entity` has no children.
22
+ fn children ( & ' w self , entity : Entity ) -> & ' w [ Entity ]
23
+ where
24
+ D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ;
25
+
26
+ /// Returns the topmost ancestor of the given `entity`.
27
+ ///
28
+ /// This may be the entity itself if it has no parent.
29
+ fn root_ancestor ( & ' w self , entity : Entity ) -> Entity
30
+ where
31
+ D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Parent > ;
32
+
33
+ /// Returns an [`Iterator`] of [`Entity`]s over the leaves of the hierarchy that are underneath this `entity`.
34
+ ///
35
+ /// Only entities which have no children are considered leaves.
36
+ /// This will not include the entity itself, and will not include any entities which are not descendants of the entity,
37
+ /// even if they are leaves in the same hierarchical tree.
38
+ ///
39
+ /// Traverses the hierarchy depth-first.
40
+ fn iter_leaves ( & ' w self , entity : Entity ) -> impl Iterator < Item = Entity > + ' w
41
+ where
42
+ D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ;
43
+
44
+ /// Returns an [`Iterator`] of [`Entity`]s over the `entity`s immediate siblings, who share the same parent.
45
+ ///
46
+ /// The entity itself is not included in the iterator.
47
+ 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
+
13
51
/// Returns an [`Iterator`] of [`Entity`]s over all of `entity`s descendants.
14
52
///
15
53
/// Can only be called on a [`Query`] of [`Children`] (i.e. `Query<&Children>`).
16
54
///
17
- /// Traverses the hierarchy breadth-first.
55
+ /// Traverses the hierarchy breadth-first and does not include the entity itself .
18
56
///
19
57
/// # Examples
20
58
/// ```
@@ -34,8 +72,21 @@ pub trait HierarchyQueryExt<'w, 's, D: QueryData, F: QueryFilter> {
34
72
where
35
73
D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ;
36
74
75
+ /// Returns an [`Iterator`] of [`Entity`]s over all of `entity`s descendants.
76
+ ///
77
+ /// Can only be called on a [`Query`] of [`Children`] (i.e. `Query<&Children>`).
78
+ ///
79
+ /// This is a depth-first alternative to [`HierarchyQueryExt::iter_descendants`].
80
+ fn iter_descendants_depth_first (
81
+ & ' w self ,
82
+ entity : Entity ,
83
+ ) -> DescendantDepthFirstIter < ' w , ' s , D , F >
84
+ where
85
+ D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ;
86
+
37
87
/// Returns an [`Iterator`] of [`Entity`]s over all of `entity`s ancestors.
38
88
///
89
+ /// Does not include the entity itself.
39
90
/// Can only be called on a [`Query`] of [`Parent`] (i.e. `Query<&Parent>`).
40
91
///
41
92
/// # Examples
@@ -58,13 +109,76 @@ pub trait HierarchyQueryExt<'w, 's, D: QueryData, F: QueryFilter> {
58
109
}
59
110
60
111
impl < ' w , ' s , D : QueryData , F : QueryFilter > HierarchyQueryExt < ' w , ' s , D , F > for Query < ' w , ' s , D , F > {
112
+ fn parent ( & ' w self , entity : Entity ) -> Option < Entity >
113
+ where
114
+ <D as QueryData >:: ReadOnly : WorldQuery < Item < ' w > = & ' w Parent > ,
115
+ {
116
+ self . get ( entity) . map ( Parent :: get) . ok ( )
117
+ }
118
+
119
+ fn children ( & ' w self , entity : Entity ) -> & ' w [ Entity ]
120
+ where
121
+ <D as QueryData >:: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ,
122
+ {
123
+ self . get ( entity)
124
+ . map_or ( & [ ] as & [ Entity ] , |children| children)
125
+ }
126
+
127
+ fn root_ancestor ( & ' w self , entity : Entity ) -> Entity
128
+ where
129
+ <D as QueryData >:: ReadOnly : WorldQuery < Item < ' w > = & ' w Parent > ,
130
+ {
131
+ // Recursively search up the tree until we're out of parents
132
+ match self . get ( entity) {
133
+ Ok ( parent) => self . root_ancestor ( parent. get ( ) ) ,
134
+ Err ( _) => entity,
135
+ }
136
+ }
137
+
138
+ fn iter_leaves ( & ' w self , entity : Entity ) -> impl Iterator < Item = Entity >
139
+ where
140
+ <D as QueryData >:: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ,
141
+ {
142
+ self . iter_descendants_depth_first ( entity) . filter ( |entity| {
143
+ self . get ( * entity)
144
+ // These are leaf nodes if they have the `Children` component but it's empty
145
+ . map ( |children| children. is_empty ( ) )
146
+ // Or if they don't have the `Children` component at all
147
+ . unwrap_or ( true )
148
+ } )
149
+ }
150
+
151
+ fn iter_siblings ( & ' w self , entity : Entity ) -> impl Iterator < Item = Entity >
152
+ where
153
+ D :: ReadOnly : WorldQuery < Item < ' w > = ( Option < & ' w Parent > , Option < & ' w Children > ) > ,
154
+ {
155
+ self . get ( entity)
156
+ . ok ( )
157
+ . and_then ( |( maybe_parent, _) | maybe_parent. map ( Parent :: get) )
158
+ . and_then ( |parent| self . get ( parent) . ok ( ) )
159
+ . and_then ( |( _, maybe_children) | maybe_children)
160
+ . into_iter ( )
161
+ . flat_map ( move |children| children. iter ( ) . filter ( move |child| * * child != entity) )
162
+ . copied ( )
163
+ }
164
+
61
165
fn iter_descendants ( & ' w self , entity : Entity ) -> DescendantIter < ' w , ' s , D , F >
62
166
where
63
167
D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ,
64
168
{
65
169
DescendantIter :: new ( self , entity)
66
170
}
67
171
172
+ fn iter_descendants_depth_first (
173
+ & ' w self ,
174
+ entity : Entity ,
175
+ ) -> DescendantDepthFirstIter < ' w , ' s , D , F >
176
+ where
177
+ D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ,
178
+ {
179
+ DescendantDepthFirstIter :: new ( self , entity)
180
+ }
181
+
68
182
fn iter_ancestors ( & ' w self , entity : Entity ) -> AncestorIter < ' w , ' s , D , F >
69
183
where
70
184
D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Parent > ,
@@ -119,6 +233,51 @@ where
119
233
}
120
234
}
121
235
236
+ /// An [`Iterator`] of [`Entity`]s over the descendants of an [`Entity`].
237
+ ///
238
+ /// Traverses the hierarchy depth-first.
239
+ pub struct DescendantDepthFirstIter < ' w , ' s , D : QueryData , F : QueryFilter >
240
+ where
241
+ D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ,
242
+ {
243
+ children_query : & ' w Query < ' w , ' s , D , F > ,
244
+ stack : SmallVec < [ Entity ; 8 ] > ,
245
+ }
246
+
247
+ impl < ' w , ' s , D : QueryData , F : QueryFilter > DescendantDepthFirstIter < ' w , ' s , D , F >
248
+ where
249
+ D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ,
250
+ {
251
+ /// Returns a new [`DescendantDepthFirstIter`].
252
+ pub fn new ( children_query : & ' w Query < ' w , ' s , D , F > , entity : Entity ) -> Self {
253
+ DescendantDepthFirstIter {
254
+ children_query,
255
+ stack : children_query
256
+ . get ( entity)
257
+ . map_or ( SmallVec :: new ( ) , |children| {
258
+ children. iter ( ) . rev ( ) . copied ( ) . collect ( )
259
+ } ) ,
260
+ }
261
+ }
262
+ }
263
+
264
+ impl < ' w , ' s , D : QueryData , F : QueryFilter > Iterator for DescendantDepthFirstIter < ' w , ' s , D , F >
265
+ where
266
+ D :: ReadOnly : WorldQuery < Item < ' w > = & ' w Children > ,
267
+ {
268
+ type Item = Entity ;
269
+
270
+ fn next ( & mut self ) -> Option < Self :: Item > {
271
+ let entity = self . stack . pop ( ) ?;
272
+
273
+ if let Ok ( children) = self . children_query . get ( entity) {
274
+ self . stack . extend ( children. iter ( ) . rev ( ) . copied ( ) ) ;
275
+ }
276
+
277
+ Some ( entity)
278
+ }
279
+ }
280
+
122
281
/// An [`Iterator`] of [`Entity`]s over the ancestors of an [`Entity`].
123
282
pub struct AncestorIter < ' w , ' s , D : QueryData , F : QueryFilter >
124
283
where
@@ -170,35 +329,108 @@ mod tests {
170
329
fn descendant_iter ( ) {
171
330
let world = & mut World :: new ( ) ;
172
331
173
- let [ a , b , c , d ] = core:: array:: from_fn ( |i| world. spawn ( A ( i) ) . id ( ) ) ;
332
+ let [ a0 , a1 , a2 , a3 ] = core:: array:: from_fn ( |i| world. spawn ( A ( i) ) . id ( ) ) ;
174
333
175
- world. entity_mut ( a ) . add_children ( & [ b , c ] ) ;
176
- world. entity_mut ( c ) . add_children ( & [ d ] ) ;
334
+ world. entity_mut ( a0 ) . add_children ( & [ a1 , a2 ] ) ;
335
+ world. entity_mut ( a1 ) . add_children ( & [ a3 ] ) ;
177
336
178
337
let mut system_state = SystemState :: < ( Query < & Children > , Query < & A > ) > :: new ( world) ;
179
338
let ( children_query, a_query) = system_state. get ( world) ;
180
339
181
340
let result: Vec < _ > = a_query
182
- . iter_many ( children_query. iter_descendants ( a ) )
341
+ . iter_many ( children_query. iter_descendants ( a0 ) )
183
342
. collect ( ) ;
184
343
185
344
assert_eq ! ( [ & A ( 1 ) , & A ( 2 ) , & A ( 3 ) ] , result. as_slice( ) ) ;
186
345
}
187
346
347
+ #[ test]
348
+ fn descendant_depth_first_iter ( ) {
349
+ let world = & mut World :: new ( ) ;
350
+
351
+ let [ a0, a1, a2, a3] = core:: array:: from_fn ( |i| world. spawn ( A ( i) ) . id ( ) ) ;
352
+
353
+ world. entity_mut ( a0) . add_children ( & [ a1, a2] ) ;
354
+ world. entity_mut ( a1) . add_children ( & [ a3] ) ;
355
+
356
+ let mut system_state = SystemState :: < ( Query < & Children > , Query < & A > ) > :: new ( world) ;
357
+ let ( children_query, a_query) = system_state. get ( world) ;
358
+
359
+ let result: Vec < _ > = a_query
360
+ . iter_many ( children_query. iter_descendants_depth_first ( a0) )
361
+ . collect ( ) ;
362
+
363
+ assert_eq ! ( [ & A ( 1 ) , & A ( 3 ) , & A ( 2 ) ] , result. as_slice( ) ) ;
364
+ }
365
+
188
366
#[ test]
189
367
fn ancestor_iter ( ) {
190
368
let world = & mut World :: new ( ) ;
191
369
192
- let [ a , b , c ] = core:: array:: from_fn ( |i| world. spawn ( A ( i) ) . id ( ) ) ;
370
+ let [ a0 , a1 , a2 ] = core:: array:: from_fn ( |i| world. spawn ( A ( i) ) . id ( ) ) ;
193
371
194
- world. entity_mut ( a ) . add_children ( & [ b ] ) ;
195
- world. entity_mut ( b ) . add_children ( & [ c ] ) ;
372
+ world. entity_mut ( a0 ) . add_children ( & [ a1 ] ) ;
373
+ world. entity_mut ( a1 ) . add_children ( & [ a2 ] ) ;
196
374
197
375
let mut system_state = SystemState :: < ( Query < & Parent > , Query < & A > ) > :: new ( world) ;
198
376
let ( parent_query, a_query) = system_state. get ( world) ;
199
377
200
- let result: Vec < _ > = a_query. iter_many ( parent_query. iter_ancestors ( c ) ) . collect ( ) ;
378
+ let result: Vec < _ > = a_query. iter_many ( parent_query. iter_ancestors ( a2 ) ) . collect ( ) ;
201
379
202
380
assert_eq ! ( [ & A ( 1 ) , & A ( 0 ) ] , result. as_slice( ) ) ;
203
381
}
382
+
383
+ #[ test]
384
+ fn root_ancestor ( ) {
385
+ let world = & mut World :: new ( ) ;
386
+
387
+ let [ a0, a1, a2] = core:: array:: from_fn ( |i| world. spawn ( A ( i) ) . id ( ) ) ;
388
+
389
+ world. entity_mut ( a0) . add_children ( & [ a1] ) ;
390
+ world. entity_mut ( a1) . add_children ( & [ a2] ) ;
391
+
392
+ let mut system_state = SystemState :: < Query < & Parent > > :: new ( world) ;
393
+ let parent_query = system_state. get ( world) ;
394
+
395
+ assert_eq ! ( a0, parent_query. root_ancestor( a2) ) ;
396
+ assert_eq ! ( a0, parent_query. root_ancestor( a1) ) ;
397
+ assert_eq ! ( a0, parent_query. root_ancestor( a0) ) ;
398
+ }
399
+
400
+ #[ test]
401
+ fn leaf_iter ( ) {
402
+ let world = & mut World :: new ( ) ;
403
+
404
+ let [ a0, a1, a2, a3] = core:: array:: from_fn ( |i| world. spawn ( A ( i) ) . id ( ) ) ;
405
+
406
+ world. entity_mut ( a0) . add_children ( & [ a1, a2] ) ;
407
+ world. entity_mut ( a1) . add_children ( & [ a3] ) ;
408
+
409
+ let mut system_state = SystemState :: < ( Query < & Children > , Query < & A > ) > :: new ( world) ;
410
+ let ( children_query, a_query) = system_state. get ( world) ;
411
+
412
+ let result: Vec < _ > = a_query. iter_many ( children_query. iter_leaves ( a0) ) . collect ( ) ;
413
+
414
+ assert_eq ! ( [ & A ( 3 ) , & A ( 2 ) ] , result. as_slice( ) ) ;
415
+ }
416
+
417
+ #[ test]
418
+ fn siblings ( ) {
419
+ let world = & mut World :: new ( ) ;
420
+
421
+ let [ a0, a1, a2, a3, a4] = core:: array:: from_fn ( |i| world. spawn ( A ( i) ) . id ( ) ) ;
422
+
423
+ world. entity_mut ( a0) . add_children ( & [ a1, a2, a3] ) ;
424
+ world. entity_mut ( a2) . add_children ( & [ a4] ) ;
425
+
426
+ let mut system_state =
427
+ SystemState :: < ( Query < ( Option < & Parent > , Option < & Children > ) > , Query < & A > ) > :: new ( world) ;
428
+ let ( hierarchy_query, a_query) = system_state. get ( world) ;
429
+
430
+ let result: Vec < _ > = a_query
431
+ . iter_many ( hierarchy_query. iter_siblings ( a1) )
432
+ . collect ( ) ;
433
+
434
+ assert_eq ! ( [ & A ( 2 ) , & A ( 3 ) ] , result. as_slice( ) ) ;
435
+ }
204
436
}
0 commit comments