Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Bevy app docs #3539

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions crates/bevy_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ use std::fmt::Debug;

#[cfg(feature = "trace")]
use bevy_utils::tracing::info_span;

bevy_utils::define_label!(AppLabel);

#[allow(clippy::needless_doctest_main)]
/// Containers of app logic and data
///
/// Bundles together the necessary elements, like [`World`] and [`Schedule`], to create
/// an ECS-based application. It also stores a pointer to a
/// [runner function](App::set_runner), which by default executes the App schedule
/// once. Apps are constructed with the builder pattern.
/// [runner function](Self::set_runner). The runner is responsible for managing the application's
/// event loop and applying the [`Schedule`] to the [`World`] to drive application logic.
/// Apps are constructed with the builder pattern.
///
/// ## Example
/// Here is a simple "Hello World" Bevy app:
Expand All @@ -42,12 +42,22 @@ bevy_utils::define_label!(AppLabel);
/// }
/// ```
pub struct App {
/// The main ECS [`World`] of the [`App`].
/// This stores and provides access to all the main data of the application.
/// The systems of the [`App`] will run using this [`World`].
/// If additional separate [`World`]-[`Schedule`] pairs are needed, you can use `sub_app`s.
dbearden marked this conversation as resolved.
Show resolved Hide resolved
pub world: World,
/// The [runner function](Self::set_runner) is primarily responsible for managing
/// the application's event loop and advancing the [`Schedule`].
/// Typically, it is not configured manually, but set by one of Bevy's built-in plugins.
/// See bevy_winit::WinitPlugin and [`ScheduleRunnerPlugin`](crate::schedule_runner::ScheduleRunnerPlugin).
dbearden marked this conversation as resolved.
Show resolved Hide resolved
pub runner: Box<dyn Fn(App)>,
/// A container of [`Stage`]s set to be run in a linear order.
pub schedule: Schedule,
sub_apps: HashMap<Box<dyn AppLabel>, SubApp>,
}

