Allow tuples and single plugins in add_plugins, deprecate add_plugin (#8097)

# Objective

- Better consistency with `add_systems`.
- Deprecating `add_plugin` in favor of a more powerful `add_plugins`.
- Allow passing `Plugin` to `add_plugins`.
- Allow passing tuples to `add_plugins`.

## Solution

- `App::add_plugins` now takes an `impl Plugins` parameter.
- `App::add_plugin` is deprecated.
- `Plugins` is a new sealed trait that is only implemented for `Plugin`,
`PluginGroup` and tuples over `Plugins`.
- All examples, benchmarks and tests are changed to use `add_plugins`,
using tuples where appropriate.

---

## Changelog

### Changed

- `App::add_plugins` now accepts all types that implement `Plugins`,
which is implemented for:
  - Types that implement `Plugin`.
  - Types that implement `PluginGroup`.
  - Tuples (up to 16 elements) over types that implement `Plugins`.
- Deprecated `App::add_plugin` in favor of `App::add_plugins`.

## Migration Guide

- Replace `app.add_plugin(plugin)` calls with `app.add_plugins(plugin)`.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
Edgar Geier 2023-06-21 22:51:03 +02:00 committed by GitHub
parent 72b4aacf86
commit f18f28874a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
81 changed files with 438 additions and 321 deletions

View file

@ -1,6 +1,4 @@
use crate::{ use crate::{First, Main, MainSchedulePlugin, Plugin, Plugins, Startup, StateTransition, Update};
First, Main, MainSchedulePlugin, Plugin, PluginGroup, Startup, StateTransition, Update,
};
pub use bevy_derive::AppLabel; pub use bevy_derive::AppLabel;
use bevy_ecs::{ use bevy_ecs::{
prelude::*, prelude::*,
@ -18,6 +16,7 @@ use std::{
#[cfg(feature = "trace")] #[cfg(feature = "trace")]
use bevy_utils::tracing::info_span; use bevy_utils::tracing::info_span;
bevy_utils::define_label!( bevy_utils::define_label!(
/// A strongly-typed class of labels used to identify an [`App`]. /// A strongly-typed class of labels used to identify an [`App`].
AppLabel, AppLabel,
@ -183,7 +182,7 @@ impl Default for App {
#[cfg(feature = "bevy_reflect")] #[cfg(feature = "bevy_reflect")]
app.init_resource::<AppTypeRegistry>(); app.init_resource::<AppTypeRegistry>();
app.add_plugin(MainSchedulePlugin); app.add_plugins(MainSchedulePlugin);
app.add_event::<AppExit>(); app.add_event::<AppExit>();
#[cfg(feature = "bevy_ci_testing")] #[cfg(feature = "bevy_ci_testing")]
@ -685,19 +684,16 @@ impl App {
/// # Panics /// # Panics
/// ///
/// Panics if the plugin was already added to the application. /// Panics if the plugin was already added to the application.
#[deprecated(since = "0.11.0", note = "Please use `add_plugins` instead.")]
pub fn add_plugin<T>(&mut self, plugin: T) -> &mut Self pub fn add_plugin<T>(&mut self, plugin: T) -> &mut Self
where where
T: Plugin, T: Plugin,
{ {
match self.add_boxed_plugin(Box::new(plugin)) { self.add_plugins(plugin)
Ok(app) => app,
Err(AppError::DuplicatePlugin { plugin_name }) => panic!(
"Error adding plugin {plugin_name}: : plugin was already added in application"
),
}
} }
/// Boxed variant of [`add_plugin`](App::add_plugin) that can be used from a [`PluginGroup`] /// Boxed variant of [`add_plugin`](App::add_plugin) that can be used from a
/// [`PluginGroup`](super::PluginGroup)
pub(crate) fn add_boxed_plugin( pub(crate) fn add_boxed_plugin(
&mut self, &mut self,
plugin: Box<dyn Plugin>, plugin: Box<dyn Plugin>,
@ -752,7 +748,7 @@ impl App {
/// # fn build(&self, app: &mut App) {} /// # fn build(&self, app: &mut App) {}
/// # } /// # }
/// # let mut app = App::new(); /// # let mut app = App::new();
/// # app.add_plugin(ImagePlugin::default()); /// # app.add_plugins(ImagePlugin::default());
/// let default_sampler = app.get_added_plugins::<ImagePlugin>()[0].default_sampler; /// let default_sampler = app.get_added_plugins::<ImagePlugin>()[0].default_sampler;
/// ``` /// ```
pub fn get_added_plugins<T>(&self) -> Vec<&T> pub fn get_added_plugins<T>(&self) -> Vec<&T>
@ -765,7 +761,10 @@ impl App {
.collect() .collect()
} }
/// Adds a group of [`Plugin`]s. /// Adds one or more [`Plugin`]s.
///
/// One of Bevy's core principles is modularity. All Bevy engine features are implemented
/// as [`Plugin`]s. This includes internal features like the renderer.
/// ///
/// [`Plugin`]s can be grouped into a set by using a [`PluginGroup`]. /// [`Plugin`]s can be grouped into a set by using a [`PluginGroup`].
/// ///
@ -773,23 +772,35 @@ impl App {
/// The [`PluginGroup`]s available by default are `DefaultPlugins` and `MinimalPlugins`. /// The [`PluginGroup`]s available by default are `DefaultPlugins` and `MinimalPlugins`.
/// ///
/// To customize the plugins in the group (reorder, disable a plugin, add a new plugin /// To customize the plugins in the group (reorder, disable a plugin, add a new plugin
/// before / after another plugin), call [`build()`](PluginGroup::build) on the group, /// before / after another plugin), call [`build()`](super::PluginGroup::build) on the group,
/// which will convert it to a [`PluginGroupBuilder`](crate::PluginGroupBuilder). /// which will convert it to a [`PluginGroupBuilder`](crate::PluginGroupBuilder).
/// ///
/// You can also specify a group of [`Plugin`]s by using a tuple over [`Plugin`]s and
/// [`PluginGroup`]s. See [`Plugins`] for more details.
///
/// ## Examples /// ## Examples
/// ``` /// ```
/// # use bevy_app::{prelude::*, PluginGroupBuilder, NoopPluginGroup as MinimalPlugins}; /// # use bevy_app::{prelude::*, PluginGroupBuilder, NoopPluginGroup as MinimalPlugins};
/// # /// #
/// # // Dummies created to avoid using `bevy_log`,
/// # // which pulls in too many dependencies and breaks rust-analyzer
/// # pub struct LogPlugin;
/// # impl Plugin for LogPlugin {
/// # fn build(&self, app: &mut App) {}
/// # }
/// App::new() /// App::new()
/// .add_plugins(MinimalPlugins); /// .add_plugins(MinimalPlugins);
/// App::new()
/// .add_plugins((MinimalPlugins, LogPlugin));
/// ``` /// ```
/// ///
/// # Panics /// # Panics
/// ///
/// Panics if one of the plugin in the group was already added to the application. /// Panics if one of the plugins was already added to the application.
pub fn add_plugins<T: PluginGroup>(&mut self, group: T) -> &mut Self { ///
let builder = group.build(); /// [`PluginGroup`]:super::PluginGroup
builder.finish(self); pub fn add_plugins<M>(&mut self, plugins: impl Plugins<M>) -> &mut Self {
plugins.add_to_app(self);
self self
} }
@ -1006,23 +1017,23 @@ mod tests {
#[test] #[test]
fn can_add_two_plugins() { fn can_add_two_plugins() {
App::new().add_plugin(PluginA).add_plugin(PluginB); App::new().add_plugins((PluginA, PluginB));
} }
#[test] #[test]
#[should_panic] #[should_panic]
fn cant_add_twice_the_same_plugin() { fn cant_add_twice_the_same_plugin() {
App::new().add_plugin(PluginA).add_plugin(PluginA); App::new().add_plugins((PluginA, PluginA));
} }
#[test] #[test]
fn can_add_twice_the_same_plugin_with_different_type_param() { fn can_add_twice_the_same_plugin_with_different_type_param() {
App::new().add_plugin(PluginC(0)).add_plugin(PluginC(true)); App::new().add_plugins((PluginC(0), PluginC(true)));
} }
#[test] #[test]
fn can_add_twice_the_same_plugin_not_unique() { fn can_add_twice_the_same_plugin_not_unique() {
App::new().add_plugin(PluginD).add_plugin(PluginD); App::new().add_plugins((PluginD, PluginD));
} }
#[test] #[test]
@ -1035,10 +1046,10 @@ mod tests {
} }
impl Plugin for PluginRun { impl Plugin for PluginRun {
fn build(&self, app: &mut crate::App) { fn build(&self, app: &mut crate::App) {
app.add_plugin(InnerPlugin).run(); app.add_plugins(InnerPlugin).run();
} }
} }
App::new().add_plugin(PluginRun); App::new().add_plugins(PluginRun);
} }
#[derive(States, PartialEq, Eq, Debug, Default, Hash, Clone)] #[derive(States, PartialEq, Eq, Debug, Default, Hash, Clone)]

View file

@ -65,3 +65,61 @@ impl_downcast!(Plugin);
/// ///
/// See `bevy_dynamic_plugin/src/loader.rs#dynamically_load_plugin`. /// See `bevy_dynamic_plugin/src/loader.rs#dynamically_load_plugin`.
pub type CreatePlugin = unsafe fn() -> *mut dyn Plugin; pub type CreatePlugin = unsafe fn() -> *mut dyn Plugin;
/// Types that represent a set of [`Plugin`]s.
///
/// This is implemented for all types which implement [`Plugin`],
/// [`PluginGroup`](super::PluginGroup), and tuples over [`Plugins`].
pub trait Plugins<Marker>: sealed::Plugins<Marker> {}
impl<Marker, T> Plugins<Marker> for T where T: sealed::Plugins<Marker> {}
mod sealed {
use bevy_ecs::all_tuples;
use crate::{App, AppError, Plugin, PluginGroup};
pub trait Plugins<Marker> {
fn add_to_app(self, app: &mut App);
}
pub struct PluginMarker;
pub struct PluginGroupMarker;
pub struct PluginsTupleMarker;
impl<P: Plugin> Plugins<PluginMarker> for P {
fn add_to_app(self, app: &mut App) {
if let Err(AppError::DuplicatePlugin { plugin_name }) =
app.add_boxed_plugin(Box::new(self))
{
panic!(
"Error adding plugin {plugin_name}: : plugin was already added in application"
)
}
}
}
impl<P: PluginGroup> Plugins<PluginGroupMarker> for P {
fn add_to_app(self, app: &mut App) {
self.build().finish(app);
}
}
macro_rules! impl_plugins_tuples {
($(($param: ident, $plugins: ident)),*) => {
impl<$($param, $plugins),*> Plugins<(PluginsTupleMarker, $($param,)*)> for ($($plugins,)*)
where
$($plugins: Plugins<$param>),*
{
#[allow(non_snake_case, unused_variables)]
fn add_to_app(self, app: &mut App) {
let ($($plugins,)*) = self;
$($plugins.add_to_app(app);)*
}
}
}
}
all_tuples!(impl_plugins_tuples, 0, 15, P, S);
}

View file

@ -85,7 +85,7 @@ pub struct AssetServerInternal {
/// # use bevy_utils::Duration; /// # use bevy_utils::Duration;
/// # let mut app = App::new(); /// # let mut app = App::new();
/// // The asset plugin can be configured to watch for asset changes. /// // The asset plugin can be configured to watch for asset changes.
/// app.add_plugin(AssetPlugin { /// app.add_plugins(AssetPlugin {
/// watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)), /// watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)),
/// ..Default::default() /// ..Default::default()
/// }); /// });

View file

@ -494,9 +494,11 @@ mod tests {
#[uuid = "44115972-f31b-46e5-be5c-2b9aece6a52f"] #[uuid = "44115972-f31b-46e5-be5c-2b9aece6a52f"]
struct MyAsset; struct MyAsset;
let mut app = App::new(); let mut app = App::new();
app.add_plugin(bevy_core::TaskPoolPlugin::default()) app.add_plugins((
.add_plugin(bevy_core::TypeRegistrationPlugin::default()) bevy_core::TaskPoolPlugin::default(),
.add_plugin(crate::AssetPlugin::default()); bevy_core::TypeRegistrationPlugin::default(),
crate::AssetPlugin::default(),
));
app.add_asset::<MyAsset>(); app.add_asset::<MyAsset>();
let mut assets_before = app.world.resource_mut::<Assets<MyAsset>>(); let mut assets_before = app.world.resource_mut::<Assets<MyAsset>>();
let handle = assets_before.add(MyAsset); let handle = assets_before.add(MyAsset);

View file

@ -71,7 +71,7 @@ impl Plugin for DebugAssetServerPlugin {
.build() .build()
}); });
let mut debug_asset_app = App::new(); let mut debug_asset_app = App::new();
debug_asset_app.add_plugin(AssetPlugin { debug_asset_app.add_plugins(AssetPlugin {
asset_folder: "crates".to_string(), asset_folder: "crates".to_string(),
watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)), watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)),
}); });

View file

@ -268,7 +268,7 @@ mod tests {
#[test] #[test]
fn test_reflect_asset_operations() { fn test_reflect_asset_operations() {
let mut app = App::new(); let mut app = App::new();
app.add_plugin(AssetPlugin::default()) app.add_plugins(AssetPlugin::default())
.add_asset::<AssetType>() .add_asset::<AssetType>()
.register_asset_reflect::<AssetType>(); .register_asset_reflect::<AssetType>();

View file

@ -7,9 +7,7 @@
//! # use bevy_app::{App, AppExit, NoopPluginGroup as MinimalPlugins, Startup}; //! # use bevy_app::{App, AppExit, NoopPluginGroup as MinimalPlugins, Startup};
//! fn main() { //! fn main() {
//! App::new() //! App::new()
//! .add_plugins(MinimalPlugins) //! .add_plugins((MinimalPlugins, AssetPlugin::default(), AudioPlugin::default()))
//! .add_plugin(AssetPlugin::default())
//! .add_plugin(AudioPlugin::default())
//! .add_systems(Startup, play_background_audio) //! .add_systems(Startup, play_background_audio)
//! .run(); //! .run();
//! } //! }

View file

@ -165,8 +165,7 @@ mod tests {
#[test] #[test]
fn runs_spawn_local_tasks() { fn runs_spawn_local_tasks() {
let mut app = App::new(); let mut app = App::new();
app.add_plugin(TaskPoolPlugin::default()); app.add_plugins((TaskPoolPlugin::default(), TypeRegistrationPlugin::default()));
app.add_plugin(TypeRegistrationPlugin::default());
let (async_tx, async_rx) = crossbeam_channel::unbounded(); let (async_tx, async_rx) = crossbeam_channel::unbounded();
AsyncComputeTaskPool::get() AsyncComputeTaskPool::get()
@ -199,9 +198,11 @@ mod tests {
#[test] #[test]
fn frame_counter_update() { fn frame_counter_update() {
let mut app = App::new(); let mut app = App::new();
app.add_plugin(TaskPoolPlugin::default()); app.add_plugins((
app.add_plugin(TypeRegistrationPlugin::default()); TaskPoolPlugin::default(),
app.add_plugin(FrameCountPlugin::default()); TypeRegistrationPlugin::default(),
FrameCountPlugin::default(),
));
app.update(); app.update();
let frame_count = app.world.resource::<FrameCount>(); let frame_count = app.world.resource::<FrameCount>();

View file

@ -52,8 +52,10 @@ impl Plugin for BloomPlugin {
app.register_type::<BloomSettings>(); app.register_type::<BloomSettings>();
app.register_type::<BloomPrefilterSettings>(); app.register_type::<BloomPrefilterSettings>();
app.register_type::<BloomCompositeMode>(); app.register_type::<BloomCompositeMode>();
app.add_plugin(ExtractComponentPlugin::<BloomSettings>::default()); app.add_plugins((
app.add_plugin(UniformComponentPlugin::<BloomUniforms>::default()); ExtractComponentPlugin::<BloomSettings>::default(),
UniformComponentPlugin::<BloomUniforms>::default(),
));
let render_app = match app.get_sub_app_mut(RenderApp) { let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app, Ok(render_app) => render_app,

View file

@ -108,8 +108,10 @@ impl Plugin for CASPlugin {
); );
app.register_type::<ContrastAdaptiveSharpeningSettings>(); app.register_type::<ContrastAdaptiveSharpeningSettings>();
app.add_plugin(ExtractComponentPlugin::<ContrastAdaptiveSharpeningSettings>::default()); app.add_plugins((
app.add_plugin(UniformComponentPlugin::<CASUniform>::default()); ExtractComponentPlugin::<ContrastAdaptiveSharpeningSettings>::default(),
UniformComponentPlugin::<CASUniform>::default(),
));
let render_app = match app.get_sub_app_mut(RenderApp) { let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app, Ok(render_app) => render_app,

View file

@ -45,7 +45,7 @@ pub struct Core2dPlugin;
impl Plugin for Core2dPlugin { impl Plugin for Core2dPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.register_type::<Camera2d>() app.register_type::<Camera2d>()
.add_plugin(ExtractComponentPlugin::<Camera2d>::default()); .add_plugins(ExtractComponentPlugin::<Camera2d>::default());
let render_app = match app.get_sub_app_mut(RenderApp) { let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app, Ok(render_app) => render_app,

View file

@ -69,8 +69,7 @@ impl Plugin for Core3dPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.register_type::<Camera3d>() app.register_type::<Camera3d>()
.register_type::<Camera3dDepthLoadOp>() .register_type::<Camera3dDepthLoadOp>()
.add_plugin(SkyboxPlugin) .add_plugins((SkyboxPlugin, ExtractComponentPlugin::<Camera3d>::default()));
.add_plugin(ExtractComponentPlugin::<Camera3d>::default());
let render_app = match app.get_sub_app_mut(RenderApp) { let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app, Ok(render_app) => render_app,

View file

@ -87,7 +87,7 @@ impl Plugin for FxaaPlugin {
load_internal_asset!(app, FXAA_SHADER_HANDLE, "fxaa.wgsl", Shader::from_wgsl); load_internal_asset!(app, FXAA_SHADER_HANDLE, "fxaa.wgsl", Shader::from_wgsl);
app.register_type::<Fxaa>(); app.register_type::<Fxaa>();
app.add_plugin(ExtractComponentPlugin::<Fxaa>::default()); app.add_plugins(ExtractComponentPlugin::<Fxaa>::default());
let render_app = match app.get_sub_app_mut(RenderApp) { let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app, Ok(render_app) => render_app,

View file

@ -68,15 +68,17 @@ impl Plugin for CorePipelinePlugin {
.register_type::<DepthPrepass>() .register_type::<DepthPrepass>()
.register_type::<NormalPrepass>() .register_type::<NormalPrepass>()
.init_resource::<ClearColor>() .init_resource::<ClearColor>()
.add_plugin(ExtractResourcePlugin::<ClearColor>::default()) .add_plugins((
.add_plugin(Core2dPlugin) ExtractResourcePlugin::<ClearColor>::default(),
.add_plugin(Core3dPlugin) Core2dPlugin,
.add_plugin(BlitPlugin) Core3dPlugin,
.add_plugin(MsaaWritebackPlugin) BlitPlugin,
.add_plugin(TonemappingPlugin) MsaaWritebackPlugin,
.add_plugin(UpscalingPlugin) TonemappingPlugin,
.add_plugin(BloomPlugin) UpscalingPlugin,
.add_plugin(FxaaPlugin) BloomPlugin,
.add_plugin(CASPlugin); FxaaPlugin,
CASPlugin,
));
} }
} }

View file

@ -34,7 +34,7 @@ impl Plugin for SkyboxPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
load_internal_asset!(app, SKYBOX_SHADER_HANDLE, "skybox.wgsl", Shader::from_wgsl); load_internal_asset!(app, SKYBOX_SHADER_HANDLE, "skybox.wgsl", Shader::from_wgsl);
app.add_plugin(ExtractComponentPlugin::<Skybox>::default()); app.add_plugins(ExtractComponentPlugin::<Skybox>::default());
let render_app = match app.get_sub_app_mut(RenderApp) { let render_app = match app.get_sub_app_mut(RenderApp) {
Ok(render_app) => render_app, Ok(render_app) => render_app,

View file

@ -82,13 +82,15 @@ impl Plugin for TonemappingPlugin {
app.insert_resource(tonemapping_luts); app.insert_resource(tonemapping_luts);
} }
app.add_plugin(ExtractResourcePlugin::<TonemappingLuts>::default()); app.add_plugins(ExtractResourcePlugin::<TonemappingLuts>::default());
app.register_type::<Tonemapping>(); app.register_type::<Tonemapping>();
app.register_type::<DebandDither>(); app.register_type::<DebandDither>();
app.add_plugin(ExtractComponentPlugin::<Tonemapping>::default()); app.add_plugins((
app.add_plugin(ExtractComponentPlugin::<DebandDither>::default()); ExtractComponentPlugin::<Tonemapping>::default(),
ExtractComponentPlugin::<DebandDither>::default(),
));
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app render_app

View file

@ -299,7 +299,7 @@ impl RegisterDiagnostic for App {
/// ///
/// App::new() /// App::new()
/// .register_diagnostic(Diagnostic::new(UNIQUE_DIAG_ID, "example", 10)) /// .register_diagnostic(Diagnostic::new(UNIQUE_DIAG_ID, "example", 10))
/// .add_plugin(DiagnosticsPlugin) /// .add_plugins(DiagnosticsPlugin)
/// .run(); /// .run();
/// ``` /// ```
fn register_diagnostic(&mut self, diagnostic: Diagnostic) -> &mut Self { fn register_diagnostic(&mut self, diagnostic: Diagnostic) -> &mut Self {

View file

@ -78,9 +78,9 @@ impl Plugin for GizmoPlugin {
fn build(&self, app: &mut bevy_app::App) { fn build(&self, app: &mut bevy_app::App) {
load_internal_asset!(app, LINE_SHADER_HANDLE, "lines.wgsl", Shader::from_wgsl); load_internal_asset!(app, LINE_SHADER_HANDLE, "lines.wgsl", Shader::from_wgsl);
app.add_plugin(UniformComponentPlugin::<LineGizmoUniform>::default()) app.add_plugins(UniformComponentPlugin::<LineGizmoUniform>::default())
.add_asset::<LineGizmo>() .add_asset::<LineGizmo>()
.add_plugin(RenderAssetPlugin::<LineGizmo>::default()) .add_plugins(RenderAssetPlugin::<LineGizmo>::default())
.init_resource::<LineGizmoHandles>() .init_resource::<LineGizmoHandles>()
.init_resource::<GizmoConfig>() .init_resource::<GizmoConfig>()
.init_resource::<GizmoStorage>() .init_resource::<GizmoStorage>()
@ -100,9 +100,9 @@ impl Plugin for GizmoPlugin {
.add_systems(Render, queue_line_gizmo_bind_group.in_set(RenderSet::Queue)); .add_systems(Render, queue_line_gizmo_bind_group.in_set(RenderSet::Queue));
#[cfg(feature = "bevy_sprite")] #[cfg(feature = "bevy_sprite")]
app.add_plugin(pipeline_2d::LineGizmo2dPlugin); app.add_plugins(pipeline_2d::LineGizmo2dPlugin);
#[cfg(feature = "bevy_pbr")] #[cfg(feature = "bevy_pbr")]
app.add_plugin(pipeline_3d::LineGizmo3dPlugin); app.add_plugins(pipeline_3d::LineGizmo3dPlugin);
} }
fn finish(&self, app: &mut bevy_app::App) { fn finish(&self, app: &mut bevy_app::App) {

View file

@ -28,7 +28,7 @@ impl Plugin for EnvironmentMapPlugin {
); );
app.register_type::<EnvironmentMapLight>() app.register_type::<EnvironmentMapLight>()
.add_plugin(ExtractComponentPlugin::<EnvironmentMapLight>::default()); .add_plugins(ExtractComponentPlugin::<EnvironmentMapLight>::default());
} }
} }

View file

@ -182,18 +182,21 @@ impl Plugin for PbrPlugin {
.register_type::<PointLight>() .register_type::<PointLight>()
.register_type::<PointLightShadowMap>() .register_type::<PointLightShadowMap>()
.register_type::<SpotLight>() .register_type::<SpotLight>()
.add_plugin(MeshRenderPlugin)
.add_plugin(MaterialPlugin::<StandardMaterial> {
prepass_enabled: self.prepass_enabled,
..Default::default()
})
.add_plugin(ScreenSpaceAmbientOcclusionPlugin)
.add_plugin(EnvironmentMapPlugin)
.init_resource::<AmbientLight>() .init_resource::<AmbientLight>()
.init_resource::<GlobalVisiblePointLights>() .init_resource::<GlobalVisiblePointLights>()
.init_resource::<DirectionalLightShadowMap>() .init_resource::<DirectionalLightShadowMap>()
.init_resource::<PointLightShadowMap>() .init_resource::<PointLightShadowMap>()
.add_plugin(ExtractResourcePlugin::<AmbientLight>::default()) .add_plugins((
MeshRenderPlugin,
MaterialPlugin::<StandardMaterial> {
prepass_enabled: self.prepass_enabled,
..Default::default()
},
ScreenSpaceAmbientOcclusionPlugin,
EnvironmentMapPlugin,
ExtractResourcePlugin::<AmbientLight>::default(),
FogPlugin,
))
.configure_sets( .configure_sets(
PostUpdate, PostUpdate,
( (
@ -203,7 +206,6 @@ impl Plugin for PbrPlugin {
) )
.chain(), .chain(),
) )
.add_plugin(FogPlugin)
.add_systems( .add_systems(
PostUpdate, PostUpdate,
( (

View file

@ -188,7 +188,7 @@ where
{ {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_asset::<M>() app.add_asset::<M>()
.add_plugin(ExtractComponentPlugin::<Handle<M>>::extract_visible()); .add_plugins(ExtractComponentPlugin::<Handle<M>>::extract_visible());
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app render_app
@ -214,10 +214,10 @@ where
} }
// PrepassPipelinePlugin is required for shadow mapping and the optional PrepassPlugin // PrepassPipelinePlugin is required for shadow mapping and the optional PrepassPlugin
app.add_plugin(PrepassPipelinePlugin::<M>::default()); app.add_plugins(PrepassPipelinePlugin::<M>::default());
if self.prepass_enabled { if self.prepass_enabled {
app.add_plugin(PrepassPlugin::<M>::default()); app.add_plugins(PrepassPlugin::<M>::default());
} }
} }

View file

@ -138,7 +138,7 @@ impl Plugin for FogPlugin {
load_internal_asset!(app, FOG_SHADER_HANDLE, "fog.wgsl", Shader::from_wgsl); load_internal_asset!(app, FOG_SHADER_HANDLE, "fog.wgsl", Shader::from_wgsl);
app.register_type::<FogSettings>(); app.register_type::<FogSettings>();
app.add_plugin(ExtractComponentPlugin::<FogSettings>::default()); app.add_plugins(ExtractComponentPlugin::<FogSettings>::default());
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app render_app

View file

@ -102,7 +102,7 @@ impl Plugin for MeshRenderPlugin {
load_internal_asset!(app, MESH_SHADER_HANDLE, "mesh.wgsl", Shader::from_wgsl); load_internal_asset!(app, MESH_SHADER_HANDLE, "mesh.wgsl", Shader::from_wgsl);
load_internal_asset!(app, SKINNING_HANDLE, "skinning.wgsl", Shader::from_wgsl); load_internal_asset!(app, SKINNING_HANDLE, "skinning.wgsl", Shader::from_wgsl);
app.add_plugin(UniformComponentPlugin::<MeshUniform>::default()); app.add_plugins(UniformComponentPlugin::<MeshUniform>::default());
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app render_app

View file

@ -40,8 +40,10 @@ impl Plugin for WireframePlugin {
app.register_type::<Wireframe>() app.register_type::<Wireframe>()
.register_type::<WireframeConfig>() .register_type::<WireframeConfig>()
.init_resource::<WireframeConfig>() .init_resource::<WireframeConfig>()
.add_plugin(ExtractResourcePlugin::<WireframeConfig>::default()) .add_plugins((
.add_plugin(ExtractComponentPlugin::<Wireframe>::default()); ExtractResourcePlugin::<WireframeConfig>::default(),
ExtractComponentPlugin::<Wireframe>::default(),
));
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app render_app

View file

@ -28,10 +28,12 @@ impl Plugin for CameraPlugin {
.register_type::<CameraRenderGraph>() .register_type::<CameraRenderGraph>()
.register_type::<RenderTarget>() .register_type::<RenderTarget>()
.init_resource::<ManualTextureViews>() .init_resource::<ManualTextureViews>()
.add_plugin(CameraProjectionPlugin::<Projection>::default()) .add_plugins((
.add_plugin(CameraProjectionPlugin::<OrthographicProjection>::default()) CameraProjectionPlugin::<Projection>::default(),
.add_plugin(CameraProjectionPlugin::<PerspectiveProjection>::default()) CameraProjectionPlugin::<OrthographicProjection>::default(),
.add_plugin(ExtractResourcePlugin::<ManualTextureViews>::default()); CameraProjectionPlugin::<PerspectiveProjection>::default(),
ExtractResourcePlugin::<ManualTextureViews>::default(),
));
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app render_app

View file

@ -329,12 +329,14 @@ impl Plugin for RenderPlugin {
})); }));
} }
app.add_plugin(ValidParentCheckPlugin::<view::ComputedVisibility>::default()) app.add_plugins((
.add_plugin(WindowRenderPlugin) ValidParentCheckPlugin::<view::ComputedVisibility>::default(),
.add_plugin(CameraPlugin) WindowRenderPlugin,
.add_plugin(ViewPlugin) CameraPlugin,
.add_plugin(MeshPlugin) ViewPlugin,
.add_plugin(GlobalsPlugin); MeshPlugin,
GlobalsPlugin,
));
app.register_type::<color::Color>() app.register_type::<color::Color>()
.register_type::<primitives::Aabb>() .register_type::<primitives::Aabb>()

View file

@ -19,6 +19,6 @@ impl Plugin for MeshPlugin {
.add_asset::<skinning::SkinnedMeshInverseBindposes>() .add_asset::<skinning::SkinnedMeshInverseBindposes>()
.register_type::<skinning::SkinnedMesh>() .register_type::<skinning::SkinnedMesh>()
.register_type::<Vec<Entity>>() .register_type::<Vec<Entity>>()
.add_plugin(RenderAssetPlugin::<Mesh>::default()); .add_plugins(RenderAssetPlugin::<Mesh>::default());
} }
} }

View file

@ -93,7 +93,7 @@ impl Plugin for ImagePlugin {
app.init_asset_loader::<HdrTextureLoader>(); app.init_asset_loader::<HdrTextureLoader>();
} }
app.add_plugin(RenderAssetPlugin::<Image>::with_prepare_asset_set( app.add_plugins(RenderAssetPlugin::<Image>::with_prepare_asset_set(
PrepareAssetSet::PreAssetPrepare, PrepareAssetSet::PreAssetPrepare,
)) ))
.register_type::<Image>() .register_type::<Image>()

View file

@ -50,8 +50,7 @@ impl Plugin for ViewPlugin {
.register_type::<ColorGrading>() .register_type::<ColorGrading>()
.init_resource::<Msaa>() .init_resource::<Msaa>()
// NOTE: windows.is_changed() handles cases where a window was resized // NOTE: windows.is_changed() handles cases where a window was resized
.add_plugin(ExtractResourcePlugin::<Msaa>::default()) .add_plugins((ExtractResourcePlugin::<Msaa>::default(), VisibilityPlugin));
.add_plugin(VisibilityPlugin);
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app render_app

View file

@ -34,7 +34,7 @@ pub enum WindowSystem {
impl Plugin for WindowRenderPlugin { impl Plugin for WindowRenderPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugin(ScreenshotPlugin); app.add_plugins(ScreenshotPlugin);
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app render_app

View file

@ -65,8 +65,7 @@ impl Plugin for SpritePlugin {
.register_type::<TextureAtlasSprite>() .register_type::<TextureAtlasSprite>()
.register_type::<Anchor>() .register_type::<Anchor>()
.register_type::<Mesh2dHandle>() .register_type::<Mesh2dHandle>()
.add_plugin(Mesh2dRenderPlugin) .add_plugins((Mesh2dRenderPlugin, ColorMaterialPlugin))
.add_plugin(ColorMaterialPlugin)
.add_systems( .add_systems(
PostUpdate, PostUpdate,
calculate_bounds_2d.in_set(VisibilitySystems::CalculateBounds), calculate_bounds_2d.in_set(VisibilitySystems::CalculateBounds),

View file

@ -23,7 +23,7 @@ impl Plugin for ColorMaterialPlugin {
Shader::from_wgsl Shader::from_wgsl
); );
app.add_plugin(Material2dPlugin::<ColorMaterial>::default()) app.add_plugins(Material2dPlugin::<ColorMaterial>::default())
.register_asset_reflect::<ColorMaterial>(); .register_asset_reflect::<ColorMaterial>();
app.world app.world

View file

@ -152,7 +152,7 @@ where
{ {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_asset::<M>() app.add_asset::<M>()
.add_plugin(ExtractComponentPlugin::<Handle<M>>::extract_visible()); .add_plugins(ExtractComponentPlugin::<Handle<M>>::extract_visible());
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app render_app

View file

@ -97,7 +97,7 @@ impl Plugin for Mesh2dRenderPlugin {
); );
load_internal_asset!(app, MESH2D_SHADER_HANDLE, "mesh2d.wgsl", Shader::from_wgsl); load_internal_asset!(app, MESH2D_SHADER_HANDLE, "mesh2d.wgsl", Shader::from_wgsl);
app.add_plugin(UniformComponentPlugin::<Mesh2dUniform>::default()); app.add_plugins(UniformComponentPlugin::<Mesh2dUniform>::default());
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app render_app

View file

@ -101,7 +101,7 @@ impl Plugin for TransformPlugin {
app.register_type::<Transform>() app.register_type::<Transform>()
.register_type::<GlobalTransform>() .register_type::<GlobalTransform>()
.add_plugin(ValidParentCheckPlugin::<GlobalTransform>::default()) .add_plugins(ValidParentCheckPlugin::<GlobalTransform>::default())
.configure_set( .configure_set(
PostStartup, PostStartup,
PropagateTransformsSet.in_set(TransformSystem::TransformPropagate), PropagateTransformsSet.in_set(TransformSystem::TransformPropagate),

View file

@ -81,7 +81,7 @@ impl Default for UiScale {
impl Plugin for UiPlugin { impl Plugin for UiPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugin(ExtractComponentPlugin::<UiCameraConfig>::default()) app.add_plugins(ExtractComponentPlugin::<UiCameraConfig>::default())
.init_resource::<UiSurface>() .init_resource::<UiSurface>()
.init_resource::<UiScale>() .init_resource::<UiScale>()
.init_resource::<UiStack>() .init_resource::<UiStack>()
@ -144,7 +144,7 @@ impl Plugin for UiPlugin {
), ),
); );
#[cfg(feature = "bevy_text")] #[cfg(feature = "bevy_text")]
app.add_plugin(accessibility::AccessibilityPlugin); app.add_plugins(accessibility::AccessibilityPlugin);
app.add_systems(PostUpdate, { app.add_systems(PostUpdate, {
let system = widget::update_image_content_size_system.before(UiSystem::Layout); let system = widget::update_image_content_size_system.before(UiSystem::Layout);
// Potential conflicts: `Assets<Image>` // Potential conflicts: `Assets<Image>`

View file

@ -99,10 +99,10 @@ impl Plugin for WinitPlugin {
), ),
); );
app.add_plugin(AccessibilityPlugin); app.add_plugins(AccessibilityPlugin);
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
app.add_plugin(CanvasParentResizePlugin); app.add_plugins(CanvasParentResizePlugin);
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
let mut create_window_system_state: SystemState<( let mut create_window_system_state: SystemState<(

View file

@ -22,14 +22,14 @@ fn main() {
color: Color::WHITE, color: Color::WHITE,
brightness: 1.0 / 5.0f32, brightness: 1.0 / 5.0f32,
}) })
.add_plugins( .add_plugins((
DefaultPlugins.set( DefaultPlugins.set(
GltfPlugin::default() GltfPlugin::default()
// Map a custom glTF attribute name to a `MeshVertexAttribute`. // Map a custom glTF attribute name to a `MeshVertexAttribute`.
.add_custom_vertex_attribute("_BARYCENTRIC", ATTRIBUTE_BARYCENTRIC), .add_custom_vertex_attribute("_BARYCENTRIC", ATTRIBUTE_BARYCENTRIC),
), ),
) Material2dPlugin::<CustomMaterial>::default(),
.add_plugin(Material2dPlugin::<CustomMaterial>::default()) ))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }

View file

@ -32,8 +32,7 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, ColoredMesh2dPlugin))
.add_plugin(ColoredMesh2dPlugin)
.add_systems(Startup, star) .add_systems(Startup, star)
.run(); .run();
} }

View file

@ -21,8 +21,7 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.insert_resource(Msaa::Off) .insert_resource(Msaa::Off)
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, TemporalAntiAliasPlugin))
.add_plugin(TemporalAntiAliasPlugin)
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (modify_aa, modify_sharpening, update_ui)) .add_systems(Update, (modify_aa, modify_sharpening, update_ui))
.run(); .run();

View file

@ -15,8 +15,7 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, MaterialPlugin::<LineMaterial>::default()))
.add_plugin(MaterialPlugin::<LineMaterial>::default())
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }

View file

@ -9,9 +9,11 @@ use rand::{thread_rng, Rng};
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((
.add_plugin(FrameTimeDiagnosticsPlugin) DefaultPlugins,
.add_plugin(LogDiagnosticsPlugin::default()) FrameTimeDiagnosticsPlugin,
LogDiagnosticsPlugin::default(),
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (light_sway, movement)) .add_systems(Update, (light_sway, movement))
.run(); .run();

View file

@ -17,8 +17,7 @@ fn main() {
brightness: 5.0, brightness: 5.0,
..default() ..default()
}) })
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, TemporalAntiAliasPlugin))
.add_plugin(TemporalAntiAliasPlugin)
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, update) .add_systems(Update, update)
.run(); .run();

View file

@ -19,8 +19,10 @@ use std::f32::consts::PI;
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((
.add_plugin(MaterialPlugin::<ColorGradientMaterial>::default()) DefaultPlugins,
MaterialPlugin::<ColorGradientMaterial>::default(),
))
.insert_resource(CameraTransform( .insert_resource(CameraTransform(
Transform::from_xyz(0.7, 0.7, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y), Transform::from_xyz(0.7, 0.7, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y),
)) ))

View file

@ -8,13 +8,15 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins.set(RenderPlugin { .add_plugins((
DefaultPlugins.set(RenderPlugin {
wgpu_settings: WgpuSettings { wgpu_settings: WgpuSettings {
features: WgpuFeatures::POLYGON_MODE_LINE, features: WgpuFeatures::POLYGON_MODE_LINE,
..default() ..default()
}, },
})) }),
.add_plugin(WireframePlugin) WireframePlugin,
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }

View file

@ -8,12 +8,14 @@ use bevy::{prelude::*, utils::Duration};
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins)
// plugins are registered as part of the "app building" process // plugins are registered as part of the "app building" process
.add_plugin(PrintMessagePlugin { .add_plugins((
DefaultPlugins,
PrintMessagePlugin {
wait_duration: Duration::from_secs(1), wait_duration: Duration::from_secs(1),
message: "This is an example plugin".to_string(), message: "This is an example plugin".to_string(),
}) },
))
.run(); .run();
} }

View file

@ -5,10 +5,12 @@ use bevy::{app::PluginGroupBuilder, prelude::*};
fn main() { fn main() {
App::new() App::new()
.add_plugins((
// Two PluginGroups that are included with bevy are DefaultPlugins and MinimalPlugins // Two PluginGroups that are included with bevy are DefaultPlugins and MinimalPlugins
.add_plugins(DefaultPlugins) DefaultPlugins,
// Adding a plugin group adds all plugins in the group by default // Adding a plugin group adds all plugins in the group by default
.add_plugins(HelloWorldPlugins) HelloWorldPlugins,
))
// You can also modify a PluginGroup (such as disabling plugins) like this: // You can also modify a PluginGroup (such as disabling plugins) like this:
// .add_plugins( // .add_plugins(
// HelloWorldPlugins // HelloWorldPlugins

View file

@ -7,10 +7,12 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((
DefaultPlugins,
// The "print diagnostics" plugin is optional. // The "print diagnostics" plugin is optional.
// It just visualizes our diagnostics in the console. // It just visualizes our diagnostics in the console.
.add_plugin(LogDiagnosticsPlugin::default()) LogDiagnosticsPlugin::default(),
))
// Diagnostics must be initialized before measurements can be added. // Diagnostics must be initialized before measurements can be added.
.register_diagnostic( .register_diagnostic(
Diagnostic::new(SYSTEM_ITERATION_COUNT, "system_iteration_count", 10) Diagnostic::new(SYSTEM_ITERATION_COUNT, "system_iteration_count", 10)

View file

@ -7,17 +7,18 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((
DefaultPlugins,
// Adds frame time diagnostics // Adds frame time diagnostics
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
// Adds a system that prints diagnostics to the console // Adds a system that prints diagnostics to the console
.add_plugin(LogDiagnosticsPlugin::default()) LogDiagnosticsPlugin::default(),
// Any plugin can register diagnostics // Any plugin can register diagnostics. Uncomment this to add an entity count diagnostics:
// Uncomment this to add an entity count diagnostics: // bevy::diagnostic::EntityCountDiagnosticsPlugin::default(),
// .add_plugin(bevy::diagnostic::EntityCountDiagnosticsPlugin::default())
// Uncomment this to add an asset count diagnostics: // Uncomment this to add an asset count diagnostics:
// .add_plugin(bevy::asset::diagnostic::AssetCountDiagnosticsPlugin::<Texture>::default()) // bevy::asset::diagnostic::AssetCountDiagnosticsPlugin::<Texture>::default(),
// Uncomment this to add system info diagnostics: // Uncomment this to add system info diagnostics:
// .add_plugin(bevy::diagnostic::SystemInformationDiagnosticsPlugin::default()) // bevy::diagnostic::SystemInformationDiagnosticsPlugin::default()
))
.run(); .run();
} }

View file

@ -256,7 +256,7 @@ fn main() {
// Plugins are just a grouped set of app builder calls (just like we're doing here). // Plugins are just a grouped set of app builder calls (just like we're doing here).
// We could easily turn our game into a plugin, but you can check out the plugin example for // We could easily turn our game into a plugin, but you can check out the plugin example for
// that :) The plugin below runs our app's "system schedule" once every 5 seconds. // that :) The plugin below runs our app's "system schedule" once every 5 seconds.
.add_plugin(ScheduleRunnerPlugin::run_loop(Duration::from_secs(5))) .add_plugins(ScheduleRunnerPlugin::run_loop(Duration::from_secs(5)))
// `Startup` systems run exactly once BEFORE all other systems. These are generally used for // `Startup` systems run exactly once BEFORE all other systems. These are generally used for
// app initialization code (ex: adding entities and resources) // app initialization code (ex: adding entities and resources)
.add_systems(Startup, startup_system) .add_systems(Startup, startup_system)

View file

@ -25,7 +25,7 @@ fn main() {
let outside_variable = "bar".to_string(); let outside_variable = "bar".to_string();
App::new() App::new()
.add_plugin(LogPlugin::default()) .add_plugins(LogPlugin::default())
// we can use a closure as a system // we can use a closure as a system
.add_systems(Update, simple_closure) .add_systems(Update, simple_closure)
// or we can use a more complex closure, and pass an argument to initialize a Local variable. // or we can use a more complex closure, and pass an argument to initialize a Local variable.

View file

@ -11,7 +11,7 @@ fn main() {
App::new() App::new()
.insert_resource(Message("42".to_string())) .insert_resource(Message("42".to_string()))
.insert_resource(OptionalWarning(Err("Got to rusty?".to_string()))) .insert_resource(OptionalWarning(Err("Got to rusty?".to_string())))
.add_plugin(LogPlugin { .add_plugins(LogPlugin {
level: Level::TRACE, level: Level::TRACE,
filter: "".to_string(), filter: "".to_string(),
}) })

View file

@ -37,9 +37,7 @@ fn main() {
.add_state::<GameState>() .add_state::<GameState>()
.add_systems(Startup, setup) .add_systems(Startup, setup)
// Adds the plugins for each state // Adds the plugins for each state
.add_plugin(splash::SplashPlugin) .add_plugins((splash::SplashPlugin, menu::MenuPlugin, game::GamePlugin))
.add_plugin(menu::MenuPlugin)
.add_plugin(game::GamePlugin)
.run(); .run();
} }

View file

@ -9,8 +9,7 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, MaterialPlugin::<CustomMaterial>::default()))
.add_plugin(MaterialPlugin::<CustomMaterial>::default())
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }

View file

@ -9,8 +9,10 @@ use bevy::{
/// uniform variable. /// uniform variable.
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((
.add_plugin(MaterialPlugin::<ArrayTextureMaterial>::default()) DefaultPlugins,
MaterialPlugin::<ArrayTextureMaterial>::default(),
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, create_array_texture) .add_systems(Update, create_array_texture)
.run(); .run();

View file

@ -23,15 +23,17 @@ const WORKGROUP_SIZE: u32 = 8;
fn main() { fn main() {
App::new() App::new()
.insert_resource(ClearColor(Color::BLACK)) .insert_resource(ClearColor(Color::BLACK))
.add_plugins(DefaultPlugins.set(WindowPlugin { .add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
// uncomment for unthrottled FPS // uncomment for unthrottled FPS
// present_mode: bevy::window::PresentMode::AutoNoVsync, // present_mode: bevy::window::PresentMode::AutoNoVsync,
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(GameOfLifeComputePlugin) GameOfLifeComputePlugin,
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }
@ -70,7 +72,7 @@ impl Plugin for GameOfLifeComputePlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
// Extract the game of life image resource from the main world into the render world // Extract the game of life image resource from the main world into the render world
// for operation on by the compute shader and display on the sprite. // for operation on by the compute shader and display on the sprite.
app.add_plugin(ExtractResourcePlugin::<GameOfLifeImage>::default()); app.add_plugins(ExtractResourcePlugin::<GameOfLifeImage>::default());
let render_app = app.sub_app_mut(RenderApp); let render_app = app.sub_app_mut(RenderApp);
render_app.add_systems(Render, queue_bind_group.in_set(RenderSet::Queue)); render_app.add_systems(Render, queue_bind_group.in_set(RenderSet::Queue));

View file

@ -15,8 +15,7 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, MaterialPlugin::<CustomMaterial>::default()))
.add_plugin(MaterialPlugin::<CustomMaterial>::default())
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }

View file

@ -13,8 +13,10 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((
.add_plugin(MaterialPlugin::<FallbackTestMaterial>::default()) DefaultPlugins,
MaterialPlugin::<FallbackTestMaterial>::default(),
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }

View file

@ -35,12 +35,14 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins.set(AssetPlugin { .add_plugins((
DefaultPlugins.set(AssetPlugin {
// Hot reloading the shader works correctly // Hot reloading the shader works correctly
watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)), watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)),
..default() ..default()
})) }),
.add_plugin(PostProcessPlugin) PostProcessPlugin,
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (rotate, update_settings)) .add_systems(Update, (rotate, update_settings))
.run(); .run();
@ -51,18 +53,19 @@ struct PostProcessPlugin;
impl Plugin for PostProcessPlugin { impl Plugin for PostProcessPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app app.add_plugins((
// The settings will be a component that lives in the main world but will // The settings will be a component that lives in the main world but will
// be extracted to the render world every frame. // be extracted to the render world every frame.
// This makes it possible to control the effect from the main world. // This makes it possible to control the effect from the main world.
// This plugin will take care of extracting it automatically. // This plugin will take care of extracting it automatically.
// It's important to derive [`ExtractComponent`] on [`PostProcessingSettings`] // It's important to derive [`ExtractComponent`] on [`PostProcessingSettings`]
// for this plugin to work correctly. // for this plugin to work correctly.
.add_plugin(ExtractComponentPlugin::<PostProcessSettings>::default()) ExtractComponentPlugin::<PostProcessSettings>::default(),
// The settings will also be the data used in the shader. // The settings will also be the data used in the shader.
// This plugin will prepare the component for the GPU by creating a uniform buffer // This plugin will prepare the component for the GPU by creating a uniform buffer
// and writing the data to that buffer every frame. // and writing the data to that buffer every frame.
.add_plugin(UniformComponentPlugin::<PostProcessSettings>::default()); UniformComponentPlugin::<PostProcessSettings>::default(),
));
// We need to get the render app from the main app // We need to get the render app from the main app
let Ok(render_app) = app.get_sub_app_mut(RenderApp) else { let Ok(render_app) = app.get_sub_app_mut(RenderApp) else {

View file

@ -14,8 +14,7 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, MaterialPlugin::<CustomMaterial>::default()))
.add_plugin(MaterialPlugin::<CustomMaterial>::default())
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }

View file

@ -26,8 +26,7 @@ use bytemuck::{Pod, Zeroable};
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, CustomMaterialPlugin))
.add_plugin(CustomMaterialPlugin)
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }
@ -80,7 +79,7 @@ pub struct CustomMaterialPlugin;
impl Plugin for CustomMaterialPlugin { impl Plugin for CustomMaterialPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_plugin(ExtractComponentPlugin::<InstanceMaterialData>::default()); app.add_plugins(ExtractComponentPlugin::<InstanceMaterialData>::default());
app.sub_app_mut(RenderApp) app.sub_app_mut(RenderApp)
.add_render_command::<Transparent3d, DrawCustom>() .add_render_command::<Transparent3d, DrawCustom>()
.init_resource::<SpecializedMeshPipelines<CustomPipeline>>() .init_resource::<SpecializedMeshPipelines<CustomPipeline>>()

View file

@ -8,8 +8,7 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, MaterialPlugin::<CustomMaterial>::default()))
.add_plugin(MaterialPlugin::<CustomMaterial>::default())
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }

View file

@ -14,8 +14,7 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, MaterialPlugin::<CustomMaterial>::default()))
.add_plugin(MaterialPlugin::<CustomMaterial>::default())
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }

