Skip to content

Commit b4296fa

Browse files
committed
add depth to iter_related
1 parent cbd7099 commit b4296fa

File tree

1 file changed

+45
-10
lines changed

1 file changed

+45
-10
lines changed

crates/bevy_hierarchy/src/query_extension.rs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ where
109109
C: Component + IterEntities,
110110
{
111111
related_query: &'w Query<'w, 's, D, F>,
112-
vecdeque: VecDeque<Entity>,
112+
vecdeque: VecDeque<(usize, Entity)>,
113113
}
114114

115115
impl<'w, 's, C, D, F> RelatedIter<'w, 's, C, D, F>
@@ -120,16 +120,32 @@ where
120120
C: Component + IterEntities,
121121
{
122122
/// Create a new [`RelatedIter`].
123-
pub fn new(related_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
123+
fn new(related_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self {
124124
RelatedIter {
125125
related_query,
126126
vecdeque: related_query
127127
.get(entity)
128-
.iter()
128+
.into_iter()
129129
.flat_map(|t| t.iter_entities())
130+
.map(|e| (1, e))
130131
.collect(),
131132
}
132133
}
134+
135+
fn next(&mut self) -> Option<(usize, Entity)> {
136+
let (depth, entity) = self.vecdeque.pop_front()?;
137+
138+
if let Ok(children) = self.related_query.get(entity) {
139+
self.vecdeque
140+
.extend(children.iter_entities().map(|e| (depth + 1, e)));
141+
}
142+
143+
Some((depth, entity))
144+
}
145+
146+
pub fn with_depth(self) -> RelatedDepthIter<'w, 's, C, D, F> {
147+
RelatedDepthIter(self)
148+
}
133149
}
134150

135151
impl<'w, 's, C, D, F> Iterator for RelatedIter<'w, 's, C, D, F>
@@ -142,13 +158,28 @@ where
142158
type Item = Entity;
143159

144160
fn next(&mut self) -> Option<Self::Item> {
145-
let entity = self.vecdeque.pop_front()?;
161+
RelatedIter::next(self).map(|(_, e)| e)
162+
}
163+
}
146164

147-
if let Ok(children) = self.related_query.get(entity) {
148-
self.vecdeque.extend(children.iter_entities());
149-
}
165+
pub struct RelatedDepthIter<'w, 's, C, D, F>(RelatedIter<'w, 's, C, D, F>)
166+
where
167+
D: QueryData,
168+
F: QueryFilter,
169+
D::ReadOnly: WorldQuery<Item<'w> = &'w C>,
170+
C: Component + IterEntities;
150171

151-
Some(entity)
172+
impl<'w, 's, C, D, F> Iterator for RelatedDepthIter<'w, 's, C, D, F>
173+
where
174+
D: QueryData,
175+
F: QueryFilter,
176+
D::ReadOnly: WorldQuery<Item<'w> = &'w C>,
177+
C: Component + IterEntities,
178+
{
179+
type Item = (usize, Entity);
180+
181+
fn next(&mut self) -> Option<Self::Item> {
182+
RelatedIter::next(&mut self.0)
152183
}
153184
}
154185

@@ -213,9 +244,13 @@ mod tests {
213244
let mut system_state = SystemState::<(Query<&Children>, Query<&A>)>::new(world);
214245
let (children_query, a_query) = system_state.get(world);
215246

216-
let result: Vec<_> = a_query.iter_many(children_query.iter_related(a)).collect();
247+
let result: Vec<_> = children_query
248+
.iter_related(a)
249+
.with_depth()
250+
.filter_map(|(d, e)| Some((d, a_query.get(e).ok()?)))
251+
.collect();
217252

218-
assert_eq!([&A(1), &A(2), &A(3)], result.as_slice());
253+
assert_eq!([(1, &A(1)), (1, &A(2)), (2, &A(3))], result.as_slice());
219254
}
220255

221256
#[test]

0 commit comments

Comments
 (0)