ambiguity_detection/
ambiguity_detection.rs1use bevy::{
8 ecs::schedule::{InternedScheduleLabel, LogLevel, ScheduleBuildSettings},
9 platform::collections::HashMap,
10 prelude::*,
11 render::{pipelined_rendering::PipelinedRenderingPlugin, RenderPlugin},
12};
13
14fn main() {
15 let mut app = App::new();
16 app.add_plugins(
17 DefaultPlugins
18 .build()
19 .set(RenderPlugin {
20 synchronous_pipeline_compilation: true,
25 ..Default::default()
26 })
27 .disable::<PipelinedRenderingPlugin>(),
30 );
31
32 let main_app = app.main_mut();
33 configure_ambiguity_detection(main_app);
34
35 let sub_app = app.sub_app_mut(bevy_render::RenderApp);
36 configure_ambiguity_detection(sub_app);
37
38 app.finish();
40 app.cleanup();
41
42 let main_app_ambiguities = count_ambiguities(app.main_mut());
43 assert_eq!(
44 main_app_ambiguities.total(),
45 0,
46 "Main app has unexpected ambiguities among the following schedules: \n{main_app_ambiguities:#?}.",
47 );
48
49 let render_app = app.sub_app_mut(bevy_render::RenderApp);
50 render_app.init_resource::<bevy_render::MainWorld>();
52 let render_app_ambiguities = count_ambiguities(render_app);
53 assert_eq!(
54 render_app_ambiguities.total(),
55 0,
56 "Render app has unexpected ambiguities among the following schedules: \n{render_app_ambiguities:#?}.",
57 );
58}
59
60#[derive(Debug, Deref, DerefMut)]
62struct AmbiguitiesCount(pub HashMap<InternedScheduleLabel, usize>);
63
64impl AmbiguitiesCount {
65 fn total(&self) -> usize {
66 self.values().sum()
67 }
68}
69
70fn configure_ambiguity_detection(sub_app: &mut SubApp) {
71 let mut schedules = sub_app.world_mut().resource_mut::<Schedules>();
72 for (_, schedule) in schedules.iter_mut() {
73 schedule.set_build_settings(ScheduleBuildSettings {
74 ambiguity_detection: LogLevel::Warn,
76 auto_insert_apply_deferred: false,
84 use_shortnames: false,
85 ..default()
86 });
87 }
88}
89
90fn count_ambiguities(sub_app: &mut SubApp) -> AmbiguitiesCount {
92 let schedule_labels = sub_app
93 .world()
94 .resource::<Schedules>()
95 .iter()
96 .map(|(_, schedule)| schedule.label())
97 .collect::<Vec<_>>();
98 let mut ambiguities = <HashMap<_, _>>::default();
99 for label in schedule_labels {
100 let ambiguities_in_schedule =
101 sub_app
102 .world_mut()
103 .schedule_scope(label, |world, schedule| {
104 schedule.initialize(world).unwrap().unwrap();
105 schedule.graph().conflicting_systems().len()
106 });
107 ambiguities.insert(label, ambiguities_in_schedule);
108 }
109 AmbiguitiesCount(ambiguities)
110}