From 63a291c6a800a12e8beb3dbad8f64927380493ca Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 17 Jan 2023 17:54:53 +0000 Subject: [PATCH] add tests for change detection and conditions for stageless (#7249) # Objective - add some tests for how change detection and run criteria interact in stageless --- crates/bevy_ecs/src/schedule_v3/mod.rs | 151 +++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/crates/bevy_ecs/src/schedule_v3/mod.rs b/crates/bevy_ecs/src/schedule_v3/mod.rs index 6a95e28e4a..11828cbbe5 100644 --- a/crates/bevy_ecs/src/schedule_v3/mod.rs +++ b/crates/bevy_ecs/src/schedule_v3/mod.rs @@ -197,6 +197,8 @@ mod tests { } mod conditions { + use crate::change_detection::DetectChanges; + use super::*; #[test] @@ -294,6 +296,155 @@ mod tests { schedule.run(&mut world); assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); } + + #[test] + fn system_conditions_and_change_detection() { + #[derive(Resource, Default)] + struct Bool2(pub bool); + + let mut world = World::default(); + world.init_resource::(); + world.init_resource::(); + world.init_resource::(); + let mut schedule = Schedule::default(); + + schedule.add_system( + counting_system + .run_if(|res1: Res| res1.is_changed()) + .run_if(|res2: Res| res2.is_changed()), + ); + + // both resource were just added. + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // nothing has changed + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // RunConditionBool has changed, but counting_system did not run + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // internal state for the bool2 run criteria was updated in the + // previous run, so system still does not run + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // internal state for bool2 was updated, so system still does not run + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // now check that it works correctly changing Bool2 first and then RunConditionBool + world.get_resource_mut::().unwrap().0 = false; + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 2); + } + + #[test] + fn system_set_conditions_and_change_detection() { + #[derive(Resource, Default)] + struct Bool2(pub bool); + + let mut world = World::default(); + world.init_resource::(); + world.init_resource::(); + world.init_resource::(); + let mut schedule = Schedule::default(); + + schedule.configure_set( + TestSet::A + .run_if(|res1: Res| res1.is_changed()) + .run_if(|res2: Res| res2.is_changed()), + ); + + schedule.add_system(counting_system.in_set(TestSet::A)); + + // both resource were just added. + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // nothing has changed + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // RunConditionBool has changed, but counting_system did not run + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // internal state for the bool2 run criteria was updated in the + // previous run, so system still does not run + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // internal state for bool2 was updated, so system still does not run + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // the system only runs when both are changed on the same run + world.get_resource_mut::().unwrap().0 = false; + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 2); + } + + #[test] + fn mixed_conditions_and_change_detection() { + #[derive(Resource, Default)] + struct Bool2(pub bool); + + let mut world = World::default(); + world.init_resource::(); + world.init_resource::(); + world.init_resource::(); + let mut schedule = Schedule::default(); + + schedule + .configure_set(TestSet::A.run_if(|res1: Res| res1.is_changed())); + + schedule.add_system( + counting_system + .run_if(|res2: Res| res2.is_changed()) + .in_set(TestSet::A), + ); + + // both resource were just added. + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // nothing has changed + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // RunConditionBool has changed, but counting_system did not run + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // we now only change bool2 and the system also should not run + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // internal state for the bool2 run criteria was updated in the + // previous run, so system still does not run + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 1); + + // the system only runs when both are changed on the same run + world.get_resource_mut::().unwrap().0 = false; + world.get_resource_mut::().unwrap().0 = false; + schedule.run(&mut world); + assert_eq!(world.resource::().0.load(Ordering::Relaxed), 2); + } } mod schedule_build_errors {