Skip to content

Commit 7efa59b

Browse files
committed
Reduce allocations by re-using vecs
1 parent 9246295 commit 7efa59b

File tree

1 file changed

+54
-30
lines changed

1 file changed

+54
-30
lines changed

src/plugin/systems.rs

+54-30
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,35 @@ pub fn apply_scale(
132132
}
133133
}
134134

135+
fn find_child_colliders(
136+
base_entity: Entity,
137+
colliders: &Query<&Collider>,
138+
rigid_bodies: &Query<&RigidBody>,
139+
childrens: &Query<&Children>,
140+
141+
found: &mut Vec<Entity>,
142+
possibilities: &mut Vec<Entity>,
143+
) {
144+
found.clear();
145+
possibilities.clear();
146+
possibilities.push(base_entity);
147+
while let Some(entity) = possibilities.pop() {
148+
if rigid_bodies.contains(entity) {
149+
continue;
150+
}
151+
152+
if colliders.contains(entity) {
153+
found.push(entity);
154+
}
155+
156+
if let Ok(children) = childrens.get(entity) {
157+
possibilities.extend(children.iter());
158+
} else {
159+
continue;
160+
};
161+
}
162+
}
163+
135164
/// System responsible for detecting changes in the hierarchy that would
136165
/// affect the collider's parent rigid body.
137166
pub fn collect_collider_hierarchy_changes(
@@ -143,29 +172,10 @@ pub fn collect_collider_hierarchy_changes(
143172
rigid_bodies: Query<&RigidBody>,
144173
colliders: Query<&Collider>,
145174
mut collider_parents: Query<&mut ColliderParent>,
146-
) {
147-
let child_colliders = |entity: Entity| -> Vec<Entity> {
148-
let mut found = Vec::new();
149-
let mut possibilities = vec![entity];
150-
while let Some(entity) = possibilities.pop() {
151-
if rigid_bodies.contains(entity) {
152-
continue;
153-
}
154-
155-
if colliders.contains(entity) {
156-
found.push(entity);
157-
}
158-
159-
if let Ok(children) = childrens.get(entity) {
160-
possibilities.extend(children.iter());
161-
} else {
162-
continue;
163-
};
164-
}
165-
166-
found
167-
};
168175

176+
mut found: Local<Vec<Entity>>,
177+
mut possibilities: Local<Vec<Entity>>,
178+
) {
169179
let parent_rigid_body = |mut entity: Entity| -> Option<Entity> {
170180
loop {
171181
if rigid_bodies.contains(entity) {
@@ -183,25 +193,39 @@ pub fn collect_collider_hierarchy_changes(
183193
for event in hierarchy_events.iter() {
184194
match event {
185195
HierarchyEvent::ChildAdded { child, .. } | HierarchyEvent::ChildMoved { child, .. } => {
186-
let colliders = child_colliders(*child);
187196
let Some(rigid_body) = parent_rigid_body(*child) else {
188197
continue;
189198
};
199+
find_child_colliders(
200+
*child,
201+
&colliders,
202+
&rigid_bodies,
203+
&childrens,
204+
&mut found,
205+
&mut possibilities,
206+
);
190207

191-
for collider in colliders {
208+
for collider in &found {
192209
let new_collider_parent = ColliderParent(rigid_body);
193-
if let Ok(mut collider_parent) = collider_parents.get_mut(collider) {
210+
if let Ok(mut collider_parent) = collider_parents.get_mut(*collider) {
194211
*collider_parent = new_collider_parent;
195212
} else {
196-
commands.entity(collider).insert(new_collider_parent);
213+
commands.entity(*collider).insert(new_collider_parent);
197214
}
198215
}
199216
}
200217
HierarchyEvent::ChildRemoved { child, .. } => {
201-
let colliders = child_colliders(*child);
202-
for collider in colliders {
203-
if collider_parents.contains(collider) {
204-
commands.entity(collider).remove::<ColliderParent>();
218+
find_child_colliders(
219+
*child,
220+
&colliders,
221+
&rigid_bodies,
222+
&childrens,
223+
&mut found,
224+
&mut possibilities,
225+
);
226+
for collider in &found {
227+
if collider_parents.contains(*collider) {
228+
commands.entity(*collider).remove::<ColliderParent>();
205229
}
206230
}
207231
}

0 commit comments

Comments
 (0)