mirror of
https://github.com/bevyengine/bevy.git
synced 2026-05-06 06:06:42 -04:00
Change the ambiguity_detection test to be more strict. (#23846)
# Objective - Fixes #23843 by preventing these systems from recurring inside Bevy. - Note this does not fix this for users of Bevy. They would need to setup their own "strict" checking. ## Solution - Disable `auto_insert_apply_deferred` in the `ambiguity_detection` example. Now these stages won't accidentally resolve these ambiguities, so they will be detected! - Stop running the app in `ambiguity_detection` and just manually initialize the schedules. - We have to do this otherwise the schedules just panic because they depend on various resource initializations to be executed by commands (which were previously being applied by the automatically inserted `apply_deferred`). ### Caveats: - The ambiguity_detection CI test now won't detect ambiguities in runtime-added systems. - This is not a pattern we use today, and I'd encourage us to **delete** systems instead so that tooling can grab the systems before the app runs. - To clarify, this is **not** ambiguity detection in general - just Bevy's CI test that is affected. ## Testing - Ran the examples and all the ambiguities have been fixed in previous PRs.
This commit is contained in:
@@ -35,17 +35,21 @@ fn main() {
|
||||
let sub_app = app.sub_app_mut(bevy_render::RenderApp);
|
||||
configure_ambiguity_detection(sub_app);
|
||||
|
||||
// Make sure all the system stuff is added.
|
||||
app.finish();
|
||||
app.cleanup();
|
||||
app.update();
|
||||
|
||||
let main_app_ambiguities = count_ambiguities(app.main());
|
||||
let main_app_ambiguities = count_ambiguities(app.main_mut());
|
||||
assert_eq!(
|
||||
main_app_ambiguities.total(),
|
||||
0,
|
||||
"Main app has unexpected ambiguities among the following schedules: \n{main_app_ambiguities:#?}.",
|
||||
);
|
||||
let render_app_ambiguities = count_ambiguities(app.sub_app(bevy_render::RenderApp));
|
||||
|
||||
let render_app = app.sub_app_mut(bevy_render::RenderApp);
|
||||
// Initialize the MainWorld so the render world systems don't fail initialization.
|
||||
render_app.init_resource::<bevy_render::MainWorld>();
|
||||
let render_app_ambiguities = count_ambiguities(render_app);
|
||||
assert_eq!(
|
||||
render_app_ambiguities.total(),
|
||||
0,
|
||||
@@ -69,6 +73,14 @@ fn configure_ambiguity_detection(sub_app: &mut SubApp) {
|
||||
schedule.set_build_settings(ScheduleBuildSettings {
|
||||
// NOTE: you can change this to `LogLevel::Ignore` to easily see the current number of ambiguities.
|
||||
ambiguity_detection: LogLevel::Warn,
|
||||
// With auto-inserted apply_deferred stages, these can cause two ambiguous systems to
|
||||
// become accidentally ordered by one of the apply_deferred stages. Disabling requires
|
||||
// us to meet a higher bar. We don't just want no ambiguities - we also don't want
|
||||
// changes to systems or the auto-insert code from "creating" new ambiguities (by
|
||||
// reordering the graph). However, the cost is that the graph is no longer runnable,
|
||||
// since Bevy crates often rely on auto-insert apply_deferred to not panic (e.g.,
|
||||
// because a resource wasn't inserted).
|
||||
auto_insert_apply_deferred: false,
|
||||
use_shortnames: false,
|
||||
..default()
|
||||
});
|
||||
@@ -76,12 +88,23 @@ fn configure_ambiguity_detection(sub_app: &mut SubApp) {
|
||||
}
|
||||
|
||||
/// Returns the number of conflicting systems per schedule.
|
||||
fn count_ambiguities(sub_app: &SubApp) -> AmbiguitiesCount {
|
||||
let schedules = sub_app.world().resource::<Schedules>();
|
||||
fn count_ambiguities(sub_app: &mut SubApp) -> AmbiguitiesCount {
|
||||
let schedule_labels = sub_app
|
||||
.world()
|
||||
.resource::<Schedules>()
|
||||
.iter()
|
||||
.map(|(_, schedule)| schedule.label())
|
||||
.collect::<Vec<_>>();
|
||||
let mut ambiguities = <HashMap<_, _>>::default();
|
||||
for (_, schedule) in schedules.iter() {
|
||||
let ambiguities_in_schedule = schedule.graph().conflicting_systems().len();
|
||||
ambiguities.insert(schedule.label(), ambiguities_in_schedule);
|
||||
for label in schedule_labels {
|
||||
let ambiguities_in_schedule =
|
||||
sub_app
|
||||
.world_mut()
|
||||
.schedule_scope(label, |world, schedule| {
|
||||
schedule.initialize(world).unwrap().unwrap();
|
||||
schedule.graph().conflicting_systems().len()
|
||||
});
|
||||
ambiguities.insert(label, ambiguities_in_schedule);
|
||||
}
|
||||
AmbiguitiesCount(ambiguities)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user