Bevy app docs (#3539)

# Objective

Achieve 100% documentation coverage for bevy_app crate.
See #3492 

## Solution

- Add #![warn(missing_docs)] to crate root
- Add doc comments to public items
- Add doc comment to bevy_utils::define_label macro trait
This commit is contained in:
Daniel Bearden 2022-01-06 23:16:47 +00:00
parent 44f370a26c
commit b673c51e20
8 changed files with 56 additions and 7 deletions

View File

@ -14,7 +14,6 @@ use std::fmt::Debug;
#[cfg(feature = "trace")] #[cfg(feature = "trace")]
use bevy_utils::tracing::info_span; use bevy_utils::tracing::info_span;
bevy_utils::define_label!(AppLabel); bevy_utils::define_label!(AppLabel);
#[allow(clippy::needless_doctest_main)] #[allow(clippy::needless_doctest_main)]
@ -22,8 +21,9 @@ bevy_utils::define_label!(AppLabel);
/// ///
/// Bundles together the necessary elements, like [`World`] and [`Schedule`], to create /// Bundles together the necessary elements, like [`World`] and [`Schedule`], to create
/// an ECS-based application. It also stores a pointer to a /// an ECS-based application. It also stores a pointer to a
/// [runner function](App::set_runner), which by default executes the App schedule /// [runner function](Self::set_runner). The runner is responsible for managing the application's
/// once. Apps are constructed with the builder pattern. /// event loop and applying the [`Schedule`] to the [`World`] to drive application logic.
/// Apps are constructed with the builder pattern.
/// ///
/// ## Example /// ## Example
/// Here is a simple "Hello World" Bevy app: /// Here is a simple "Hello World" Bevy app:
@ -42,12 +42,22 @@ bevy_utils::define_label!(AppLabel);
/// } /// }
/// ``` /// ```
pub struct App { 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`][App::add_sub_app]s.
pub world: World, 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).
pub runner: Box<dyn Fn(App)>, pub runner: Box<dyn Fn(App)>,
/// A container of [`Stage`]s set to be run in a linear order.
pub schedule: Schedule, pub schedule: Schedule,
sub_apps: HashMap<Box<dyn AppLabel>, SubApp>, sub_apps: HashMap<Box<dyn AppLabel>, SubApp>,
} }
/// Each [`SubApp`] has its own [`Schedule`] and [`World`], enabling a separation of concerns.
struct SubApp { struct SubApp {
app: App, app: App,
runner: Box<dyn Fn(&mut World, &mut App)>, runner: Box<dyn Fn(&mut World, &mut App)>,
@ -73,10 +83,15 @@ impl Default for App {
} }
impl 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 { pub fn new() -> App {
App::default() 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.
pub fn empty() -> App { pub fn empty() -> App {
Self { Self {
world: Default::default(), world: Default::default(),
@ -837,6 +852,9 @@ impl App {
self 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( pub fn add_sub_app(
&mut self, &mut self,
label: impl AppLabel, label: impl AppLabel,

View File

@ -1,3 +1,4 @@
#![warn(missing_docs)]
//! This crate is about everything concerning the highest-level, application layer of a Bevy //! This crate is about everything concerning the highest-level, application layer of a Bevy
//! app. //! app.
@ -16,6 +17,7 @@ pub use plugin::*;
pub use plugin_group::*; pub use plugin_group::*;
pub use schedule_runner::*; pub use schedule_runner::*;
#[allow(missing_docs)]
pub mod prelude { pub mod prelude {
#[doc(hidden)] #[doc(hidden)]
pub use crate::{app::App, CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupStage}; pub use crate::{app::App, CoreStage, DynamicPlugin, Plugin, PluginGroup, StartupStage};

View File

@ -6,10 +6,14 @@ use std::any::Any;
/// Plugins configure an [`App`](crate::App). When an [`App`](crate::App) registers /// Plugins configure an [`App`](crate::App). When an [`App`](crate::App) registers
/// a plugin, the plugin's [`Plugin::build`] function is run. /// a plugin, the plugin's [`Plugin::build`] function is run.
pub trait Plugin: Any + Send + Sync { pub trait Plugin: Any + Send + Sync {
/// Configures the [`App`] to which this plugin is added.
fn build(&self, app: &mut App); fn build(&self, app: &mut App);
/// Configures a name for the [`Plugin`]. Primarily for debugging.
fn name(&self) -> &str { fn name(&self) -> &str {
std::any::type_name::<Self>() 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; pub type CreatePlugin = unsafe fn() -> *mut dyn Plugin;

View File

@ -2,7 +2,9 @@ use crate::{App, Plugin};
use bevy_utils::{tracing::debug, HashMap}; use bevy_utils::{tracing::debug, HashMap};
use std::any::TypeId; use std::any::TypeId;
/// Combines multiple [`Plugin`]s into a single unit.
pub trait PluginGroup { pub trait PluginGroup {
/// Configures the [`Plugin`]s that are to be added.
fn build(&mut self, group: &mut PluginGroupBuilder); fn build(&mut self, group: &mut PluginGroupBuilder);
} }
@ -11,6 +13,9 @@ struct PluginEntry {
enabled: bool, 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)] #[derive(Default)]
pub struct PluginGroupBuilder { pub struct PluginGroupBuilder {
plugins: HashMap<TypeId, PluginEntry>, plugins: HashMap<TypeId, PluginEntry>,
@ -18,6 +23,7 @@ pub struct PluginGroupBuilder {
} }
impl PluginGroupBuilder { impl PluginGroupBuilder {
/// Appends a [`Plugin`] to the [`PluginGroupBuilder`].
pub fn add<T: Plugin>(&mut self, plugin: T) -> &mut Self { pub fn add<T: Plugin>(&mut self, plugin: T) -> &mut Self {
self.order.push(TypeId::of::<T>()); self.order.push(TypeId::of::<T>());
self.plugins.insert( self.plugins.insert(
@ -30,6 +36,7 @@ impl PluginGroupBuilder {
self self
} }
/// Configures a [`Plugin`] to be built before another plugin.
pub fn add_before<Target: Plugin, T: Plugin>(&mut self, plugin: T) -> &mut Self { pub fn add_before<Target: Plugin, T: Plugin>(&mut self, plugin: T) -> &mut Self {
let target_index = self let target_index = self
.order .order
@ -54,6 +61,7 @@ impl PluginGroupBuilder {
self self
} }
/// Configures a [`Plugin`] to be built after another plugin.
pub fn add_after<Target: Plugin, T: Plugin>(&mut self, plugin: T) -> &mut Self { pub fn add_after<Target: Plugin, T: Plugin>(&mut self, plugin: T) -> &mut Self {
let target_index = self let target_index = self
.order .order
@ -78,6 +86,10 @@ impl PluginGroupBuilder {
self self
} }
/// Enables a [`Plugin`]
///
/// [`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 { pub fn enable<T: Plugin>(&mut self) -> &mut Self {
let mut plugin_entry = self let mut plugin_entry = self
.plugins .plugins
@ -87,6 +99,7 @@ impl PluginGroupBuilder {
self 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 { pub fn disable<T: Plugin>(&mut self) -> &mut Self {
let mut plugin_entry = self let mut plugin_entry = self
.plugins .plugins
@ -96,6 +109,7 @@ impl PluginGroupBuilder {
self self
} }
/// Consumes the [`PluginGroupBuilder`] and [builds](Plugin::build) the contained [`Plugin`]s.
pub fn finish(self, app: &mut App) { pub fn finish(self, app: &mut App) {
for ty in self.order.iter() { for ty in self.order.iter() {
if let Some(entry) = self.plugins.get(ty) { if let Some(entry) = self.plugins.get(ty) {

View File

@ -11,10 +11,16 @@ use std::{cell::RefCell, rc::Rc};
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use wasm_bindgen::{prelude::*, JsCast}; 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)] #[derive(Copy, Clone, Debug)]
pub enum RunMode { 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.
/// A value of [`None`] will not wait.
wait: Option<Duration>,
},
/// Indicates that the [`App`]'s schedule should run only once.
Once, Once,
} }
@ -24,18 +30,22 @@ impl Default for RunMode {
} }
} }
/// Configuration information for [`ScheduleRunnerPlugin`].
#[derive(Copy, Clone, Default)] #[derive(Copy, Clone, Default)]
pub struct ScheduleRunnerSettings { pub struct ScheduleRunnerSettings {
/// Determines whether the [`Schedule`](bevy_ecs::schedule::Schedule) is run once or repeatedly.
pub run_mode: RunMode, pub run_mode: RunMode,
} }
impl ScheduleRunnerSettings { impl ScheduleRunnerSettings {
/// [`RunMode::Once`]
pub fn run_once() -> Self { pub fn run_once() -> Self {
ScheduleRunnerSettings { ScheduleRunnerSettings {
run_mode: RunMode::Once, run_mode: RunMode::Once,
} }
} }
/// [`RunMode::Loop`]
pub fn run_loop(wait_duration: Duration) -> Self { pub fn run_loop(wait_duration: Duration) -> Self {
ScheduleRunnerSettings { ScheduleRunnerSettings {
run_mode: RunMode::Loop { run_mode: RunMode::Loop {

View File

@ -2,7 +2,7 @@ use libloading::{Library, Symbol};
use bevy_app::{App, CreatePlugin, Plugin}; 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`. /// [`CreatePlugin`] signature named `_bevy_create_plugin`.
/// ///
/// # Safety /// # Safety

View File

@ -58,6 +58,7 @@ where
#[macro_export] #[macro_export]
macro_rules! define_label { macro_rules! define_label {
($label_trait_name:ident) => { ($label_trait_name:ident) => {
/// Defines a set of strongly-typed labels for a class of objects
pub trait $label_trait_name: pub trait $label_trait_name:
::bevy_utils::label::DynHash + ::std::fmt::Debug + Send + Sync + 'static ::bevy_utils::label::DynHash + ::std::fmt::Debug + Send + Sync + 'static
{ {

View File

@ -80,7 +80,7 @@ fn main() {
// `CorePlugin' and `AssetPlugin`. It needs to be after the // `CorePlugin' and `AssetPlugin`. It needs to be after the
// CorePlugin, so that the IO task pool has already been constructed. // CorePlugin, so that the IO task pool has already been constructed.
// And it must be before the `AssetPlugin` so that the asset plugin // 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 // the AssetPlugin should still run so that other aspects of the
// asset system are initialized correctly. // asset system are initialized correctly.
group.add_before::<bevy::asset::AssetPlugin, _>(CustomAssetIoPlugin) group.add_before::<bevy::asset::AssetPlugin, _>(CustomAssetIoPlugin)