Skip to content

Commit 60afdf7

Browse files
committed
Reworked access patterns.
1 parent 30af92b commit 60afdf7

File tree

1 file changed

+19
-30
lines changed

1 file changed

+19
-30
lines changed

crates/bevy_hierarchy/src/recursive.rs

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ impl<
9393
/// If hierarchy is malformed, for example if a parent child mismatch or a cycle is found.
9494
pub fn for_each(
9595
&self,
96-
root_fn: impl FnMut(&ReadItem<QShared>, ReadItem<QRoot>),
97-
mut child_fn: impl FnMut(&ReadItem<QShared>, ReadItem<QShared>, ReadItem<QChild>),
96+
root_fn: impl FnMut(&ReadItem<QShared>, &ReadItem<QRoot>),
97+
mut child_fn: impl FnMut(&ReadItem<QShared>, &ReadItem<QShared>, &ReadItem<QChild>),
9898
) {
9999
self.for_each_with(root_fn, |a, _, b, c| child_fn(a, b, c));
100100
}
@@ -107,8 +107,8 @@ impl<
107107
/// If hierarchy is malformed, for example if a parent child mismatch or a cycle is found.
108108
pub fn for_each_mut(
109109
&mut self,
110-
root_fn: impl FnMut(Item<QShared>, Item<QRoot>),
111-
mut child_fn: impl FnMut(&ReadItem<QShared>, Item<QShared>, Item<QChild>),
110+
root_fn: impl FnMut(&mut Item<QShared>, &mut Item<QRoot>),
111+
mut child_fn: impl FnMut(&Item<QShared>, &mut Item<QShared>, &mut Item<QChild>),
112112
) {
113113
self.for_each_mut_with(root_fn, |a, _, b, c| child_fn(a, b, c));
114114
}
@@ -122,11 +122,11 @@ impl<
122122
#[allow(unsafe_code)]
123123
pub fn for_each_with<T: 'static>(
124124
&self,
125-
mut root_fn: impl FnMut(&ReadItem<QShared>, ReadItem<QRoot>) -> T,
126-
mut child_fn: impl FnMut(&ReadItem<QShared>, &T, ReadItem<QShared>, ReadItem<QChild>) -> T,
125+
mut root_fn: impl FnMut(&ReadItem<QShared>, &ReadItem<QRoot>) -> T,
126+
mut child_fn: impl FnMut(&ReadItem<QShared>, &T, &ReadItem<QShared>, &ReadItem<QChild>) -> T,
127127
) {
128128
for (shared, owned, children) in self.root.iter() {
129-
let info = root_fn(&shared, owned);
129+
let info = root_fn(&shared, &owned);
130130
let Some(children) = children else {
131131
continue;
132132
};
@@ -140,7 +140,7 @@ impl<
140140
&self.children.to_readonly(),
141141
&self.parent,
142142
*entity,
143-
&mut child_fn,
143+
|a, b, c, d| child_fn(a, b, c, d),
144144
);
145145
};
146146
}
@@ -156,15 +156,11 @@ impl<
156156
#[allow(unsafe_code)]
157157
pub fn for_each_mut_with<T: 'static>(
158158
&mut self,
159-
mut root_fn: impl FnMut(Item<QShared>, Item<QRoot>) -> T,
160-
mut child_fn: impl FnMut(&ReadItem<QShared>, &T, Item<QShared>, Item<QChild>) -> T,
159+
mut root_fn: impl FnMut(&mut Item<QShared>, &mut Item<QRoot>) -> T,
160+
mut child_fn: impl FnMut(&Item<QShared>, &T, &mut Item<QShared>, &mut Item<QChild>) -> T,
161161
) {
162-
let infos: Vec<_> = self
163-
.root
164-
.iter_mut()
165-
.map(|(shared, root, _)| root_fn(shared, root))
166-
.collect();
167-
for ((shared, _, children), info) in self.root.iter().zip(infos) {
162+
for (mut shared, mut root, children) in self.root.iter_mut() {
163+
let info = root_fn(&mut shared, &mut root);
168164
let Some(children) = children else {
169165
continue;
170166
};
@@ -206,12 +202,12 @@ unsafe fn propagate<
206202
Info: 'static,
207203
>(
208204
actual_root: Entity,
209-
parent: &ReadItem<QShared>,
205+
parent: &Item<QShared>,
210206
parent_info: &Info,
211207
main_query: &Query<(QShared, QMain, Option<&'static Children>), (Filter, With<Parent>)>,
212208
parent_query: &Query<(Entity, &Parent)>,
213209
entity: Entity,
214-
mut function: impl FnMut(&ReadItem<QShared>, &Info, Item<QShared>, Item<QMain>) -> Info,
210+
mut function: impl FnMut(&Item<QShared>, &Info, &mut Item<QShared>, &mut Item<QMain>) -> Info,
215211
) {
216212
// SAFETY: This call cannot create aliased mutable references.
217213
// - The top level iteration parallelizes on the roots of the hierarchy.
@@ -239,20 +235,13 @@ unsafe fn propagate<
239235
//
240236
// Even if these A and B start two separate tasks running in parallel, one of them will panic before attempting
241237
// to mutably access E.
242-
let info = {
243-
let Ok((shared, owned, _)) =
244-
// Safety: see above.
245-
(unsafe { main_query.get_unchecked(entity) }) else {
246-
return;
247-
};
248-
249-
function(parent, parent_info, shared, owned)
250-
};
251-
252-
let Ok((shared, _, children)) = main_query.get(entity) else {
238+
let Ok((mut shared, mut owned, children)) = (unsafe { main_query.get_unchecked(entity) })
239+
else {
253240
return;
254241
};
255242

243+
let info = function(parent, parent_info, &mut shared, &mut owned);
244+
256245
let Some(children) = children else { return };
257246
for (child, actual_parent) in parent_query.iter_many(children) {
258247
// Check if entities are chained properly.
@@ -264,7 +253,7 @@ unsafe fn propagate<
264253
// This was not needed in `propagate_transform` since the root node did not have parents.
265254
assert_ne!(
266255
actual_root, entity,
267-
"Malformed hierarchy. Your hierarchy contains a cycle"
256+
"Malformed hierarchy. The hierarchy contains a cycle"
268257
);
269258
// SAFETY: The caller guarantees that `main_query` will not be fetched
270259
// for any descendants of `entity`, so it is safe to call `propagate_recursive` for each child.

0 commit comments

Comments
 (0)