View file

@ -8,8 +8,7 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, MaterialPlugin::<CustomMaterial>::default()))
.add_plugin(MaterialPlugin::<CustomMaterial>::default())
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, rotate_camera) .add_systems(Update, rotate_camera)
.run(); .run();

View file

@ -12,20 +12,22 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins.set(PbrPlugin { .add_plugins((
DefaultPlugins.set(PbrPlugin {
// The prepass is enabled by default on the StandardMaterial, // The prepass is enabled by default on the StandardMaterial,
// but you can disable it if you need to. // but you can disable it if you need to.
// //
// prepass_enabled: false, // prepass_enabled: false,
..default() ..default()
})) }),
.add_plugin(MaterialPlugin::<CustomMaterial>::default()) MaterialPlugin::<CustomMaterial>::default(),
.add_plugin(MaterialPlugin::<PrepassOutputMaterial> { MaterialPlugin::<PrepassOutputMaterial> {
// This material only needs to read the prepass textures, // This material only needs to read the prepass textures,
// but the meshes using it should not contribute to the prepass render, so we can disable it. // but the meshes using it should not contribute to the prepass render, so we can disable it.
prepass_enabled: false, prepass_enabled: false,
..default() ..default()
}) },
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (rotate, toggle_prepass_view)) .add_systems(Update, (rotate, toggle_prepass_view))
// Disabling MSAA for maximum compatibility. Shader prepass with MSAA needs GPU capability MULTISAMPLED_SHADING // Disabling MSAA for maximum compatibility. Shader prepass with MSAA needs GPU capability MULTISAMPLED_SHADING

