Skip to content

Commit

Permalink
Implement plugin dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
NthTensor committed Jan 16, 2024
1 parent 2e8daba commit 167c631
Show file tree
Hide file tree
Showing 18 changed files with 378 additions and 182 deletions.
15 changes: 7 additions & 8 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,17 +723,15 @@ impl App {
/// 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 using [`PluginSet`]s, which allow plugins to be
/// added, removed, disabled, and reordered.
///
/// [`PluginGroup`] is a trait that allows types to configure and add plugins to a set.
/// There are built-in [`PluginGroup`]s that provide core engine functionality.
/// 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
/// before / after another plugin), call [`build()`](super::PluginGroup::build) on the group,
/// 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.
/// You can also specify a group of [`Plugin`]s by using a tuple over [`Plugin`]s,
/// [`PluginSet`]s, and [`PluginGroup`]s. See [`Plugins`] for more details.
///
/// ## Examples
/// ```
Expand Down Expand Up @@ -769,7 +767,8 @@ impl App {
"Plugins cannot be added after App::cleanup() or App::finish() has been called."
);
}
plugins.add_to_set(&mut self.plugin_set);
let plugin_set = std::mem::take(&mut self.plugin_set);
self.plugin_set = plugins.add_to_set(plugin_set);
self
}

Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub mod prelude {
PostStartup, PostUpdate, PreStartup, PreUpdate, SpawnScene, Startup, StateTransition,
Update,
},
DynamicPlugin, Plugin, PluginSet,
DynamicPlugin, Plugin, PluginCollectionExt, PluginExt, PluginGroup, PluginManifest,
PluginSet,
};
}
433 changes: 304 additions & 129 deletions crates/bevy_app/src/plugin.rs

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions crates/bevy_asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use crate::{
io::{embedded::EmbeddedAssetRegistry, AssetSourceBuilder, AssetSourceBuilders, AssetSourceId},
processor::{AssetProcessor, Process},
};
use bevy_app::{App, First, MainScheduleOrder, Plugin, PostUpdate};
use bevy_app::{App, First, MainScheduleOrder, Plugin, PostUpdate, MainSchedulePlugin, PluginManifest};
use bevy_ecs::{
reflect::AppTypeRegistry,
schedule::{IntoSystemConfigs, IntoSystemSetConfigs, ScheduleLabel, SystemSet},
Expand Down Expand Up @@ -223,6 +223,11 @@ impl Plugin for AssetPlugin {
order.insert_after(First, UpdateAssets);
order.insert_after(PostUpdate, AssetEvents);
}

fn configure(&self, manifest: &mut PluginManifest) {
// This plugin directly uses [`MainScheduleOrder`].
manifest.add_dependency::<MainSchedulePlugin>(true);
}
}

pub trait Asset: VisitAssetDependencies + TypePath + Send + Sync + 'static {}
Expand Down Expand Up @@ -549,6 +554,7 @@ mod tests {
LogPlugin::default(),
AssetPlugin::default(),
));
app.build();
(app, gate_opener)
}

