mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +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"
|
||||
path = "examples/app/plugin.rs"
|
||||
|
||||
[[example]]
|
||||
name = "plugin_group"
|
||||
path = "examples/app/plugin_group.rs"
|
||||
|
||||
[[example]]
|
||||
name = "return_after_run"
|
||||
path = "examples/app/return_after_run.rs"
|
||||
|
|
|
@ -17,6 +17,7 @@ keywords = ["bevy"]
|
|||
bevy_derive = { path = "../bevy_derive", version = "0.2.1" }
|
||||
bevy_ecs = { path = "../bevy_ecs", version = "0.2.1" }
|
||||
bevy_math = { path = "../bevy_math", version = "0.2.1" }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.2.1" }
|
||||
|
||||
# other
|
||||
log = { version = "0.4", features = ["release_max_level_info"] }
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||
app::{App, AppExit},
|
||||
event::Events,
|
||||
plugin::Plugin,
|
||||
stage, startup_stage,
|
||||
stage, startup_stage, PluginGroup, PluginGroupBuilder,
|
||||
};
|
||||
use bevy_ecs::{FromResources, IntoQuerySystem, Resources, System, World};
|
||||
|
||||
|
@ -271,4 +271,23 @@ impl AppBuilder {
|
|||
plugin.build(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 event;
|
||||
mod plugin;
|
||||
mod plugin_group;
|
||||
mod schedule_runner;
|
||||
|
||||
pub use app::*;
|
||||
|
@ -14,6 +15,7 @@ pub use app_builder::*;
|
|||
pub use bevy_derive::DynamicPlugin;
|
||||
pub use event::*;
|
||||
pub use plugin::*;
|
||||
pub use plugin_group::*;
|
||||
pub use schedule_runner::*;
|
||||
|
||||
pub mod prelude {
|
||||
|
@ -21,7 +23,6 @@ pub mod prelude {
|
|||
app::App,
|
||||
app_builder::AppBuilder,
|
||||
event::{EventReader, Events},
|
||||
plugin::Plugin,
|
||||
stage, DynamicPlugin,
|
||||
stage, DynamicPlugin, Plugin, PluginGroup,
|
||||
};
|
||||
}
|
||||
|
|
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"
|
||||
)]
|
||||
|
||||
mod add_default_plugins;
|
||||
mod default_plugins;
|
||||
pub mod prelude;
|
||||
|
||||
pub use add_default_plugins::*;
|
||||
pub use bevy_app as app;
|
||||
pub use bevy_asset as asset;
|
||||
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_utils as utils;
|
||||
pub use bevy_window as window;
|
||||
pub use default_plugins::*;
|
||||
|
||||
#[cfg(feature = "bevy_audio")]
|
||||
pub use bevy_audio as audio;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
pub use crate::{
|
||||
app::prelude::*, asset::prelude::*, core::prelude::*, ecs::prelude::*, input::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")]
|
||||
|
|
Loading…
Reference in a new issue