/// Each [`SubApp`] has its own [`Schedule`] and [`World`], enabling a separation of concerns.
struct SubApp {
app: App,
runner: Box<dyn Fn(&mut World, &mut App)>,
Expand All @@ -73,10 +83,14 @@ impl Default for App {
}

impl App {
/// Creates a new [`App`] with some default structure to enable core engine features.
/// This is the preferred constructor for most use cases.
pub fn new() -> App {
App::default()
}

/// Creates a new empty [`App`] with minimal default configuration.
/// This constructor should be used if you wish to provide a custom schedule, exit handling, cleanup, etc.
dbearden marked this conversation as resolved.
Show resolved Hide resolved
pub fn empty() -> App {
Self {
world: Default::default(),
Expand Down Expand Up @@ -837,6 +851,9 @@ impl App {
self
}

/// Adds a "sub app" to this [`App`].
///
/// Sub apps are a largely experimental feature: each `SubApp` has its own [`Schedule`] and [`World`].
pub fn add_sub_app(
&mut self,
label: impl AppLabel,
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_app/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![warn(missing_docs)]
//! This crate is about everything concerning the highest-level, application layer of a Bevy
//! app.

Expand All @@ -16,6 +17,7 @@ pub use plugin::*;
pub use plugin_group::*;
pub use schedule_runner::*;

#[allow(missing_docs)]
pub mod prelude {
#[doc(hidden)]
pub use crate::{app::App, CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupStage};
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_app/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ use std::any::Any;
/// Plugins configure an [`App`](crate::App). When an [`App`](crate::App) registers
/// a plugin, the plugin's [`Plugin::build`] function is run.
pub trait Plugin: Any + Send + Sync {
/// Configures the [`App`] to which this plugin is added.
fn build(&self, app: &mut App);
/// Configures a name for the [`Plugin`]. Primarily for debugging.
fn name(&self) -> &str {
std::any::type_name::<Self>()
}
}

/// Type representing an unsafe function that returns a mutable pointer to a [`Plugin`].
/// Used for dynamically loading plugins. See bevy_dynamic_plugin/src/loader.rs#dynamically_load_plugin
pub type CreatePlugin = unsafe fn() -> *mut dyn Plugin;
14 changes: 14 additions & 0 deletions crates/bevy_app/src/plugin_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use crate::{App, Plugin};
use bevy_utils::{tracing::debug, HashMap};
use std::any::TypeId;

/// Combines multiple [`Plugin`]s into a single unit.
pub trait PluginGroup {
/// Configures the [`Plugin`]s that are to be added.
fn build(&mut self, group: &mut PluginGroupBuilder);
}

Expand All @@ -11,13 +13,17 @@ struct PluginEntry {
enabled: bool,
}

/// Facilitates the creation and configuration of a [`PluginGroup`].
/// Provides a build ordering to ensure that [`Plugin`]s which produce/require a resource
/// are built before/after dependent/depending [`Plugin`]s.
#[derive(Default)]
pub struct PluginGroupBuilder {
plugins: HashMap<TypeId, PluginEntry>,
order: Vec<TypeId>,
}

impl PluginGroupBuilder {
/// Appends a [`Plugin`] to the [`PluginGroupBuilder`].
pub fn add<T: Plugin>(&mut self, plugin: T) -> &mut Self {
self.order.push(TypeId::of::<T>());
self.plugins.insert(
Expand All @@ -30,6 +36,7 @@ impl PluginGroupBuilder {
self
}

/// Configures a [`Plugin`] to be built before another plugin.
pub fn add_before<Target: Plugin, T: Plugin>(&mut self, plugin: T) -> &mut Self {
let target_index = self
.order
Expand All @@ -54,6 +61,7 @@ impl PluginGroupBuilder {
self
}

/// Configures a [`Plugin`] to be built after another plugin.
pub fn add_after<Target: Plugin, T: Plugin>(&mut self, plugin: T) -> &mut Self {
let target_index = self
.order
Expand All @@ -78,6 +86,10 @@ impl PluginGroupBuilder {
self
}

/// Enables a [`Plugin`]
dbearden marked this conversation as resolved.
Show resolved Hide resolved
///
/// [`Plugin`]s within a [`PluginGroup`] are enabled by default. This function is used to
/// opt back in to a [`Plugin`] after [disabling](Self::disable) it.
pub fn enable<T: Plugin>(&mut self) -> &mut Self {
let mut plugin_entry = self
.plugins
Expand All @@ -87,6 +99,7 @@ impl PluginGroupBuilder {
self
}

/// Disables a [`Plugin`], preventing it from being added to the `App` with the rest of the [`PluginGroup`].
pub fn disable<T: Plugin>(&mut self) -> &mut Self {
let mut plugin_entry = self
.plugins
Expand All @@ -96,6 +109,7 @@ impl PluginGroupBuilder {
self
}

/// Consumes the [`PluginGroupBuilder`] and [builds](Plugin::build) the contained [`Plugin`]s.
pub fn finish(self, app: &mut App) {
for ty in self.order.iter() {
if let Some(entry) = self.plugins.get(ty) {
Expand Down
14 changes: 12 additions & 2 deletions crates/bevy_app/src/schedule_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@ use std::{cell::RefCell, rc::Rc};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::{prelude::*, JsCast};

/// Determines the method used to run an [App]'s `Schedule`
/// Determines the method used to run an [App]'s [`Schedule`](bevy_ecs::schedule::Schedule).
#[derive(Copy, Clone, Debug)]
pub enum RunMode {
Loop { wait: Option<Duration> },
/// Indicates that the [`App`]'s schedule should run repeatedly.
Loop {
/// Minimum duration to wait after a schedule has completed before repeating.
dbearden marked this conversation as resolved.
Show resolved Hide resolved
/// A value of [`None`] will not wait.
wait: Option<Duration>,
dbearden marked this conversation as resolved.
Show resolved Hide resolved
},
/// Indicates that the [`App`]'s schedule should run only once.
Once,
}

Expand All @@ -24,18 +30,22 @@ impl Default for RunMode {
}
}

/// Configuration information for [`ScheduleRunnerPlugin`].
#[derive(Copy, Clone, Default)]
pub struct ScheduleRunnerSettings {
/// Determines whether the [`Schedule`](bevy_ecs::schedule::Schedule) is run once or repeatedly.
pub run_mode: RunMode,
}

impl ScheduleRunnerSettings {
/// [`RunMode::Once`]
pub fn run_once() -> Self {
ScheduleRunnerSettings {
run_mode: RunMode::Once,
}
}

/// [`RunMode::Loop`]
pub fn run_loop(wait_duration: Duration) -> Self {
ScheduleRunnerSettings {
run_mode: RunMode::Loop {
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_dynamic_plugin/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use libloading::{Library, Symbol};

use bevy_app::{App, CreatePlugin, Plugin};

/// Dynamically links a plugin a the given path. The plugin must export a function with the
/// Dynamically links a plugin at the given path. The plugin must export a function with the
/// [`CreatePlugin`] signature named `_bevy_create_plugin`.
///
/// # Safety
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_utils/src/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ where
#[macro_export]
macro_rules! define_label {
($label_trait_name:ident) => {
/// Defines a set of strongly-typed labels for a class of objects
pub trait $label_trait_name:
::bevy_utils::label::DynHash + ::std::fmt::Debug + Send + Sync + 'static
{
Expand Down
2 changes: 1 addition & 1 deletion examples/asset/custom_asset_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ fn main() {
// `CorePlugin' and `AssetPlugin`. It needs to be after the
// CorePlugin, so that the IO task pool has already been constructed.
// And it must be before the `AssetPlugin` so that the asset plugin
// doesn't create another instance of an assert server. In general,
// doesn't create another instance of an asset server. In general,
// the AssetPlugin should still run so that other aspects of the
// asset system are initialized correctly.
group.add_before::<bevy::asset::AssetPlugin, _>(CustomAssetIoPlugin)
Expand Down