mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
app: PluginGroups and DefaultPlugins (#744)
This commit is contained in:
parent
a592ef0562
commit
bf2a917b81
10 changed files with 242 additions and 56 deletions
|
@ -154,6 +154,10 @@ path = "examples/app/headless.rs"
|
||||||
name = "plugin"
|
name = "plugin"
|
||||||
path = "examples/app/plugin.rs"
|
path = "examples/app/plugin.rs"
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "plugin_group"
|
||||||
|
path = "examples/app/plugin_group.rs"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "return_after_run"
|
name = "return_after_run"
|
||||||
path = "examples/app/return_after_run.rs"
|
path = "examples/app/return_after_run.rs"
|
||||||
|
|
|
@ -17,6 +17,7 @@ keywords = ["bevy"]
|
||||||
bevy_derive = { path = "../bevy_derive", version = "0.2.1" }
|
bevy_derive = { path = "../bevy_derive", version = "0.2.1" }
|
||||||
bevy_ecs = { path = "../bevy_ecs", version = "0.2.1" }
|
bevy_ecs = { path = "../bevy_ecs", version = "0.2.1" }
|
||||||
bevy_math = { path = "../bevy_math", version = "0.2.1" }
|
bevy_math = { path = "../bevy_math", version = "0.2.1" }
|
||||||
|
bevy_utils = { path = "../bevy_utils", version = "0.2.1" }
|
||||||
|
|
||||||
# other
|
# other
|
||||||
log = { version = "0.4", features = ["release_max_level_info"] }
|
log = { version = "0.4", features = ["release_max_level_info"] }
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
app::{App, AppExit},
|
app::{App, AppExit},
|
||||||
event::Events,
|
event::Events,
|
||||||
plugin::Plugin,
|
plugin::Plugin,
|
||||||
stage, startup_stage,
|
stage, startup_stage, PluginGroup, PluginGroupBuilder,
|
||||||
};
|
};
|
||||||
use bevy_ecs::{FromResources, IntoQuerySystem, Resources, System, World};
|
use bevy_ecs::{FromResources, IntoQuerySystem, Resources, System, World};
|
||||||
|
|
||||||
|
@ -271,4 +271,23 @@ impl AppBuilder {
|
||||||
plugin.build(self);
|
plugin.build(self);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_plugin_group<T: PluginGroup>(&mut self, mut group: T) -> &mut Self {
|
||||||
|
let mut plugin_group_builder = PluginGroupBuilder::default();
|
||||||
|
group.build(&mut plugin_group_builder);
|
||||||
|
plugin_group_builder.finish(self);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_plugin_group_with<T, F>(&mut self, mut group: T, func: F) -> &mut Self
|
||||||
|
where
|
||||||
|
T: PluginGroup,
|
||||||
|
F: FnOnce(&mut PluginGroupBuilder) -> &mut PluginGroupBuilder,
|
||||||
|
{
|
||||||
|
let mut plugin_group_builder = PluginGroupBuilder::default();
|
||||||
|
group.build(&mut plugin_group_builder);
|
||||||
|
func(&mut plugin_group_builder);
|
||||||
|
plugin_group_builder.finish(self);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ mod app;
|
||||||
mod app_builder;
|
mod app_builder;
|
||||||
mod event;
|
mod event;
|
||||||
mod plugin;
|
mod plugin;
|
||||||
|
mod plugin_group;
|
||||||
mod schedule_runner;
|
mod schedule_runner;
|
||||||
|
|
||||||
pub use app::*;
|
pub use app::*;
|
||||||
|
@ -14,6 +15,7 @@ pub use app_builder::*;
|
||||||
pub use bevy_derive::DynamicPlugin;
|
pub use bevy_derive::DynamicPlugin;
|
||||||
pub use event::*;
|
pub use event::*;
|
||||||
pub use plugin::*;
|
pub use plugin::*;
|
||||||
|
pub use plugin_group::*;
|
||||||
pub use schedule_runner::*;
|
pub use schedule_runner::*;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
|
@ -21,7 +23,6 @@ pub mod prelude {
|
||||||
app::App,
|
app::App,
|
||||||
app_builder::AppBuilder,
|
app_builder::AppBuilder,
|
||||||
event::{EventReader, Events},
|
event::{EventReader, Events},
|
||||||
plugin::Plugin,
|
stage, DynamicPlugin, Plugin, PluginGroup,
|
||||||
stage, DynamicPlugin,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
103
crates/bevy_app/src/plugin_group.rs
Normal file
103
crates/bevy_app/src/plugin_group.rs
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
use crate::{AppBuilder, Plugin};
|
||||||
|
use bevy_utils::HashMap;
|
||||||
|
use std::any::TypeId;
|
||||||
|
|
||||||
|
pub trait PluginGroup {
|
||||||
|
fn build(&mut self, group: &mut PluginGroupBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PluginEntry {
|
||||||
|
plugin: Box<dyn Plugin>,
|
||||||
|
enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct PluginGroupBuilder {
|
||||||
|
plugins: HashMap<TypeId, PluginEntry>,
|
||||||
|
order: Vec<TypeId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PluginGroupBuilder {
|
||||||
|
pub fn add<T: Plugin>(&mut self, plugin: T) -> &mut Self {
|
||||||
|
self.order.push(TypeId::of::<T>());
|
||||||
|
self.plugins.insert(
|
||||||
|
TypeId::of::<T>(),
|
||||||
|
PluginEntry {
|
||||||
|
plugin: Box::new(plugin),
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_before<Target: Plugin, T: Plugin>(&mut self, plugin: T) -> &mut Self {
|
||||||
|
let target_index = self
|
||||||
|
.order
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_i, ty)| **ty == TypeId::of::<Target>())
|
||||||
|
.map(|(i, _)| i)
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
panic!("Plugin does not exist: {}", std::any::type_name::<Target>())
|
||||||
|
});
|
||||||
|
self.order.insert(target_index, TypeId::of::<T>());
|
||||||
|
self.plugins.insert(
|
||||||
|
TypeId::of::<T>(),
|
||||||
|
PluginEntry {
|
||||||
|
plugin: Box::new(plugin),
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_after<Target: Plugin, T: Plugin>(&mut self, plugin: T) -> &mut Self {
|
||||||
|
let target_index = self
|
||||||
|
.order
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_i, ty)| **ty == TypeId::of::<Target>())
|
||||||
|
.map(|(i, _)| i)
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
panic!("Plugin does not exist: {}", std::any::type_name::<Target>())
|
||||||
|
});
|
||||||
|
self.order.insert(target_index + 1, TypeId::of::<T>());
|
||||||
|
self.plugins.insert(
|
||||||
|
TypeId::of::<T>(),
|
||||||
|
PluginEntry {
|
||||||
|
plugin: Box::new(plugin),
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn enable<T: Plugin>(&mut self) -> &mut Self {
|
||||||
|
let mut plugin_entry = self
|
||||||
|
.plugins
|
||||||
|
.get_mut(&TypeId::of::<T>())
|
||||||
|
.expect("Cannot enable a plugin that does not exist");
|
||||||
|
plugin_entry.enabled = true;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn disable<T: Plugin>(&mut self) -> &mut Self {
|
||||||
|
let mut plugin_entry = self
|
||||||
|
.plugins
|
||||||
|
.get_mut(&TypeId::of::<T>())
|
||||||
|
.expect("Cannot disable a plugin that does not exist");
|
||||||
|
plugin_entry.enabled = false;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finish(self, app: &mut AppBuilder) {
|
||||||
|
for ty in self.order.iter() {
|
||||||
|
if let Some(entry) = self.plugins.get(ty) {
|
||||||
|
if entry.enabled {
|
||||||
|
log::debug!("added plugin: {}", entry.plugin.name());
|
||||||
|
entry.plugin.build(app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
examples/app/plugin_group.rs
Normal file
50
examples/app/plugin_group.rs
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
use bevy::{app::PluginGroupBuilder, prelude::*};
|
||||||
|
|
||||||
|
/// PluginGroups are a way to group sets of plugins that should be registered together.
|
||||||
|
fn main() {
|
||||||
|
App::build()
|
||||||
|
// The app.add_default_plugins() you see in all of the examples is just an alias for this:
|
||||||
|
.add_plugin_group(DefaultPlugins)
|
||||||
|
// Adding a plugin group adds all plugins in the group by default
|
||||||
|
.add_plugin_group(HelloWorldPlugins)
|
||||||
|
// You can also modify a PluginGroup (such as disabling plugins) like this:
|
||||||
|
// .add_plugin_group_with(HelloWorldPlugins, |group| {
|
||||||
|
// group
|
||||||
|
// .disable::<PrintWorldPlugin>()
|
||||||
|
// .add_before::<PrintHelloPlugin, _>(bevy::diagnostic::PrintDiagnosticsPlugin::default())
|
||||||
|
// })
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A group of plugins that produce the "hello world" behavior
|
||||||
|
pub struct HelloWorldPlugins;
|
||||||
|
|
||||||
|
impl PluginGroup for HelloWorldPlugins {
|
||||||
|
fn build(&mut self, group: &mut PluginGroupBuilder) {
|
||||||
|
group.add(PrintHelloPlugin).add(PrintWorldPlugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PrintHelloPlugin;
|
||||||
|
|
||||||
|
impl Plugin for PrintHelloPlugin {
|
||||||
|
fn build(&self, app: &mut AppBuilder) {
|
||||||
|
app.add_system(print_hello_system.system());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_hello_system() {
|
||||||
|
println!("hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PrintWorldPlugin;
|
||||||
|
|
||||||
|
impl Plugin for PrintWorldPlugin {
|
||||||
|
fn build(&self, app: &mut AppBuilder) {
|
||||||
|
app.add_system(print_world_system.system());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_world_system() {
|
||||||
|
println!("world");
|
||||||
|
}
|
|
@ -1,50 +0,0 @@
|
||||||
use crate::app::AppBuilder;
|
|
||||||
|
|
||||||
pub trait AddDefaultPlugins {
|
|
||||||
fn add_default_plugins(&mut self) -> &mut Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AddDefaultPlugins for AppBuilder {
|
|
||||||
fn add_default_plugins(&mut self) -> &mut Self {
|
|
||||||
self.add_plugin(bevy_type_registry::TypeRegistryPlugin::default());
|
|
||||||
self.add_plugin(bevy_core::CorePlugin::default());
|
|
||||||
self.add_plugin(bevy_transform::TransformPlugin::default());
|
|
||||||
self.add_plugin(bevy_diagnostic::DiagnosticsPlugin::default());
|
|
||||||
self.add_plugin(bevy_input::InputPlugin::default());
|
|
||||||
self.add_plugin(bevy_window::WindowPlugin::default());
|
|
||||||
self.add_plugin(bevy_asset::AssetPlugin::default());
|
|
||||||
self.add_plugin(bevy_scene::ScenePlugin::default());
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_render")]
|
|
||||||
self.add_plugin(bevy_render::RenderPlugin::default());
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_sprite")]
|
|
||||||
self.add_plugin(bevy_sprite::SpritePlugin::default());
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_pbr")]
|
|
||||||
self.add_plugin(bevy_pbr::PbrPlugin::default());
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_ui")]
|
|
||||||
self.add_plugin(bevy_ui::UiPlugin::default());
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_text")]
|
|
||||||
self.add_plugin(bevy_text::TextPlugin::default());
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_audio")]
|
|
||||||
self.add_plugin(bevy_audio::AudioPlugin::default());
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_gilrs")]
|
|
||||||
self.add_plugin(bevy_gilrs::GilrsPlugin::default());
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_gltf")]
|
|
||||||
self.add_plugin(bevy_gltf::GltfPlugin::default());
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_winit")]
|
|
||||||
self.add_plugin(bevy_winit::WinitPlugin::default());
|
|
||||||
|
|
||||||
#[cfg(feature = "bevy_wgpu")]
|
|
||||||
self.add_plugin(bevy_wgpu::WgpuPlugin::default());
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
58
src/default_plugins.rs
Normal file
58
src/default_plugins.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
use bevy_app::{PluginGroup, PluginGroupBuilder};
|
||||||
|
|
||||||
|
use crate::app::AppBuilder;
|
||||||
|
|
||||||
|
pub struct DefaultPlugins;
|
||||||
|
|
||||||
|
impl PluginGroup for DefaultPlugins {
|
||||||
|
fn build(&mut self, group: &mut PluginGroupBuilder) {
|
||||||
|
group.add(bevy_type_registry::TypeRegistryPlugin::default());
|
||||||
|
group.add(bevy_core::CorePlugin::default());
|
||||||
|
group.add(bevy_transform::TransformPlugin::default());
|
||||||
|
group.add(bevy_diagnostic::DiagnosticsPlugin::default());
|
||||||
|
group.add(bevy_input::InputPlugin::default());
|
||||||
|
group.add(bevy_window::WindowPlugin::default());
|
||||||
|
group.add(bevy_asset::AssetPlugin::default());
|
||||||
|
group.add(bevy_scene::ScenePlugin::default());
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_render")]
|
||||||
|
group.add(bevy_render::RenderPlugin::default());
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_sprite")]
|
||||||
|
group.add(bevy_sprite::SpritePlugin::default());
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_pbr")]
|
||||||
|
group.add(bevy_pbr::PbrPlugin::default());
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_ui")]
|
||||||
|
group.add(bevy_ui::UiPlugin::default());
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_text")]
|
||||||
|
group.add(bevy_text::TextPlugin::default());
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_audio")]
|
||||||
|
group.add(bevy_audio::AudioPlugin::default());
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_gilrs")]
|
||||||
|
group.add(bevy_gilrs::GilrsPlugin::default());
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_gltf")]
|
||||||
|
group.add(bevy_gltf::GltfPlugin::default());
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_winit")]
|
||||||
|
group.add(bevy_winit::WinitPlugin::default());
|
||||||
|
|
||||||
|
#[cfg(feature = "bevy_wgpu")]
|
||||||
|
group.add(bevy_wgpu::WgpuPlugin::default());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait AddDefaultPlugins {
|
||||||
|
fn add_default_plugins(&mut self) -> &mut Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AddDefaultPlugins for AppBuilder {
|
||||||
|
fn add_default_plugins(&mut self) -> &mut Self {
|
||||||
|
self.add_plugin_group(DefaultPlugins)
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,10 +37,9 @@
|
||||||
html_favicon_url = "https://bevyengine.org/assets/icon.png"
|
html_favicon_url = "https://bevyengine.org/assets/icon.png"
|
||||||
)]
|
)]
|
||||||
|
|
||||||
mod add_default_plugins;
|
mod default_plugins;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
|
||||||
pub use add_default_plugins::*;
|
|
||||||
pub use bevy_app as app;
|
pub use bevy_app as app;
|
||||||
pub use bevy_asset as asset;
|
pub use bevy_asset as asset;
|
||||||
pub use bevy_core as core;
|
pub use bevy_core as core;
|
||||||
|
@ -55,6 +54,7 @@ pub use bevy_transform as transform;
|
||||||
pub use bevy_type_registry as type_registry;
|
pub use bevy_type_registry as type_registry;
|
||||||
pub use bevy_utils as utils;
|
pub use bevy_utils as utils;
|
||||||
pub use bevy_window as window;
|
pub use bevy_window as window;
|
||||||
|
pub use default_plugins::*;
|
||||||
|
|
||||||
#[cfg(feature = "bevy_audio")]
|
#[cfg(feature = "bevy_audio")]
|
||||||
pub use bevy_audio as audio;
|
pub use bevy_audio as audio;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
app::prelude::*, asset::prelude::*, core::prelude::*, ecs::prelude::*, input::prelude::*,
|
app::prelude::*, asset::prelude::*, core::prelude::*, ecs::prelude::*, input::prelude::*,
|
||||||
math::prelude::*, property::prelude::*, scene::prelude::*, transform::prelude::*,
|
math::prelude::*, property::prelude::*, scene::prelude::*, transform::prelude::*,
|
||||||
type_registry::RegisterType, window::prelude::*, AddDefaultPlugins,
|
type_registry::RegisterType, window::prelude::*, AddDefaultPlugins, DefaultPlugins,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "bevy_audio")]
|
#[cfg(feature = "bevy_audio")]
|
||||||
|
|
Loading…
Reference in a new issue