bevy/crates/bevy_internal/src/default_plugins.rs
Alice Cecile 4ac2a63556
Remove all existing system order ambiguities in DefaultPlugins (#15031)
# Objective

As discussed in https://github.com/bevyengine/bevy/issues/7386, system
order ambiguities within `DefaultPlugins` are a source of bugs in the
engine and badly pollute diagnostic output for users.

We should eliminate them!

This PR is an alternative to #15027: with all external ambiguities
silenced, this should be much less prone to merge conflicts and the test
output should be much easier for authors to understand.

Note that system order ambiguities are still permitted in the
`RenderApp`: these need a bit of thought in terms of how to test them,
and will be fairly involved to fix. While these aren't *good*, they'll
generally only cause graphical bugs, not logic ones.

## Solution

All remaining system order ambiguities have been resolved.
Review this PR commit-by-commit to see how each of these problems were
fixed.

## Testing

`cargo run --example ambiguity_detection` passes with no panics or
logging!
2024-09-03 20:24:34 +00:00

122 lines
5.0 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use bevy_app::{plugin_group, Plugin};
plugin_group! {
/// This plugin group will add all the default plugins for a *Bevy* application:
pub struct DefaultPlugins {
bevy_app:::PanicHandlerPlugin,
bevy_log:::LogPlugin,
bevy_core:::TaskPoolPlugin,
bevy_core:::TypeRegistrationPlugin,
bevy_core:::FrameCountPlugin,
bevy_time:::TimePlugin,
bevy_transform:::TransformPlugin,
bevy_hierarchy:::HierarchyPlugin,
bevy_diagnostic:::DiagnosticsPlugin,
bevy_input:::InputPlugin,
bevy_window:::WindowPlugin,
bevy_a11y:::AccessibilityPlugin,
#[custom(cfg(not(target_arch = "wasm32")))]
bevy_app:::TerminalCtrlCHandlerPlugin,
#[cfg(feature = "bevy_asset")]
bevy_asset:::AssetPlugin,
#[cfg(feature = "bevy_scene")]
bevy_scene:::ScenePlugin,
#[cfg(feature = "bevy_winit")]
bevy_winit:::WinitPlugin,
#[cfg(feature = "bevy_render")]
bevy_render:::RenderPlugin,
// NOTE: Load this after renderer initialization so that it knows about the supported
// compressed texture formats.
#[cfg(feature = "bevy_render")]
bevy_render::texture:::ImagePlugin,
#[cfg(feature = "bevy_render")]
#[custom(cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded")))]
bevy_render::pipelined_rendering:::PipelinedRenderingPlugin,
#[cfg(feature = "bevy_core_pipeline")]
bevy_core_pipeline:::CorePipelinePlugin,
#[cfg(feature = "bevy_sprite")]
bevy_sprite:::SpritePlugin,
#[cfg(feature = "bevy_text")]
bevy_text:::TextPlugin,
#[cfg(feature = "bevy_ui")]
bevy_ui:::UiPlugin,
#[cfg(feature = "bevy_pbr")]
bevy_pbr:::PbrPlugin,
// NOTE: Load this after renderer initialization so that it knows about the supported
// compressed texture formats.
#[cfg(feature = "bevy_gltf")]
bevy_gltf:::GltfPlugin,
#[cfg(feature = "bevy_audio")]
bevy_audio:::AudioPlugin,
#[cfg(feature = "bevy_gilrs")]
bevy_gilrs:::GilrsPlugin,
#[cfg(feature = "bevy_animation")]
bevy_animation:::AnimationPlugin,
#[cfg(feature = "bevy_gizmos")]
bevy_gizmos:::GizmoPlugin,
#[cfg(feature = "bevy_state")]
bevy_state::app:::StatesPlugin,
#[cfg(feature = "bevy_picking")]
bevy_picking:::DefaultPickingPlugins,
#[cfg(feature = "bevy_dev_tools")]
bevy_dev_tools:::DevToolsPlugin,
#[cfg(feature = "bevy_ci_testing")]
bevy_dev_tools::ci_testing:::CiTestingPlugin,
#[doc(hidden)]
:IgnoreAmbiguitiesPlugin,
}
/// [`DefaultPlugins`] obeys *Cargo* *feature* flags. Users may exert control over this plugin group
/// by disabling `default-features` in their `Cargo.toml` and enabling only those features
/// that they wish to use.
///
/// [`DefaultPlugins`] contains all the plugins typically required to build
/// a *Bevy* application which includes a *window* and presentation components.
/// For *headless* cases without a *window* or presentation, see [`MinimalPlugins`].
}
#[derive(Default)]
struct IgnoreAmbiguitiesPlugin;
impl Plugin for IgnoreAmbiguitiesPlugin {
#[allow(unused_variables)] // Variables are used depending on enabled features
fn build(&self, app: &mut bevy_app::App) {
// bevy_ui owns the Transform and cannot be animated
#[cfg(all(feature = "bevy_animation", feature = "bevy_ui"))]
if app.is_plugin_added::<bevy_animation::AnimationPlugin>()
&& app.is_plugin_added::<bevy_ui::UiPlugin>()
{
app.ignore_ambiguity(
bevy_app::PostUpdate,
bevy_animation::advance_animations,
bevy_ui::ui_layout_system,
);
app.ignore_ambiguity(
bevy_app::PostUpdate,
bevy_animation::animate_targets,
bevy_ui::ui_layout_system,
);
}
}
}
plugin_group! {
/// This plugin group will add the minimal plugins for a *Bevy* application:
pub struct MinimalPlugins {
bevy_core:::TaskPoolPlugin,
bevy_core:::TypeRegistrationPlugin,
bevy_core:::FrameCountPlugin,
bevy_time:::TimePlugin,
bevy_app:::ScheduleRunnerPlugin,
#[cfg(feature = "bevy_ci_testing")]
bevy_dev_tools::ci_testing:::CiTestingPlugin,
}
/// This group of plugins is intended for use for minimal, *headless* programs
/// see the [*Bevy* *headless* example](https://github.com/bevyengine/bevy/blob/main/examples/app/headless.rs)
/// and includes a [schedule runner (`ScheduleRunnerPlugin`)](crate::app::ScheduleRunnerPlugin)
/// to provide functionality that would otherwise be driven by a windowed application's
/// *event loop* or *message loop*.
///
/// Windowed applications that wish to use a reduced set of plugins should consider the
/// [`DefaultPlugins`] plugin group which can be controlled with *Cargo* *feature* flags.
}