Expand Down Expand Up @@ -1213,8 +1219,9 @@ mod tests {
#[test]
fn ignore_system_ambiguities_on_assets() {
let mut app = App::new();
app.add_plugins(AssetPlugin::default())
.init_asset::<CoolText>();
app.add_plugins(AssetPlugin::default());
app.build();
app.init_asset::<CoolText>();

fn uses_assets(_asset: ResMut<Assets<CoolText>>) {}
app.add_systems(Update, (uses_assets, uses_assets));
Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_asset/src/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,9 @@ mod tests {
#[test]
fn test_reflect_asset_operations() {
let mut app = App::new();
app.add_plugins(AssetPlugin::default())
.init_asset::<AssetType>()
app.add_plugins(AssetPlugin::default());
app.build();
app.init_asset::<AssetType>()
.register_asset_reflect::<AssetType>();

let reflect_asset = {
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ mod tests {
fn runs_spawn_local_tasks() {
let mut app = App::new();
app.add_plugins((TaskPoolPlugin::default(), TypeRegistrationPlugin));
app.build();

let (async_tx, async_rx) = crossbeam_channel::unbounded();
AsyncComputeTaskPool::get()
Expand Down Expand Up @@ -207,6 +208,7 @@ mod tests {
TypeRegistrationPlugin,
FrameCountPlugin,
));
app.build();
app.update();

let frame_count = app.world.resource::<FrameCount>();
Expand Down
41 changes: 21 additions & 20 deletions crates/bevy_internal/src/default_plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ use bevy_app::{Plugin, PluginGroup, PluginSet};
pub struct DefaultPlugins;

impl PluginGroup for DefaultPlugins {
fn build(self, set: &mut PluginSet) {
set.add_plugins((
fn build(self, mut set: PluginSet) -> PluginSet {
set = set.add_plugins((
bevy_log::LogPlugin::default(),
bevy_core::TaskPoolPlugin::default(),
bevy_core::TypeRegistrationPlugin,
Expand All @@ -50,89 +50,90 @@ impl PluginGroup for DefaultPlugins {
bevy_input::InputPlugin,
bevy_window::WindowPlugin::default(),
bevy_a11y::AccessibilityPlugin,
IgnoreAmbiguitiesPlugin,
));

#[cfg(feature = "bevy_asset")]
{
set.add_plugins(bevy_asset::AssetPlugin::default());
set = set.add_plugins(bevy_asset::AssetPlugin::default());
}

#[cfg(feature = "bevy_scene")]
{
set.add_plugins(bevy_scene::ScenePlugin);
set = set.add_plugins(bevy_scene::ScenePlugin);
}

#[cfg(feature = "bevy_winit")]
{
set.add_plugins(bevy_winit::WinitPluginGroup::default());
set = set.add_plugins(bevy_winit::WinitPluginGroup::default());
}

#[cfg(feature = "bevy_render")]
{
set.add_plugins((
set = set.add_plugins((
bevy_render::RenderPlugin::default(),
bevy_render::texture::ImagePlugin::default(),
));

#[cfg(all(not(target_arch = "wasm32"), feature = "multi-threaded"))]
{
set.add_plugins(bevy_render::pipelined_rendering::PipelinedRenderingPlugin);
set = set.add_plugins(bevy_render::pipelined_rendering::PipelinedRenderingPlugin);
}
}

#[cfg(feature = "bevy_core_pipeline")]
{
set.add_plugins(bevy_core_pipeline::CorePipelinePlugin);
set = set.add_plugins(bevy_core_pipeline::CorePipelinePlugin);
}

#[cfg(feature = "bevy_sprite")]
{
set.add_plugins(bevy_sprite::SpritePlugin);
set = set.add_plugins(bevy_sprite::SpritePlugin);
}

#[cfg(feature = "bevy_text")]
{
set.add_plugins(bevy_text::TextPlugin);
set = set.add_plugins(bevy_text::TextPlugin);
}

#[cfg(feature = "bevy_ui")]
{
set.add_plugins(bevy_ui::UiPlugin);
set = set.add_plugins(bevy_ui::UiPlugin);
}

#[cfg(feature = "bevy_pbr")]
{
set.add_plugins(bevy_pbr::PbrPlugin::default());
set = set.add_plugins(bevy_pbr::PbrPlugin::default());
}

// NOTE: Load this after renderer initialization so that it knows about the supported
// compressed texture formats
#[cfg(feature = "bevy_gltf")]
{
set.add_plugins(bevy_gltf::GltfPlugin::default());
set = set.add_plugins(bevy_gltf::GltfPlugin::default());
}

#[cfg(feature = "bevy_audio")]
{
set.add_plugins(bevy_audio::AudioPlugin::default());
set = set.add_plugins(bevy_audio::AudioPlugin::default());
}

#[cfg(feature = "bevy_gilrs")]
{
set.add_plugins(bevy_gilrs::GilrsPlugin);
set = set.add_plugins(bevy_gilrs::GilrsPlugin);
}

#[cfg(feature = "bevy_animation")]
{
set.add_plugins(bevy_animation::AnimationPlugin);
set = set.add_plugins(bevy_animation::AnimationPlugin);
}

#[cfg(feature = "bevy_gizmos")]
{
set.add_plugins(bevy_gizmos::GizmoPlugin);
set = set.add_plugins(bevy_gizmos::GizmoPlugin);
}

set.add_plugins(IgnoreAmbiguitiesPlugin);
set
}
}

Expand Down Expand Up @@ -194,13 +195,13 @@ impl Plugin for IgnoreAmbiguitiesPlugin {
pub struct MinimalPlugins;

impl PluginGroup for MinimalPlugins {
fn build(self, set: &mut PluginSet) {
fn build(self, set: PluginSet) -> PluginSet {
set.add_plugins((
bevy_core::TaskPoolPlugin::default(),
bevy_core::TypeRegistrationPlugin,
bevy_core::FrameCountPlugin,
bevy_time::TimePlugin,
bevy_app::ScheduleRunnerPlugin::default(),
));
))
}
}
8 changes: 4 additions & 4 deletions crates/bevy_log/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ use tracing_subscriber::{prelude::*, registry::Registry, EnvFilter};
///
/// You can configure this plugin.
/// ```no_run
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup};
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup, PluginCollectionExt};
/// # use bevy_log::LogPlugin;
/// # use bevy_utils::tracing::Level;
/// fn main() {
/// App::new()
/// .add_plugins(DefaultPlugins.set(LogPlugin {
/// .add_plugins(DefaultPlugins.replace(LogPlugin {
/// level: Level::DEBUG,
/// filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(),
/// }))
Expand All @@ -79,11 +79,11 @@ use tracing_subscriber::{prelude::*, registry::Registry, EnvFilter};
/// If you want to setup your own tracing collector, you should disable this
/// plugin from `DefaultPlugins`:
/// ```no_run
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup};
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup, PluginCollectionExt};
/// # use bevy_log::LogPlugin;
/// fn main() {
/// App::new()
/// .add_plugins(DefaultPlugins.build().disable::<LogPlugin>())
/// .add_plugins(DefaultPlugins.disable::<LogPlugin>())
/// .run();
/// }
/// ```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ error[E0277]: the trait bound `TupleStruct: Deref` is not satisfied
| ^^^^^^^^^^^ the trait `Deref` is not implemented for `TupleStruct`
|
note: required by a bound in `DerefMut`
--> $RUST/core/src/ops/deref.rs
--> /build/rustc-1.74.0-src/library/core/src/ops/deref.rs:180:1

error[E0277]: the trait bound `Struct: Deref` is not satisfied
--> tests/deref_mut_derive/missing_deref.fail.rs:7:8
Expand All @@ -14,7 +14,7 @@ error[E0277]: the trait bound `Struct: Deref` is not satisfied
| ^^^^^^ the trait `Deref` is not implemented for `Struct`
|
note: required by a bound in `DerefMut`
--> $RUST/core/src/ops/deref.rs
--> /build/rustc-1.74.0-src/library/core/src/ops/deref.rs:180:1

error[E0277]: the trait bound `TupleStruct: Deref` is not satisfied
--> tests/deref_mut_derive/missing_deref.fail.rs:3:10
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_render/src/view/visibility/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ mod test {
#[test]
fn visibility_propagation() {
let mut app = App::new();
app.build();
app.add_systems(Update, visibility_propagate_system);

let root1 = app.world.spawn(visibility_bundle(Visibility::Hidden)).id();
Expand Down Expand Up @@ -572,6 +573,7 @@ mod test {
use Visibility::{Hidden, Inherited, Visible};

let mut app = App::new();
app.build();
app.add_systems(Update, visibility_propagate_system);

let root1 = app.world.spawn(visibility_bundle(Visible)).id();
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_sprite/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ mod test {
.contains::<Aabb>());

// Run system
app.build();
app.update();

// Verify the AABB exists
Expand Down Expand Up @@ -243,6 +244,7 @@ mod test {
.id();

// Create initial AABB
app.build();
app.update();

// Get the initial AABB
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_transform/src/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ mod tests {
fn match_transform_propagation_systems_inner(transforms: Vec<Transform>) {
let mut app = App::new();
app.add_plugins(TransformPluginGroup);
app.build();

let mut entity = None;

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,11 @@ impl Plugin for TransformPlugin {
pub struct TransformPluginGroup;

impl PluginGroup for TransformPluginGroup {
fn build(self, set: &mut PluginSet) {
fn build(self, set: PluginSet) -> PluginSet {
set.add_plugins((
TransformPlugin,
ValidParentCheckPlugin::<GlobalTransform>::default(),
));
))
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/bevy_transform/src/systems.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ mod test {
#[test]
fn correct_transforms_when_no_children() {
let mut app = App::new();
app.build();
ComputeTaskPool::get_or_init(TaskPool::default);

app.add_systems(Update, (sync_simple_transforms, propagate_transforms));
Expand Down
12 changes: 7 additions & 5 deletions crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
S#![warn(missing_docs)]
#![warn(missing_docs)]
//! `bevy_winit` provides utilities to handle window creation and the eventloop through [`winit`]
//!
//! Most commonly, the [`WinitPlugin`] is used as part of
Expand All @@ -18,7 +18,7 @@ use system::{changed_windows, create_windows, despawn_windows, CachedWindow};
pub use winit_config::*;
pub use winit_windows::*;

use bevy_app::{App, AppExit, Last, Plugin, PluginsState, PluginSet};
use bevy_app::{App, AppExit, Last, Plugin, PluginGroup, PluginSet, PluginsState};
use bevy_ecs::event::{Events, ManualEventReader};
use bevy_ecs::prelude::*;
use bevy_ecs::system::{SystemParam, SystemState};
Expand Down Expand Up @@ -217,13 +217,15 @@ impl Plugin for WinitPlugin {
}

#[derive(Default)]
/// A plugin group which adds [`WinitPluginGroup`] and it's dependencies:
/// + [`crate::accessibility::AccessKitPlugin`]
pub struct WinitPluginGroup {
winit_plugin: WinitPlugin
winit_plugin: WinitPlugin,
}

impl PluginGroup for WinitPluginGroup {
fn build(self) -> PluginSet {
PluginSet::new().add_plugins((self.winit_plugin, AccessKitPlugin))
fn build(self, set: PluginSet) -> PluginSet {
set.add_plugins((self.winit_plugin, AccessKitPlugin))
}
}

Expand Down
Loading

0 comments on commit 167c631

Please sign in to comment.