Skip to content

Commit

Permalink
Pass query change ticks to QueryParIter instead of always using cha…
Browse files Browse the repository at this point in the history
…nge ticks from `World`. (bevyengine#8029)

Co-authored-by: Chris Russell <[email protected]>
Co-authored-by: James Liu <[email protected]>
  • Loading branch information
3 people authored and Shfty committed Mar 19, 2023
1 parent e29d4c5 commit f984f1f
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 10 deletions.
32 changes: 31 additions & 1 deletion crates/bevy_ecs/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@ impl<T> DebugCheckedUnwrap for Option<T> {
#[cfg(test)]
mod tests {
use super::{ReadOnlyWorldQuery, WorldQuery};
use crate::prelude::{AnyOf, Entity, Or, QueryState, With, Without};
use crate::prelude::{AnyOf, Changed, Entity, Or, QueryState, With, Without};
use crate::query::{ArchetypeFilter, QueryCombinationIter};
use crate::schedule::{IntoSystemConfigs, Schedule};
use crate::system::{IntoSystem, Query, System, SystemState};
use crate::{self as bevy_ecs, component::Component, world::World};
use std::any::type_name;
Expand Down Expand Up @@ -749,4 +750,33 @@ mod tests {
let _: [&Foo; 1] = q.many([e]);
let _: &Foo = q.single();
}

// regression test for https://github.com/bevyengine/bevy/pull/8029
#[test]
fn par_iter_mut_change_detection() {
let mut world = World::new();
world.spawn((A(1), B(1)));

fn propagate_system(mut query: Query<(&A, &mut B), Changed<A>>) {
query.par_iter_mut().for_each_mut(|(a, mut b)| {
b.0 = a.0;
});
}

fn modify_system(mut query: Query<&mut A>) {
for mut a in &mut query {
a.0 = 2;
}
}

let mut schedule = Schedule::new();
schedule.add_systems((propagate_system, modify_system).chain());
schedule.run(&mut world);
world.clear_trackers();
schedule.run(&mut world);
world.clear_trackers();

let values = world.query::<&B>().iter(&world).collect::<Vec<&B>>();
assert_eq!(values, vec![&B(2)]);
}
}
16 changes: 7 additions & 9 deletions crates/bevy_ecs/src/query/par_iter.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::world::World;
use crate::{component::Tick, world::World};
use bevy_tasks::ComputeTaskPool;
use std::ops::Range;

Expand Down Expand Up @@ -81,6 +81,8 @@ impl BatchingStrategy {
pub struct QueryParIter<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> {
pub(crate) world: &'w World,
pub(crate) state: &'s QueryState<Q, F>,
pub(crate) last_run: Tick,
pub(crate) this_run: Tick,
pub(crate) batching_strategy: BatchingStrategy,
}

Expand Down Expand Up @@ -148,21 +150,17 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> QueryParIter<'w, 's, Q, F> {
) {
let thread_count = ComputeTaskPool::get().thread_num();
if thread_count <= 1 {
self.state.for_each_unchecked_manual(
self.world,
func,
self.world.last_change_tick(),
self.world.read_change_tick(),
);
self.state
.for_each_unchecked_manual(self.world, func, self.last_run, self.this_run);
} else {
// Need a batch size of at least 1.
let batch_size = self.get_batch_size(thread_count).max(1);
self.state.par_for_each_unchecked_manual(
self.world,
batch_size,
func,
self.world.last_change_tick(),
self.world.read_change_tick(),
self.last_run,
self.this_run,
);
}
}
Expand Down
5 changes: 5 additions & 0 deletions crates/bevy_ecs/src/query/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,8 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
QueryParIter {
world,
state: self,
last_run: world.last_change_tick(),
this_run: world.read_change_tick(),
batching_strategy: BatchingStrategy::new(),
}
}
Expand All @@ -832,9 +834,12 @@ impl<Q: WorldQuery, F: ReadOnlyWorldQuery> QueryState<Q, F> {
#[inline]
pub fn par_iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryParIter<'w, 's, Q, F> {
self.update_archetypes(world);
let this_run = world.change_tick();
QueryParIter {
world,
state: self,
last_run: world.last_change_tick(),
this_run,
batching_strategy: BatchingStrategy::new(),
}
}
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_ecs/src/system/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,8 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> {
QueryParIter {
world: self.world,
state: self.state.as_readonly(),
last_run: self.last_run,
this_run: self.this_run,
batching_strategy: BatchingStrategy::new(),
}
}
Expand All @@ -742,6 +744,8 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> {
QueryParIter {
world: self.world,
state: self.state,
last_run: self.last_run,
this_run: self.this_run,
batching_strategy: BatchingStrategy::new(),
}
}
Expand Down

0 comments on commit f984f1f

Please sign in to comment.