From 43c5e3e95fac047584025949742a70ec3a1abe4a Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 9 Dec 2024 18:11:31 +0100 Subject: [PATCH] conflicting system order ambiguity test --- .github/workflows/main.yml | 2 + Cargo.toml | 2 +- ci/Cargo.toml | 15 ++++++ ci/src/bin/ambiguity_detection.rs | 77 +++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 ci/Cargo.toml create mode 100644 ci/src/bin/ambiguity_detection.rs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f966b503..236c2821 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -58,6 +58,8 @@ jobs: run: cargo test --verbose -p bevy_rapier2d - name: Test for bevy_rapier3d run: cargo test --verbose -p bevy_rapier3d + - name: Test for no conflicting system order ambiguity + run: cargo run --bin ambiguity_detection test-wasm: runs-on: ubuntu-latest env: diff --git a/Cargo.toml b/Cargo.toml index a297a9b5..251fef80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["bevy_rapier2d", "bevy_rapier3d", "bevy_rapier_benches3d"] +members = ["bevy_rapier2d", "bevy_rapier3d", "bevy_rapier_benches3d", "ci"] resolver = "2" [profile.dev] diff --git a/ci/Cargo.toml b/ci/Cargo.toml new file mode 100644 index 00000000..ac2d9aad --- /dev/null +++ b/ci/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "ci" +version = "0.1.0" +edition = "2021" + +[dependencies] +bevy = "0.15.0" +bevy_audio = "0.15.0" +bevy_rapier3d = { path = "../bevy_rapier3d" } +bevy_rapier2d = { path = "../bevy_rapier2d" } + +[[bin]] +name = "ambiguity_detection" +test = false +bench = false diff --git a/ci/src/bin/ambiguity_detection.rs b/ci/src/bin/ambiguity_detection.rs new file mode 100644 index 00000000..b6cb7c10 --- /dev/null +++ b/ci/src/bin/ambiguity_detection.rs @@ -0,0 +1,77 @@ +//! A test to confirm that `bevy` doesn't regress its system ambiguities count when using [`DefaultPlugins`]. +//! This is run in CI. +//! +//! Note that because this test requires rendering, it isn't actually an integration test! +//! Instead, it's secretly an example: you can run this test manually using `cargo run --example ambiguity_detection`. + +use bevy::{ + ecs::schedule::{InternedScheduleLabel, LogLevel, ScheduleBuildSettings}, + log::LogPlugin, + prelude::*, + utils::HashMap, +}; +use bevy_rapier2d::plugin::NoUserData; +use bevy_rapier3d::plugin::RapierPhysicsPlugin; + +fn main() { + check_ambiguities(RapierPhysicsPlugin::::default(), true); + check_ambiguities( + RapierPhysicsPlugin::::default().in_fixed_schedule(), + false, + ); +} + +fn check_ambiguities(plugin: RapierPhysicsPlugin, set_logger: bool) { + let mut app = App::new(); + app.add_plugins((MinimalPlugins, TransformPlugin, AssetPlugin::default())); + if set_logger { + app.add_plugins(LogPlugin::default()); + } + app.add_plugins(plugin); + + let main_app = app.main_mut(); + configure_ambiguity_detection(main_app); + + app.finish(); + app.cleanup(); + app.update(); + + let main_app_ambiguities = count_ambiguities(app.main()); + assert_eq!( + main_app_ambiguities.total(), + 0, + "Main app has unexpected ambiguities among the following schedules: \n{main_app_ambiguities:#?}.", + ); +} + +/// Contains the number of conflicting systems per schedule. +#[derive(Debug, Deref, DerefMut)] +struct AmbiguitiesCount(pub HashMap); + +impl AmbiguitiesCount { + fn total(&self) -> usize { + self.values().sum() + } +} + +fn configure_ambiguity_detection(sub_app: &mut SubApp) { + let mut schedules = sub_app.world_mut().resource_mut::(); + for (_, schedule) in schedules.iter_mut() { + schedule.set_build_settings(ScheduleBuildSettings { + ambiguity_detection: LogLevel::Ignore, + use_shortnames: false, + ..default() + }); + } +} + +/// Returns the number of conflicting systems per schedule. +fn count_ambiguities(sub_app: &SubApp) -> AmbiguitiesCount { + let schedules = sub_app.world().resource::(); + let mut ambiguities = HashMap::new(); + for (_, schedule) in schedules.iter() { + let ambiguities_in_schedule = schedule.graph().conflicting_systems().len(); + ambiguities.insert(schedule.label(), ambiguities_in_schedule); + } + AmbiguitiesCount(ambiguities) +}