View file

@ -16,10 +16,11 @@ use std::{num::NonZeroU32, process::exit};
fn main() { fn main() {
let mut app = App::new(); let mut app = App::new();
app.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())); app.add_plugins((
DefaultPlugins.set(ImagePlugin::default_nearest()),
app.add_plugin(GpuFeatureSupportChecker) GpuFeatureSupportChecker,
.add_plugin(MaterialPlugin::<BindlessMaterial>::default()) MaterialPlugin::<BindlessMaterial>::default(),
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.run(); .run();
} }

View file

@ -28,7 +28,8 @@ struct Bird {
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin { .add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
title: "BevyMark".into(), title: "BevyMark".into(),
resolution: (800., 600.).into(), resolution: (800., 600.).into(),
@ -36,9 +37,10 @@ fn main() {
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
.add_plugin(LogDiagnosticsPlugin::default()) LogDiagnosticsPlugin::default(),
))
.insert_resource(BevyCounter { .insert_resource(BevyCounter {
count: 0, count: 0,
color: Color::WHITE, color: Color::WHITE,

View file

@ -20,15 +20,17 @@ const CAMERA_SPEED: f32 = 1000.0;
fn main() { fn main() {
App::new() App::new()
// Since this is also used as a benchmark, we want it to display performance data. // Since this is also used as a benchmark, we want it to display performance data.
.add_plugin(LogDiagnosticsPlugin::default()) .add_plugins((
.add_plugin(FrameTimeDiagnosticsPlugin) LogDiagnosticsPlugin::default(),
.add_plugins(DefaultPlugins.set(WindowPlugin { FrameTimeDiagnosticsPlugin,
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
present_mode: PresentMode::AutoNoVsync, present_mode: PresentMode::AutoNoVsync,
..default() ..default()
}), }),
..default() ..default()
})) }),
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems( .add_systems(
Update, Update,

View file

@ -23,15 +23,17 @@ const FONT_SIZE: f32 = 7.0;
fn main() { fn main() {
let mut app = App::new(); let mut app = App::new();
app.add_plugins(DefaultPlugins.set(WindowPlugin { app.add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
present_mode: PresentMode::AutoNoVsync, present_mode: PresentMode::AutoNoVsync,
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
.add_plugin(LogDiagnosticsPlugin::default()) LogDiagnosticsPlugin::default(),
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, button_system); .add_systems(Update, button_system);

View file

@ -21,15 +21,17 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin { .add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
present_mode: PresentMode::AutoNoVsync, present_mode: PresentMode::AutoNoVsync,
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
.add_plugin(LogDiagnosticsPlugin::default()) LogDiagnosticsPlugin::default(),
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (move_camera, print_mesh_count)) .add_systems(Update, (move_camera, print_mesh_count))
.run(); .run();

View file

@ -20,16 +20,18 @@ struct Foxes {
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin { .add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
title: "🦊🦊🦊 Many Foxes! 🦊🦊🦊".into(), title: "🦊🦊🦊 Many Foxes! 🦊🦊🦊".into(),
present_mode: PresentMode::AutoNoVsync, present_mode: PresentMode::AutoNoVsync,
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
.add_plugin(LogDiagnosticsPlugin::default()) LogDiagnosticsPlugin::default(),
))
.insert_resource(Foxes { .insert_resource(Foxes {
count: std::env::args() count: std::env::args()
.nth(1) .nth(1)

View file

@ -10,15 +10,17 @@ const SYSTEM_COUNT: u32 = 10;
fn main() { fn main() {
let mut app = App::new(); let mut app = App::new();
app.add_plugins(DefaultPlugins.set(WindowPlugin { app.add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
title: "Many Debug Lines".to_string(), title: "Many Debug Lines".to_string(),
present_mode: PresentMode::AutoNoVsync, present_mode: PresentMode::AutoNoVsync,
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
))
.insert_resource(Config { .insert_resource(Config {
line_count: 50_000, line_count: 50_000,
fancy: false, fancy: false,

View file

@ -14,15 +14,17 @@ use bevy::{
fn main() { fn main() {
let mut app = App::new(); let mut app = App::new();
app.add_plugins(DefaultPlugins.set(WindowPlugin { app.add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
present_mode: PresentMode::AutoNoVsync, present_mode: PresentMode::Immediate,
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
.add_plugin(LogDiagnosticsPlugin::default()) LogDiagnosticsPlugin::default(),
))
.add_systems(Startup, setup); .add_systems(Startup, setup);
if std::env::args().any(|arg| arg == "recompute-text") { if std::env::args().any(|arg| arg == "recompute-text") {

View file

@ -15,7 +15,8 @@ use rand::{thread_rng, Rng};
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin { .add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
resolution: (1024.0, 768.0).into(), resolution: (1024.0, 768.0).into(),
title: "many_lights".into(), title: "many_lights".into(),
@ -23,12 +24,13 @@ fn main() {
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
.add_plugin(LogDiagnosticsPlugin::default()) LogDiagnosticsPlugin::default(),
LogVisibleLights,
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (move_camera, print_light_count)) .add_systems(Update, (move_camera, print_light_count))
.add_plugin(LogVisibleLights)
.run(); .run();
} }

View file

@ -28,15 +28,17 @@ fn main() {
std::env::args().nth(1).unwrap_or_default() == "--colored", std::env::args().nth(1).unwrap_or_default() == "--colored",
)) ))
// Since this is also used as a benchmark, we want it to display performance data. // Since this is also used as a benchmark, we want it to display performance data.
.add_plugin(LogDiagnosticsPlugin::default()) .add_plugins((
.add_plugin(FrameTimeDiagnosticsPlugin) LogDiagnosticsPlugin::default(),
.add_plugins(DefaultPlugins.set(WindowPlugin { FrameTimeDiagnosticsPlugin,
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
present_mode: PresentMode::AutoNoVsync, present_mode: PresentMode::AutoNoVsync,
..default() ..default()
}), }),
..default() ..default()
})) }),
))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems( .add_systems(
Update, Update,

View file

@ -11,15 +11,17 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin { .add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
present_mode: PresentMode::Immediate, present_mode: PresentMode::Immediate,
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
.add_plugin(LogDiagnosticsPlugin::default()) LogDiagnosticsPlugin::default(),
))
.add_systems(Startup, spawn) .add_systems(Startup, spawn)
.add_systems(Update, update_text_bounds) .add_systems(Update, update_text_bounds)
.run(); .run();

View file

@ -183,8 +183,7 @@ fn main() {
App::new() App::new()
.insert_resource(cfg) .insert_resource(cfg)
.add_plugins(MinimalPlugins) .add_plugins((MinimalPlugins, TransformPlugin))
.add_plugin(TransformPlugin)
.add_systems(Startup, setup) .add_systems(Startup, setup)
// Updating transforms *must* be done before `CoreSet::PostUpdate` // Updating transforms *must* be done before `CoreSet::PostUpdate`
// or the hierarchy will momentarily be in an invalid state. // or the hierarchy will momentarily be in an invalid state.

View file

@ -26,7 +26,7 @@ fn main() {
color: Color::WHITE, color: Color::WHITE,
brightness: 1.0 / 5.0f32, brightness: 1.0 / 5.0f32,
}) })
.add_plugins( .add_plugins((
DefaultPlugins DefaultPlugins
.set(WindowPlugin { .set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
@ -40,9 +40,9 @@ fn main() {
.unwrap_or_else(|_| ".".to_string()), .unwrap_or_else(|_| ".".to_string()),
watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)), watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)),
}), }),
) CameraControllerPlugin,
.add_plugin(CameraControllerPlugin) SceneViewerPlugin,
.add_plugin(SceneViewerPlugin) ))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(PreUpdate, setup_scene_after_load); .add_systems(PreUpdate, setup_scene_after_load);

View file

@ -10,8 +10,7 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins((DefaultPlugins, FrameTimeDiagnosticsPlugin))
.add_plugin(FrameTimeDiagnosticsPlugin)
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (text_update_system, text_color_system)) .add_systems(Update, (text_update_system, text_color_system))
.run(); .run();

View file

@ -8,14 +8,16 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin { .add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
present_mode: PresentMode::AutoNoVsync, present_mode: PresentMode::AutoNoVsync,
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
))
.add_systems(Startup, infotext_system) .add_systems(Startup, infotext_system)
.add_systems(Update, change_text_system) .add_systems(Update, change_text_system)
.run(); .run();

View file

@ -9,7 +9,8 @@ use bevy::{
fn main() { fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin { .add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window { primary_window: Some(Window {
title: "I am a window!".into(), title: "I am a window!".into(),
resolution: (500., 300.).into(), resolution: (500., 300.).into(),
@ -22,9 +23,10 @@ fn main() {
..default() ..default()
}), }),
..default() ..default()
})) }),
.add_plugin(LogDiagnosticsPlugin::default()) LogDiagnosticsPlugin::default(),
.add_plugin(FrameTimeDiagnosticsPlugin) FrameTimeDiagnosticsPlugin,
))
.add_systems( .add_systems(
Update, Update,
( (