From 1126949807fc8a403604744ece9e3be929c43494 Mon Sep 17 00:00:00 2001 From: urben1680 <55257931+urben1680@users.noreply.github.com> Date: Mon, 26 May 2025 21:28:56 +0200 Subject: [PATCH] No schedule build pass overwrite if build settings do not change `auto_insert_apply_deferred` from `true` (#19217) # Objective Fixes #18790. Simpler alternative to #19195. ## Solution As suggested by @PixelDust22, simply avoid overwriting the pass if the schedule already has auto sync points enabled. Leave pass logic untouched. It still is probably a bad idea to add systems/set configs before changing the build settings, but that is not important as long there are no more complex build passes. ## Testing Added a test. --------- Co-authored-by: Thierry Berger --- crates/bevy_ecs/src/schedule/schedule.rs | 54 +++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/schedule/schedule.rs b/crates/bevy_ecs/src/schedule/schedule.rs index 584e621bf8..8015bde6c1 100644 --- a/crates/bevy_ecs/src/schedule/schedule.rs +++ b/crates/bevy_ecs/src/schedule/schedule.rs @@ -394,9 +394,21 @@ impl Schedule { } /// Changes miscellaneous build settings. + /// + /// If [`settings.auto_insert_apply_deferred`][ScheduleBuildSettings::auto_insert_apply_deferred] + /// is `false`, this clears `*_ignore_deferred` edge settings configured so far. + /// + /// Generally this method should be used before adding systems or set configurations to the schedule, + /// not after. pub fn set_build_settings(&mut self, settings: ScheduleBuildSettings) -> &mut Self { if settings.auto_insert_apply_deferred { - self.add_build_pass(passes::AutoInsertApplyDeferredPass::default()); + if !self + .graph + .passes + .contains_key(&TypeId::of::()) + { + self.add_build_pass(passes::AutoInsertApplyDeferredPass::default()); + } } else { self.remove_build_pass::(); } @@ -2076,6 +2088,46 @@ mod tests { #[derive(Resource)] struct Resource2; + #[test] + fn unchanged_auto_insert_apply_deferred_has_no_effect() { + use alloc::{vec, vec::Vec}; + + #[derive(PartialEq, Debug)] + enum Entry { + System(usize), + SyncPoint(usize), + } + + #[derive(Resource, Default)] + struct Log(Vec); + + fn system(mut res: ResMut, mut commands: Commands) { + res.0.push(Entry::System(N)); + commands + .queue(|world: &mut World| world.resource_mut::().0.push(Entry::SyncPoint(N))); + } + + let mut world = World::default(); + world.init_resource::(); + let mut schedule = Schedule::default(); + schedule.add_systems((system::<1>, system::<2>).chain_ignore_deferred()); + schedule.set_build_settings(ScheduleBuildSettings { + auto_insert_apply_deferred: true, + ..Default::default() + }); + schedule.run(&mut world); + let actual = world.remove_resource::().unwrap().0; + + let expected = vec![ + Entry::System(1), + Entry::System(2), + Entry::SyncPoint(1), + Entry::SyncPoint(2), + ]; + + assert_eq!(actual, expected); + } + // regression test for https://github.com/bevyengine/bevy/issues/9114 #[test] fn ambiguous_with_not_breaking_run_conditions() {