Improve bevy_ecs and bevy_app API docs where referenced by the new Bevy Book (#2365)

## Objective

The upcoming Bevy Book makes many references to the API documentation of bevy.

Most references belong to the first two chapters of the Bevy Book:

- bevyengine/bevy-website#176
- bevyengine/bevy-website#182

This PR attempts to improve the documentation of `bevy_ecs` and `bevy_app` in order to help readers of the Book who want to delve deeper into technical details.

## Solution

- Add crate and level module documentation
- Document the most important items (basically those included in the preludes), with the following style, where applicable:
    - **Summary.** Short description of the item.
    - **Second paragraph.** Detailed description of the item, without going too much in the implementation.
    - **Code example(s).**
    - **Safety or panic notes.**

## Collaboration

Any kind of collaboration is welcome, especially corrections, wording, new ideas and guidelines on where the focus should be put in.

---

### Related issues

- Fixes #2246
This commit is contained in:
Federico Rinaldi 2021-09-17 18:00:29 +00:00
parent 064af63400
commit 615d43b998
18 changed files with 1348 additions and 202 deletions

View file

@ -16,9 +16,10 @@ use bevy_utils::tracing::info_span;
#[allow(clippy::needless_doctest_main)]
/// Containers of app logic and data
///
/// App store the ECS World, Resources, Schedule, and Executor. They also store the "run" function
/// of the App, which by default executes the App schedule once. Apps are constructed using the
/// builder pattern.
/// 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.
///
/// ## Example
/// Here is a simple "Hello World" Bevy app:
@ -74,6 +75,9 @@ impl App {
}
}
/// Advances the execution of the [`Schedule`] by one cycle.
///
/// See [`Schedule::run_once`] for more details.
pub fn update(&mut self) {
#[cfg(feature = "trace")]
let bevy_frame_update_span = info_span!("frame");
@ -82,22 +86,10 @@ impl App {
self.schedule.run(&mut self.world);
}
/// Start the application (through main runner)
/// Starts the application by calling the app's [runner function](Self::set_runner).
///
/// Runs the application main loop.
///
/// Usually the main loop is handled by Bevy integrated plugins (`winit`), but
/// one can also set the runner function through [`App::set_runner`].
///
/// ## Example
/// ```
/// # use bevy_app::prelude::*;
/// #
/// App::new()
/// // all required plugin insertions, systems, etc inserted here
/// // finally, call:
/// .run();
/// ```
/// Finalizes the [`App`] configuration. For general usage, see the example on the item
/// level documentation.
pub fn run(&mut self) {
#[cfg(feature = "trace")]
let bevy_app_run_span = info_span!("bevy_app");
@ -109,11 +101,35 @@ impl App {
(runner)(app);
}
/// Adds a [`Stage`] with the given `label` to the last position of the app's
/// [`Schedule`].
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// # let mut app = App::new();
/// #
/// app.add_stage("my_stage", SystemStage::parallel());
/// ```
pub fn add_stage<S: Stage>(&mut self, label: impl StageLabel, stage: S) -> &mut Self {
self.schedule.add_stage(label, stage);
self
}
/// Adds a [`Stage`] with the given `label` to the app's [`Schedule`], located
/// immediately after the stage labeled by `target`.
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// # let mut app = App::new();
/// #
/// app.add_stage_after(CoreStage::Update, "my_stage", SystemStage::parallel());
/// ```
pub fn add_stage_after<S: Stage>(
&mut self,
target: impl StageLabel,
@ -124,6 +140,18 @@ impl App {
self
}
/// Adds a [`Stage`] with the given `label` to the app's [`Schedule`], located
/// immediately before the stage labeled by `target`.
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// # let mut app = App::new();
/// #
/// app.add_stage_before(CoreStage::Update, "my_stage", SystemStage::parallel());
/// ```
pub fn add_stage_before<S: Stage>(
&mut self,
target: impl StageLabel,
@ -134,6 +162,18 @@ impl App {
self
}
/// Adds a [`Stage`] with the given `label` to the last position of the
/// [startup schedule](Self::add_default_stages).
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// # let mut app = App::new();
/// #
/// app.add_startup_stage("my_startup_stage", SystemStage::parallel());
/// ```
pub fn add_startup_stage<S: Stage>(&mut self, label: impl StageLabel, stage: S) -> &mut Self {
self.schedule
.stage(CoreStage::Startup, |schedule: &mut Schedule| {
@ -142,6 +182,24 @@ impl App {
self
}
/// Adds a [startup stage](Self::add_default_stages) with the given `label`, immediately
/// after the stage labeled by `target`.
///
/// The `target` label must refer to a stage inside the startup schedule.
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// # let mut app = App::new();
/// #
/// app.add_startup_stage_after(
/// StartupStage::Startup,
/// "my_startup_stage",
/// SystemStage::parallel()
/// );
/// ```
pub fn add_startup_stage_after<S: Stage>(
&mut self,
target: impl StageLabel,
@ -155,6 +213,24 @@ impl App {
self
}
/// Adds a [startup stage](Self::add_default_stages) with the given `label`, immediately
/// before the stage labeled by `target`.
///
/// The `target` label must refer to a stage inside the startup schedule.
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// # let mut app = App::new();
/// #
/// app.add_startup_stage_before(
/// StartupStage::Startup,
/// "my_startup_stage",
/// SystemStage::parallel()
/// );
/// ```
pub fn add_startup_stage_before<S: Stage>(
&mut self,
target: impl StageLabel,
@ -168,6 +244,30 @@ impl App {
self
}
/// Fetches the [`Stage`] of type `T` marked with `label` from the [`Schedule`], then
/// executes the provided `func` passing the fetched stage to it as an argument.
///
/// The `func` argument should be a function or a closure that accepts a mutable reference
/// to a struct implementing `Stage` and returns the same type. That means that it should
/// also assume that the stage has already been fetched successfully.
///
/// See [`Schedule::stage`] for more details.
///
/// # Example
///
/// Here the closure is used to add a system to the update stage:
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut app = App::new();
/// # fn my_system() {}
/// #
/// app.stage(CoreStage::Update, |stage: &mut SystemStage| {
/// stage.add_system(my_system)
/// });
/// ```
pub fn stage<T: Stage, F: FnOnce(&mut T) -> &mut T>(
&mut self,
label: impl StageLabel,
@ -177,40 +277,63 @@ impl App {
self
}
/// Adds a system that runs every time `app.update()` is called by the runner
/// Adds a system to the [update stage](Self::add_default_stages) of the app's [`Schedule`].
///
/// Systems are the main building block in the Bevy ECS app model. You can define
/// normal rust functions, and use them as a Bevy system.
/// Refer to the [system module documentation](bevy_ecs::system) to see how a system
/// can be defined.
///
/// System functions can have parameters, through which one can query and
/// mutate Bevy ECS states.
/// See [The Bevy Book](https://bevyengine.org/learn/book/introduction/) for more information.
/// # Example
///
/// Systems are run in parallel, and the execution order is not deterministic.
/// If you want more fine-grained control for order, see [`App::add_system_to_stage`].
///
/// For adding a system that runs only at app startup, see [`App::add_startup_system`].
///
/// ## Example
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// fn my_system(_commands: Commands) {
/// println!("My system, triggered once per frame");
/// }
///
/// App::new()
/// .add_system(my_system);
/// # fn my_system() {}
/// # let mut app = App::new();
/// #
/// app.add_system(my_system);
/// ```
pub fn add_system<Params>(&mut self, system: impl IntoSystemDescriptor<Params>) -> &mut Self {
self.add_system_to_stage(CoreStage::Update, system)
}
/// Adds a [`SystemSet`] to the [update stage](Self::add_default_stages).
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut app = App::new();
/// # fn system_a() {}
/// # fn system_b() {}
/// # fn system_c() {}
/// #
/// app.add_system_set(
/// SystemSet::new()
/// .with_system(system_a)
/// .with_system(system_b)
/// .with_system(system_c),
/// );
/// ```
pub fn add_system_set(&mut self, system_set: SystemSet) -> &mut Self {
self.add_system_set_to_stage(CoreStage::Update, system_set)
}
/// Adds a system to the [`Stage`] identified by `stage_label`.
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut app = App::new();
/// # fn my_system() {}
/// #
/// app.add_system_to_stage(CoreStage::PostUpdate, my_system);
/// ```
pub fn add_system_to_stage<Params>(
&mut self,
stage_label: impl StageLabel,
@ -220,6 +343,27 @@ impl App {
self
}
/// Adds a [`SystemSet`] to the [`Stage`] identified by `stage_label`.
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut app = App::new();
/// # fn system_a() {}
/// # fn system_b() {}
/// # fn system_c() {}
/// #
/// app.add_system_set_to_stage(
/// CoreStage::PostUpdate,
/// SystemSet::new()
/// .with_system(system_a)
/// .with_system(system_b)
/// .with_system(system_c),
/// );
/// ```
pub fn add_system_set_to_stage(
&mut self,
stage_label: impl StageLabel,
@ -230,13 +374,10 @@ impl App {
self
}
/// Adds a system that is run once at application startup
/// Adds a system to the [startup stage](Self::add_default_stages) of the app's [`Schedule`].
///
/// Startup systems run exactly once BEFORE all other systems. These are generally used for
/// app initialization code (ex: adding entities and resources).
///
/// * For adding a system that runs for every frame, see [`App::add_system`].
/// * For adding a system to specific stage, see [`App::add_system_to_stage`].
/// * For adding a system that runs for every frame, see [`add_system`](Self::add_system).
/// * For adding a system to specific stage, see [`add_system_to_stage`](Self::add_system_to_stage).
///
/// ## Example
/// ```
@ -248,7 +389,7 @@ impl App {
/// }
///
/// App::new()
/// .add_startup_system(my_startup_system);
/// .add_startup_system(my_startup_system.system());
/// ```
pub fn add_startup_system<Params>(
&mut self,
@ -257,10 +398,46 @@ impl App {
self.add_startup_system_to_stage(StartupStage::Startup, system)
}
/// Adds a [`SystemSet`] to the [startup stage](Self::add_default_stages)
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut app = App::new();
/// # fn startup_system_a() {}
/// # fn startup_system_b() {}
/// # fn startup_system_c() {}
/// #
/// app.add_startup_system_set(
/// SystemSet::new()
/// .with_system(startup_system_a)
/// .with_system(startup_system_b)
/// .with_system(startup_system_c),
/// );
/// ```
pub fn add_startup_system_set(&mut self, system_set: SystemSet) -> &mut Self {
self.add_startup_system_set_to_stage(StartupStage::Startup, system_set)
}
/// Adds a system to the [startup schedule](Self::add_default_stages), in the stage
/// identified by `stage_label`.
///
/// `stage_label` must refer to a stage inside the startup schedule.
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut app = App::new();
/// # fn my_startup_system() {}
/// #
/// app.add_startup_system_to_stage(StartupStage::PreStartup, my_startup_system);
/// ```
pub fn add_startup_system_to_stage<Params>(
&mut self,
stage_label: impl StageLabel,
@ -273,6 +450,30 @@ impl App {
self
}
/// Adds a [`SystemSet`] to the [startup schedule](Self::add_default_stages), in the stage
/// identified by `stage_label`.
///
/// `stage_label` must refer to a stage inside the startup schedule.
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut app = App::new();
/// # fn startup_system_a() {}
/// # fn startup_system_b() {}
/// # fn startup_system_c() {}
/// #
/// app.add_startup_system_set_to_stage(
/// StartupStage::PreStartup,
/// SystemSet::new()
/// .with_system(startup_system_a)
/// .with_system(startup_system_b)
/// .with_system(startup_system_c),
/// );
/// ```
pub fn add_startup_system_set_to_stage(
&mut self,
stage_label: impl StageLabel,
@ -310,6 +511,41 @@ impl App {
.add_system_set_to_stage(stage, State::<T>::get_driver())
}
/// Adds utility stages to the [`Schedule`], giving it a standardized structure.
///
/// Adding those stages is necessary to make some core engine features work, like
/// adding systems without specifying a stage, or registering events. This is however
/// done by default by calling `App::default`, which is in turn called by
/// [`App::new`].
///
/// # The stages
///
/// All the added stages, with the exception of the startup stage, run every time the
/// schedule is invoked. The stages are the following, in order of execution:
/// - **First:** Runs at the very start of the schedule execution cycle, even before the
/// startup stage.
/// - **Startup:** This is actually a schedule containing sub-stages. Runs only once
/// when the app starts.
/// - **Pre-startup:** Intended for systems that need to run before other startup systems.
/// - **Startup:** The main startup stage. Startup systems are added here by default.
/// - **Post-startup:** Intended for systems that need to run after other startup systems.
/// - **Pre-update:** Often used by plugins to prepare their internal state before the
/// update stage begins.
/// - **Update:** Intended for user defined logic. Systems are added here by default.
/// - **Post-update:** Often used by plugins to finalize their internal state after the
/// world changes that happened during the update stage.
/// - **Last:** Runs right before the end of the schedule execution cycle.
///
/// The labels for those stages are defined in the [`CoreStage`] and [`StartupStage`]
/// `enum`s.
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// #
/// let app = App::empty().add_default_stages();
/// ```
pub fn add_default_stages(&mut self) -> &mut Self {
self.add_stage(CoreStage::First, SystemStage::parallel())
.add_stage(
@ -330,6 +566,20 @@ impl App {
///
/// This is done by adding a `Resource` of type `Events::<T>`,
/// and inserting a `Events::<T>::update_system` system into `CoreStage::First`.
///
/// See [`Events`](bevy_ecs::event::Events) for defining events.
///
/// # Example
///
/// ```
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// # struct MyEvent;
/// # let mut app = App::new();
/// #
/// app.add_event::<MyEvent>();
/// ```
pub fn add_event<T>(&mut self) -> &mut Self
where
T: Component,
@ -341,7 +591,7 @@ impl App {
/// Inserts a resource to the current [App] and overwrites any resource previously added of the same type.
///
/// A resource in Bevy represents globally unique data. Resources must be added to Bevy Apps
/// before using them. This happens with [`App::insert_resource`].
/// before using them. This happens with [`insert_resource`](Self::insert_resource).
///
/// See also `init_resource` for resources that implement `Default` or [`FromWorld`].
///
@ -388,10 +638,11 @@ impl App {
self
}
/// Initialize a resource in the current [App], if it does not exist yet
/// Initialize a resource in the current [`App`], if it does not exist yet
///
/// If the resource already exists, nothing happens.
///
/// Adds a resource that implements `Default` or [`FromWorld`] trait.
/// If the resource already exists, `init_resource` does nothing.
///
/// ## Example
/// ```
@ -426,6 +677,9 @@ impl App {
self
}
/// Initialize a non-send resource in the current [`App`], if it does not exist yet.
///
/// Adds a resource that implements `Default` or [`FromWorld`] trait.
pub fn init_non_send_resource<R>(&mut self) -> &mut Self
where
R: FromWorld + 'static,
@ -438,13 +692,14 @@ impl App {
self
}
/// Sets the main runner loop function for this Bevy App
/// Sets the function that will be called when the app is run.
///
/// Usually the main loop is handled by Bevy integrated plugins
/// ([`WinitPlugin`](https://docs.rs/bevy/*/bevy/winit/struct.WinitPlugin.html)),
/// but in some cases one might wish to implement their own main loop.
/// The runner function (`run_fn`) is called only once by [`App::run`]. If the
/// presence of a main loop in the app is desired, it is responsibility of the runner
/// function to provide it.
///
/// This method sets the main loop function, overwriting a previous runner if any.
/// The runner function is usually not set manually, but by Bevy integrated plugins
/// (e.g. winit plugin).
///
/// ## Example
/// ```
@ -470,7 +725,7 @@ impl App {
/// One of Bevy's core principles is modularity. All Bevy engine features are implemented
/// as plugins. This includes internal features like the renderer.
///
/// Bevy also provides a few sets of default plugins. See [`App::add_plugins`].
/// Bevy also provides a few sets of default plugins. See [`add_plugins`](Self::add_plugins).
///
/// ## Example
/// ```
@ -492,9 +747,7 @@ impl App {
/// Bevy plugins can be grouped into a set of plugins. Bevy provides
/// built-in PluginGroups that provide core engine functionality.
///
/// The plugin groups available by default are
/// [`DefaultPlugins`](https://docs.rs/bevy/*/bevy/struct.DefaultPlugins.html)
/// and [`MinimalPlugins`](https://docs.rs/bevy/*/bevy/struct.MinimalPlugins.html).
/// The plugin groups available by default are `DefaultPlugins` and `MinimalPlugins`.
///
/// ## Example
/// ```
@ -557,10 +810,11 @@ impl App {
self
}
/// Registers a new component using the given [ComponentDescriptor]. Components do not need to
/// be manually registered. This just provides a way to override default configuration.
/// Attempting to register a component with a type that has already been used by [World]
/// will result in an error.
/// Registers a new component using the given [ComponentDescriptor].
///
/// Components do not need to be manually registered. This just provides a way to
/// override default configuration. Attempting to register a component with a type
/// that has already been used by [World] will result in an error.
///
/// See [World::register_component]
pub fn register_component(&mut self, descriptor: ComponentDescriptor) -> &mut Self {
@ -568,6 +822,7 @@ impl App {
self
}
/// Adds the type `T` to the type registry resource.
#[cfg(feature = "bevy_reflect")]
pub fn register_type<T: bevy_reflect::GetTypeRegistration>(&mut self) -> &mut Self {
{

View file

@ -1,3 +1,6 @@
//! This crate is about everything concerning the highest-level, application layer of a Bevy
//! app.
mod app;
mod plugin;
mod plugin_group;
@ -21,9 +24,14 @@ pub mod prelude {
use bevy_ecs::schedule::StageLabel;
/// The names of the default App stages
///
/// The relative stages are added by [`App::add_default_stages`].
#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)]
pub enum CoreStage {
/// Runs once at the beginning of the app.
/// Runs only once at the beginning of the app.
///
/// Consists of the sub-stages defined in [`StartupStage`]. Systems added here are
/// referred to as "startup systems".
Startup,
/// Name of app stage that runs before all other app stages
First,

View file

@ -1,3 +1,6 @@
//! Types for defining [`Archetype`]s, collections of entities that have the same set of
//! components.
use crate::{
bundle::BundleId,
component::{ComponentId, StorageType},

View file

@ -1,3 +1,7 @@
//! Types for handling [`Bundle`]s.
//!
//! This module contains the `Bundle` trait and some other helper types.
pub use bevy_ecs_macros::Bundle;
use crate::{
@ -9,15 +13,35 @@ use crate::{
use bevy_ecs_macros::all_tuples;
use std::{any::TypeId, collections::HashMap};
/// An ordered collection of components, commonly used for spawning entities, and adding and
/// removing components in bulk.
/// An ordered collection of components.
///
/// Typically, you will simply use `#[derive(Bundle)]` when creating your own `Bundle`.
/// The `Bundle` trait is automatically implemented for tuples of components:
/// `(ComponentA, ComponentB)` is a very convenient shorthand when working with one-off collections
/// of components. Note that both `()` and `(ComponentA, )` are valid tuples.
/// Commonly used for spawning entities and adding and removing components in bulk. This
/// trait is automatically implemented for tuples of components: `(ComponentA, ComponentB)`
/// is a very convenient shorthand when working with one-off collections of components. Note
/// that both the unit type `()` and `(ComponentA, )` are valid bundles. The unit bundle is
/// particularly useful for spawning multiple empty entities by using
/// [`Commands::spawn_batch`](crate::system::Commands::spawn_batch).
///
/// You can nest bundles like so:
/// # Examples
///
/// Typically, you will simply use `#[derive(Bundle)]` when creating your own `Bundle`. Each
/// struct field is a component:
///
/// ```
/// # use bevy_ecs::prelude::*;
/// # struct ComponentA;
/// # struct ComponentB;
/// # struct ComponentC;
/// #
/// #[derive(Bundle)]
/// struct MyBundle {
/// a: ComponentA,
/// b: ComponentB,
/// c: ComponentC,
/// }
/// ```
///
/// You can nest bundles using the `#[bundle]` attribute:
/// ```
/// # use bevy_ecs::bundle::Bundle;
///
@ -36,10 +60,11 @@ use std::{any::TypeId, collections::HashMap};
/// ```
///
/// # Safety
/// [Bundle::component_ids] must return the ComponentId for each component type in the bundle, in the
/// _exact_ order that [Bundle::get_components] is called.
/// [Bundle::from_components] must call `func` exactly once for each [ComponentId] returned by
/// [Bundle::component_ids]
///
/// - [Bundle::component_ids] must return the ComponentId for each component type in the bundle, in the
/// _exact_ order that [Bundle::get_components] is called.
/// - [Bundle::from_components] must call `func` exactly once for each [ComponentId] returned by
/// [Bundle::component_ids].
pub unsafe trait Bundle: Send + Sync + 'static {
/// Gets this [Bundle]'s component ids, in the order of this bundle's Components
fn component_ids(components: &mut Components) -> Vec<ComponentId>;

View file

@ -1,3 +1,5 @@
//! Types that detect when their internal data mutate.
use crate::component::{Component, ComponentTicks};
use bevy_reflect::Reflect;
use std::ops::{Deref, DerefMut};
@ -136,9 +138,13 @@ pub(crate) struct Ticks<'a> {
/// Unique mutable borrow of a resource.
///
/// See the [`World`](crate::world::World) documentation to see the usage of a resource.
///
/// If you need a shared borrow, use [`Res`](crate::system::Res) instead.
///
/// # Panics
///
/// Panics when used as a [`SystemParameter`](crate::system::SystemParam) if the resource does not exist.
/// Panics when used as a [`SystemParam`](crate::system::SystemParam) if the resource does not exist.
///
/// Use `Option<ResMut<T>>` instead if the resource might not always exist.
pub struct ResMut<'a, T: Component> {
@ -152,7 +158,7 @@ impl_debug!(ResMut<'a, T>, Component);
/// Unique borrow of a non-[`Send`] resource.
///
/// Only [`Send`] resources may be accessed with the [`ResMut`] [`crate::system::SystemParam`]. In case that the
/// Only [`Send`] resources may be accessed with the [`ResMut`] [`SystemParam`](crate::system::SystemParam). In case that the
/// resource does not implement `Send`, this `SystemParam` wrapper can be used. This will instruct
/// the scheduler to instead run the system on the main thread so that it doesn't send the resource
/// over to another thread.

View file

@ -1,3 +1,5 @@
//! Types for declaring and storing [`Component`]s.
use crate::storage::SparseSetIndex;
use std::{
alloc::Layout,

View file

@ -1,3 +1,27 @@
//! Entity handling types.
//!
//! In Bevy ECS, there is no monolithic data structure for an entity. Instead, the [`Entity`]
//! `struct` is just a *generational index* (a combination of an ID and a generation). Then,
//! the `Entity` maps to the specific [`Component`s](crate::component::Component). This way,
//! entities can have meaningful data attached to it. This is a fundamental design choice
//! that has been taken to enhance performance and usability.
//!
//! # Usage
//!
//! Here are links to the methods used to perform common operations
//! involving entities:
//!
//! - **Spawning an empty entity:** use [`Commands::spawn`](crate::system::Commands::spawn).
//! - **Spawning an entity with components:** use
//! [`Commands::spawn_bundle`](crate::system::Commands::spawn_bundle).
//! - **Despawning an entity:** use
//! [`EntityCommands::despawn`](crate::system::EntityCommands::despawn).
//! - **Inserting a component to an entity:** use
//! [`EntityCommands::insert`](crate::system::EntityCommands::insert).
//! - **Adding multiple components to an entity:** use
//! [`EntityCommands::insert_bundle`](crate::system::EntityCommands::insert_bundle).
//! - **Removing a component to an entity:** use
//! [`EntityCommands::remove`](crate::system::EntityCommands::remove).
mod map_entities;
mod serde;
@ -36,9 +60,11 @@ impl Entity {
/// Creates a new entity reference with a generation of 0.
///
/// # Note
/// Spawning a specific `entity` value is rarely the right choice. Most apps should favor [`Commands::spawn`].
/// This method should generally only be used for sharing entities across apps, and only when they have a
/// scheme worked out to share an ID space (which doesn't happen by default).
///
/// Spawning a specific `entity` value is rarely the right choice. Most apps should favor
/// [`Commands::spawn`](crate::system::Commands::spawn). This method should generally
/// only be used for sharing entities across apps, and only when they have a scheme
/// worked out to share an ID space (which doesn't happen by default).
pub fn new(id: u32) -> Entity {
Entity { id, generation: 0 }
}

View file

@ -1,3 +1,5 @@
//! Event handling types.
use crate as bevy_ecs;
use crate::{
component::Component,

View file

@ -12,6 +12,7 @@ pub mod storage;
pub mod system;
pub mod world;
/// Most commonly used re-exported types.
pub mod prelude {
#[doc(hidden)]
#[cfg(feature = "bevy_reflect")]

View file

@ -1,3 +1,5 @@
//! Types that enable reflection support.
pub use crate::change_detection::ReflectMut;
use crate::{
component::Component,

View file

@ -1,3 +1,8 @@
//! Tools for controlling system execution.
//!
//! When using Bevy ECS, systems are usually not run directly, but are inserted into a
//! [`Stage`], which then lives within a [`Schedule`].
mod executor;
mod executor_parallel;
pub mod graph_utils;
@ -25,6 +30,12 @@ use std::fmt::Debug;
use crate::{system::System, world::World};
use bevy_utils::HashMap;
/// A container of [`Stage`]s set to be run in a linear order.
///
/// Since `Schedule` implements the [`Stage`] trait, it can be inserted into another schedule.
/// In this way, the properties of the child schedule can be set differently from the parent.
/// For example, it can be set to run only once during app execution, while the parent schedule
/// runs indefinitely.
#[derive(Default)]
pub struct Schedule {
stages: HashMap<BoxedStageLabel, Box<dyn Stage>>,
@ -33,11 +44,13 @@ pub struct Schedule {
}
impl Schedule {
/// Similar to [`add_stage`](Self::add_stage), but it also returns itself.
pub fn with_stage<S: Stage>(mut self, label: impl StageLabel, stage: S) -> Self {
self.add_stage(label, stage);
self
}
/// Similar to [`add_stage_after`](Self::add_stage_after), but it also returns itself.
pub fn with_stage_after<S: Stage>(
mut self,
target: impl StageLabel,
@ -48,6 +61,7 @@ impl Schedule {
self
}
/// Similar to [`add_stage_before`](Self::add_stage_before), but it also returns itself.
pub fn with_stage_before<S: Stage>(
mut self,
target: impl StageLabel,
@ -63,6 +77,7 @@ impl Schedule {
self
}
/// Similar to [`add_system_to_stage`](Self::add_system_to_stage), but it also returns itself.
pub fn with_system_in_stage<Params>(
mut self,
stage_label: impl StageLabel,
@ -80,6 +95,16 @@ impl Schedule {
self
}
/// Adds the given `stage` at the last position of the schedule.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut schedule = Schedule::default();
/// schedule.add_stage("my_stage", SystemStage::parallel());
/// ```
pub fn add_stage<S: Stage>(&mut self, label: impl StageLabel, stage: S) -> &mut Self {
let label: Box<dyn StageLabel> = Box::new(label);
self.stage_order.push(label.clone());
@ -90,6 +115,17 @@ impl Schedule {
self
}
/// Adds the given `stage` immediately after the `target` stage.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut schedule = Schedule::default();
/// # schedule.add_stage("target_stage", SystemStage::parallel());
/// schedule.add_stage_after("target_stage", "my_stage", SystemStage::parallel());
/// ```
pub fn add_stage_after<S: Stage>(
&mut self,
target: impl StageLabel,
@ -114,6 +150,17 @@ impl Schedule {
self
}
/// Adds the given `stage` immediately before the `target` stage.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut schedule = Schedule::default();
/// # schedule.add_stage("target_stage", SystemStage::parallel());
/// #
/// schedule.add_stage_before("target_stage", "my_stage", SystemStage::parallel());
pub fn add_stage_before<S: Stage>(
&mut self,
target: impl StageLabel,
@ -138,6 +185,18 @@ impl Schedule {
self
}
/// Adds the given `system` to the stage identified by `stage_label`.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # fn my_system() {}
/// # let mut schedule = Schedule::default();
/// # schedule.add_stage("my_stage", SystemStage::parallel());
/// #
/// schedule.add_system_to_stage("my_stage", my_system);
pub fn add_system_to_stage<Params>(
&mut self,
stage_label: impl StageLabel,
@ -160,6 +219,29 @@ impl Schedule {
self
}
/// Adds the given `system_set` to the stage identified by `stage_label`.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # fn my_system() {}
/// # let mut schedule = Schedule::default();
/// # schedule.add_stage("my_stage", SystemStage::parallel());
/// #
/// schedule.add_system_set_to_stage(
/// "my_stage",
/// SystemSet::new()
/// .with_system(system_a)
/// .with_system(system_b)
/// .with_system(system_c)
/// );
/// #
/// # fn system_a() {}
/// # fn system_b() {}
/// # fn system_c() {}
/// ```
pub fn add_system_set_to_stage(
&mut self,
stage_label: impl StageLabel,
@ -170,6 +252,31 @@ impl Schedule {
})
}
/// Fetches the [`Stage`] of type `T` marked with `label`, then executes the provided
/// `func` passing the fetched stage to it as an argument.
///
/// The `func` argument should be a function or a closure that accepts a mutable reference
/// to a struct implementing `Stage` and returns the same type. That means that it should
/// also assume that the stage has already been fetched successfully.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # let mut schedule = Schedule::default();
/// # schedule.add_stage("my_stage", SystemStage::parallel());
/// #
/// schedule.stage("my_stage", |stage: &mut SystemStage| {
/// stage.add_system(my_system)
/// });
/// #
/// # fn my_system() {}
/// ```
///
/// # Panics
///
/// Panics if `label` refers to a non-existing stage, or if it's not of type `T`.
pub fn stage<T: Stage, F: FnOnce(&mut T) -> &mut T>(
&mut self,
label: impl StageLabel,
@ -182,18 +289,48 @@ impl Schedule {
self
}
/// Returns a shared reference to the stage identified by `label`, if it exists.
///
/// If the requested stage does not exist, `None` is returned instead.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # fn my_system() {}
/// # let mut schedule = Schedule::default();
/// # schedule.add_stage("my_stage", SystemStage::parallel());
/// #
/// let stage = schedule.get_stage::<SystemStage>(&"my_stage").unwrap();
/// ```
pub fn get_stage<T: Stage>(&self, label: &dyn StageLabel) -> Option<&T> {
self.stages
.get(label)
.and_then(|stage| stage.downcast_ref::<T>())
}
/// Returns a unique, mutable reference to the stage identified by `label`, if it exists.
///
/// If the requested stage does not exist, `None` is returned instead.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # fn my_system() {}
/// # let mut schedule = Schedule::default();
/// # schedule.add_stage("my_stage", SystemStage::parallel());
/// #
/// let stage = schedule.get_stage_mut::<SystemStage>(&"my_stage").unwrap();
pub fn get_stage_mut<T: Stage>(&mut self, label: &dyn StageLabel) -> Option<&mut T> {
self.stages
.get_mut(label)
.and_then(|stage| stage.downcast_mut::<T>())
}
/// Executes each [`Stage`] contained in the schedule, one at a time.
pub fn run_once(&mut self, world: &mut World) {
for label in self.stage_order.iter() {
#[cfg(feature = "trace")]

View file

@ -18,6 +18,7 @@ use std::fmt::Debug;
use super::IntoSystemDescriptor;
/// A type that can run as a step of a [`Schedule`](super::Schedule).
pub trait Stage: Downcast + Send + Sync {
/// Runs the stage; this happens once per update.
/// Implementors must initialize all of their state and systems before running the first time.

View file

@ -1,3 +1,5 @@
//! Storage layouts for ECS data.
mod blob_vec;
mod sparse_set;
mod table;

View file

@ -15,7 +15,23 @@ pub trait Command: Send + Sync + 'static {
fn write(self, world: &mut World);
}
/// A list of commands that will be run to modify a [`World`].
/// A list of commands that modify a [`World`], running at the end of the stage where they
/// have been invoked.
///
/// # Usage
///
/// `Commands` is a [`SystemParam`](crate::system::SystemParam), therefore it is declared
/// as a function parameter:
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// fn my_system(mut commands: Commands) {
/// // ...
/// }
/// ```
///
/// Then, commands can be invoked by calling the methods of `commands`.
pub struct Commands<'w, 's> {
queue: &'s mut CommandQueue,
entities: &'w Entities,
@ -32,6 +48,11 @@ impl<'w, 's> Commands<'w, 's> {
/// Creates a new empty [`Entity`] and returns an [`EntityCommands`] builder for it.
///
/// To directly spawn an entity with a [`Bundle`] included, you can use
/// [`spawn_bundle`](Self::spawn_bundle) instead of `.spawn().insert_bundle()`.
///
/// See [`World::spawn`] for more details.
///
/// # Example
///
/// ```
@ -157,8 +178,35 @@ impl<'w, 's> Commands<'w, 's> {
}
}
/// Equivalent to iterating `bundles_iter` and calling [`Self::spawn`] on each bundle, but
/// slightly more performant.
/// Spawns entities to the [`World`] according to the given iterator (or a type that can
/// be converted to it).
///
/// The end result of this command is equivalent to iterating `bundles_iter` and calling
/// [`spawn`](Self::spawn) on each bundle, but it is more performant due to memory
/// pre-allocation.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Name(String);
/// # struct Score(u32);
/// #
/// # fn system(mut commands: Commands) {
/// commands.spawn_batch(vec![
/// (
/// Name("Alice".to_string()),
/// Score(0),
/// ),
/// (
/// Name("Bob".to_string()),
/// Score(0),
/// ),
/// ]);
/// # }
/// # system.system();
/// ```
pub fn spawn_batch<I>(&mut self, bundles_iter: I)
where
I: IntoIterator + Send + Sync + 'static,
@ -169,9 +217,11 @@ impl<'w, 's> Commands<'w, 's> {
/// For a given batch of ([Entity], [Bundle]) pairs, either spawns each [Entity] with the given
/// bundle (if the entity does not exist), or inserts the [Bundle] (if the entity already exists).
///
/// This is faster than doing equivalent operations one-by-one.
///
/// # Note
///
/// Spawning a specific `entity` value is rarely the right choice. Most apps should use [`Commands::spawn_batch`].
/// This method should generally only be used for sharing entities across apps, and only when they have a scheme
/// worked out to share an ID space (which doesn't happen by default).
@ -184,12 +234,51 @@ impl<'w, 's> Commands<'w, 's> {
self.queue.push(InsertOrSpawnBatch { bundles_iter });
}
/// See [`World::insert_resource`].
/// Inserts a resource to the [`World`], overwriting any previous value of the same type.
///
/// See [`World::insert_resource`] for more details.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Scoreboard {
/// # current_score: u32,
/// # high_score: u32,
/// # }
/// #
/// # fn system(mut commands: Commands) {
/// commands.insert_resource(Scoreboard {
/// current_score: 0,
/// high_score: 0,
/// });
/// # }
/// # system.system();
/// ```
pub fn insert_resource<T: Component>(&mut self, resource: T) {
self.queue.push(InsertResource { resource })
}
/// Queue a resource removal.
/// Removes a resource from the [`World`].
///
/// See [`World::remove_resource`] for more details.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Scoreboard {
/// # current_score: u32,
/// # high_score: u32,
/// # }
/// #
/// # fn system(mut commands: Commands) {
/// commands.remove_resource::<Scoreboard>();
/// # }
/// # system.system();
/// ```
pub fn remove_resource<T: Component>(&mut self) {
self.queue.push(RemoveResource::<T> {
phantom: PhantomData,
@ -197,25 +286,94 @@ impl<'w, 's> Commands<'w, 's> {
}
/// Adds a command directly to the command list.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// use bevy_ecs::system::InsertBundle;
/// #
/// # struct PlayerEntity { entity: Entity }
/// # struct Health(u32);
/// # struct Strength(u32);
/// # struct Defense(u32);
/// #
/// # #[derive(Bundle)]
/// # struct CombatBundle {
/// # health: Health,
/// # strength: Strength,
/// # defense: Defense,
/// # }
///
/// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
/// commands.add(InsertBundle {
/// entity: player.entity,
/// bundle: CombatBundle {
/// health: Health(100),
/// strength: Strength(40),
/// defense: Defense(20),
/// },
/// });
/// }
/// # add_combat_stats_system.system();
/// ```
pub fn add<C: Command>(&mut self, command: C) {
self.queue.push(command);
}
}
/// A list of commands that will be run to modify an [`Entity`].
/// A list of commands that will be run to modify an [entity](crate::entity).
pub struct EntityCommands<'w, 's, 'a> {
entity: Entity,
commands: &'a mut Commands<'w, 's>,
}
impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
/// Retrieves the current entity's unique [`Entity`] id.
/// Returns the [`Entity`] id of the entity.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// fn my_system(mut commands: Commands) {
/// let entity_id = commands.spawn().id();
/// }
/// # my_system.system();
/// ```
#[inline]
pub fn id(&self) -> Entity {
self.entity
}
/// Adds a [`Bundle`] of components to the current entity.
/// Adds a [`Bundle`] of components to the entity.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct PlayerEntity { entity: Entity }
/// # struct Health(u32);
/// # struct Strength(u32);
/// # struct Defense(u32);
/// #
/// # #[derive(Bundle)]
/// # struct CombatBundle {
/// # health: Health,
/// # strength: Strength,
/// # defense: Defense,
/// # }
/// #
/// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
/// commands.entity(player.entity).insert_bundle(CombatBundle {
/// health: Health(100),
/// strength: Strength(40),
/// defense: Defense(20),
/// });
/// }
/// # add_combat_stats_system.system();
/// ```
pub fn insert_bundle(&mut self, bundle: impl Bundle) -> &mut Self {
self.commands.add(InsertBundle {
entity: self.entity,
@ -224,8 +382,10 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
self
}
/// Adds a single [`Component`] to the current entity.
/// Adds a single [`Component`] to the entity.
///
/// See [`EntityMut::insert`](crate::world::EntityMut::insert) for more
/// details.
///
/// # Warning
///
@ -239,18 +399,18 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
/// `Self::insert` can be chained with [`Commands::spawn`].
///
/// ```
/// use bevy_ecs::prelude::*;
///
/// struct Component1;
/// struct Component2;
///
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Component1;
/// # struct Component2;
/// #
/// fn example_system(mut commands: Commands) {
/// // Create a new entity with `Component1` and `Component2`
/// commands.spawn()
/// .insert(Component1)
/// .insert(Component2);
///
/// // Psst! These are also equivalent to the expression above!
/// // The following statements are equivalent to above one.
/// commands.spawn().insert_bundle((Component1, Component2));
/// commands.spawn_bundle((Component1, Component2));
/// }
@ -264,7 +424,26 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
self
}
/// See [`EntityMut::remove_bundle`](crate::world::EntityMut::remove_bundle).
/// Removes a [`Bundle`] of components from the entity.
///
/// See [`EntityMut::remove_bundle`](crate::world::EntityMut::remove_bundle) for more
/// details.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct PlayerEntity { entity: Entity }
/// #
/// # #[derive(Bundle)]
/// # struct CombatBundle { a: u32 }; // dummy field, unit bundles are not permitted.
/// #
/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {
/// commands.entity(player.entity).remove_bundle::<CombatBundle>();
/// }
/// # remove_combat_stats_system.system();
/// ```
pub fn remove_bundle<T>(&mut self) -> &mut Self
where
T: Bundle,
@ -276,7 +455,23 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
self
}
/// See [`EntityMut::remove`](crate::world::EntityMut::remove).
/// Removes a single component from the entity.
///
/// See [`EntityMut::remove`](crate::world::EntityMut::remove) for more details.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct TargetEnemy { entity: Entity }
/// # struct Enemy;
/// #
/// fn convert_enemy_system(mut commands: Commands, enemy: Res<TargetEnemy>) {
/// commands.entity(enemy.entity).remove::<Enemy>();
/// }
/// # convert_enemy_system.system();
/// ```
pub fn remove<T>(&mut self) -> &mut Self
where
T: Component,
@ -288,14 +483,33 @@ impl<'w, 's, 'a> EntityCommands<'w, 's, 'a> {
self
}
/// Despawns only the specified entity, not including its children.
/// Despawns the entity.
///
/// See [`World::despawn`] for more details.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct CharacterToRemove { entity: Entity }
/// #
/// fn remove_character_system(
/// mut commands: Commands,
/// character_to_remove: Res<CharacterToRemove>
/// )
/// {
/// commands.entity(character_to_remove.entity).despawn();
/// }
/// # remove_character_system.system();
/// ```
pub fn despawn(&mut self) {
self.commands.add(Despawn {
entity: self.entity,
})
}
/// Returns the underlying `[Commands]`.
/// Returns the underlying [`Commands`].
pub fn commands(&mut self) -> &mut Commands<'w, 's> {
self.commands
}

View file

@ -1,3 +1,68 @@
//! Tools for controlling behavior in an ECS application.
//!
//! Systems define how an ECS based application behaves. They have to be registered to a
//! [`SystemStage`](crate::schedule::SystemStage) to be able to run. A system is usually
//! written as a normal function that will be automatically converted into a system.
//!
//! System functions can have parameters, through which one can query and mutate Bevy ECS state.
//! Only types that implement [`SystemParam`] can be used, automatically fetching data from
//! the [`World`](crate::world::World).
//!
//! System functions often look like this:
//!
//! ```
//! # use bevy_ecs::prelude::*;
//! #
//! # struct Player { alive: bool }
//! # struct Score(u32);
//! # struct Round(u32);
//! #
//! fn update_score_system(
//! mut query: Query<(&Player, &mut Score)>,
//! mut round: ResMut<Round>,
//! ) {
//! for (player, mut score) in query.iter_mut() {
//! if player.alive {
//! score.0 += round.0;
//! }
//! }
//! round.0 += 1;
//! }
//! # update_score_system.system();
//! ```
//!
//! # System ordering
//!
//! While the execution of systems is usually parallel and not deterministic, there are two
//! ways to determine a certain degree of execution order:
//!
//! - **System Stages:** They determine hard execution synchronization boundaries inside of
//! which systems run in parallel by default.
//! - **Labeling:** First, systems are labeled upon creation by calling `.label()`. Then,
//! methods such as `.before()` and `.after()` are appended to systems to determine
//! execution order in respect to other systems.
//!
//! # System parameter list
//! Following is the complete list of accepted types as system parameters:
//!
//! - [`Query`]
//! - [`Res`] and `Option<Res>`
//! - [`ResMut`] and `Option<ResMut>`
//! - [`Commands`]
//! - [`Local`]
//! - [`EventReader`](crate::event::EventReader)
//! - [`EventWriter`](crate::event::EventWriter)
//! - [`NonSend`] and `Option<NonSend>`
//! - [`NonSendMut`] and `Option<NonSendMut>`
//! - [`RemovedComponents`]
//! - [`SystemChangeTick`]
//! - [`Archetypes`](crate::archetype::Archetypes) (Provides Archetype metadata)
//! - [`Bundles`](crate::bundle::Bundles) (Provides Bundles metadata)
//! - [`Components`](crate::component::Components) (Provides Components metadata)
//! - [`Entities`](crate::entity::Entities) (Provides Entities metadata)
//! - All tuples between 1 to 16 elements where each element implements [`SystemParam`]
//! - [`()` (unit primitive type)](https://doc.rust-lang.org/stable/std/primitive.unit.html)
mod commands;
mod exclusive_system;
mod function_system;

View file

@ -11,102 +11,225 @@ use bevy_tasks::TaskPool;
use std::{any::TypeId, fmt::Debug};
use thiserror::Error;
/// Provides scoped access to a [`World`] according to a given [`WorldQuery`] and query filter.
/// Provides scoped access to components in a [`World`].
///
/// Queries are a powerful tool enabling the programmer to iterate over entities and their components
/// as well as filtering them on certain conditions.
/// Queries enable iteration over entities and their components as well as filtering them
/// on certain conditions. A query matches its parameters against the world to produce a series
/// of results. Each *query result* is a tuple of components (the same components defined
/// in the query) that belong to the same entity.
///
/// # Query Building Primer
/// Computational cost of queries is reduced by the fact that they have an internal archetype
/// cache to avoid re-computing archetype matches on each query access.
///
/// ### Basic Component Access
/// Query functionality is based on the [`WorldQuery`] trait. Both tuples of components
/// (up to 16 elements) and query filters implement this trait.
///
/// A basic query looks like `Query<&UnitHealth>` and all it does is grant immutable access to all
/// `UnitHealth` components. Similarly using `&mut UnitHealth` instead grants mutable access instead.
/// `Query` accepts two type parameters:
///
/// The main way to access the components of a query is through the [`Query::iter`] and [`Query::iter_mut`]
/// functions which return a [`QueryIter`] to iterate over:
/// 1. **Component access:** the components that an entity must have at the same time to yield
/// a query result.
/// 2. **Query filters (optional):** a predicate that ignores query results that don't match
/// its conditions.
///
/// # Usage as system parameter
///
/// A query is defined by declaring it as a system parameter. This section shows the various
/// use cases of `Query` as a system parameter.
///
/// ## Immutable component access
///
/// The following example defines a query that gives an iterator over `(&ComponentA, &ComponentB)`
/// tuples, where `ComponentA` and `ComponentB` belong to the same entity. Accessing components
/// immutably helps system parallelization.
///
/// ```
/// # use bevy_ecs::system::IntoSystem;
/// # use bevy_ecs::system::Query;
/// struct UnitHealth(pub u32);
/// fn system(query: Query<&UnitHealth>) {
/// for UnitHealth(health) in query.iter() {
/// println!("We got {} health points left!", health);
/// }
/// }
/// # struct ComponentA;
/// # struct ComponentB;
/// # fn system(
/// query: Query<(&ComponentA, &ComponentB)>
/// # ) {}
/// # system.system();
/// ```
///
/// ### Multiple Component Access
/// ## Mutable component access
///
/// Instead of asking for just one component like before we can build a query that queries for multiple
/// components with the help of tuples,`Query<(&Shape, &Color, &mut Size)>`. This query retrieves
/// immutable references to the `Shape` and `Color` component and a mutable reference to the `Size`
/// component.
/// The following example is similar to the previous one, with the exception of `ComponentA`
/// being accessed mutably here. Note that both mutable and immutable accesses are allowed
/// in the same query.
///
/// ```
/// # use bevy_ecs::system::IntoSystem;
/// # use bevy_ecs::system::Query;
/// #[derive(Debug)]
/// enum Shape {
/// Circle,
/// Box,
/// };
/// struct Color(pub String);
/// struct Size(pub u32);
/// fn system(mut query: Query<(&Shape, &Color, &mut Size)>) {
/// for (shape, color, mut size) in query.iter_mut() {
/// *size = Size(1);
/// println!("We got a {} colored {:?} and made it one unit big!", color.0, shape);
/// }
/// }
/// # struct ComponentA;
/// # struct ComponentB;
/// # fn system(
/// // `ComponentA` is accessed mutably, while `ComponentB` is accessed immutably.
/// mut query: Query<(&mut ComponentA, &ComponentB)>
/// # ) {}
/// # system.system();
/// ```
///
/// Note the use of [`Query::iter_mut`] here, as our query is not read-only anymore due to the use
/// of the `&mut` [`WorldQuery`] we aren't able to use the `iter` method any longer.
/// Two systems cannot be executed in parallel if both access a certain component and
/// at least one of the accesses is mutable, unless the schedule can verify that no entity
/// could be found in both queries, as otherwise Rusts mutability Rules would be broken.
///
/// ### Filtering Query Results
/// Similarly, a system cannot contain two queries that would break Rust's mutability Rules.
/// If you need such Queries, you can use Filters to make the Queries disjoint or use a
/// [`QuerySet`](super::QuerySet).
///
/// Queries also support filters. A filter is a [`WorldQuery`] that can be used as a predicate to
/// filter out entities that do not meet the requirement set by the predicate. [`With`](crate::query::With)
/// is one such filter and all it does is filter out all entities that do not contain the component
/// it requests. Let's look at an example on how to use this filter.
/// ## Entity ID access
///
/// Inserting [`Entity`](crate::entity::Entity) at any position in the type parameter tuple
/// will give access to the entity ID.
///
/// ```
/// # use bevy_ecs::entity::Entity;
/// # use bevy_ecs::system::IntoSystem;
/// # use bevy_ecs::system::Query;
/// # struct ComponentA;
/// # struct ComponentB;
/// # fn system(
/// query: Query<(Entity, &ComponentA, &ComponentB)>
/// # ) {}
/// # system.system();
/// ```
///
/// ## Query filtering
///
/// The second, optional type parameter of query, is used for filters can be added to filter
/// out the query results that don't satisfy the given condition.
///
/// ```
/// # use bevy_ecs::query::With;
/// struct Person(String);
/// struct IsTallEnough;
/// fn system(query: Query<&Person, With<IsTallEnough>>) {
/// for person in query.iter() {
/// println!("{} is tall enough!", person.0);
/// }
/// }
/// # use bevy_ecs::system::IntoSystem;
/// # use bevy_ecs::system::Query;
/// # struct ComponentA;
/// # struct ComponentB;
/// # struct ComponentC;
/// # fn system(
/// // `ComponentC` data won't be accessed, but only entities that contain it will be queried.
/// query: Query<(&ComponentA, &ComponentB), With<ComponentC>>
/// # ) {}
/// # system.system();
/// ```
///
/// As shown above, the filter is a second type parameter of the query. It is optional (defaults to
/// ()). Filters do not give access to the component data, only limit the entities that the query will match.
/// If you need to apply more filters in a single query, group them into a tuple:
///
/// ### Optional Components
/// ```
/// # use bevy_ecs::query::{Changed, With};
/// # use bevy_ecs::system::IntoSystem;
/// # use bevy_ecs::system::Query;
/// # struct ComponentA;
/// # struct ComponentB;
/// # struct ComponentC;
/// # fn system(
/// // Similar to the previous query, but with the addition of a `Changed` filter.
/// query: Query<(&ComponentA, &ComponentB), (With<ComponentC>, Changed<ComponentA>)>
/// # ) {}
/// # system.system();
/// ```
///
/// Now we've seen how to narrow down results of a query, but what if we want to act on entities that
/// may have a component but not always. This is where [`Option`] comes into play, with `Option` we
/// can specify just that. The result of the following query, `Query<&Color, Option<&mut Size>>`, is
/// the tuple `(&Color, Option<&mut Size>)` containing all entities that have the `Color` component,
/// some of which also have a `Size` component. Note that we didn't put a [`Component`] inside the
/// `Option` but a [`WorldQuery`], `&mut T` in this case. This means we can also do the following
/// just fine, `Query<Option<(&Size, &Color)>>`.
/// The following list contains all the available query filters:
///
/// Do take care when handling optional components though, as iterating a query that solely consists
/// of optional components will go over all the entities of the [`World`]. Therefore it's best to
/// design your queries in such a way that they at least contain one non-optional [`WorldQuery`].
/// - [`Added`](crate::query::Added)
/// - [`Changed`](crate::query::Changed)
/// - [`With`](crate::query::With)
/// - [`Without`](crate::query::Without)
/// - [`Or`](crate::query::Or)
///
/// This touches all the basics of queries, make sure to check out all the [`WorldQueries`](WorldQuery)
/// bevy has to offer.
/// ## Optional component access
///
/// A component can be made optional in a query by wrapping it into an [`Option`]. In the
/// following example, the query will iterate over components of both entities that contain
/// `ComponentA` and `ComponentB`, and entities that contain `ComponentA` but not `ComponentB`.
///
/// ```
/// # use bevy_ecs::system::IntoSystem;
/// # use bevy_ecs::system::Query;
/// # struct ComponentA;
/// # struct ComponentB;
/// # fn system(
/// query: Query<(&ComponentA, Option<&ComponentB>)>
/// # ) {}
/// # system.system();
/// ```
///
/// If an entity does not contain a component, its corresponding query result value will be
/// `None`. Optional components increase the number of entities a query has to match against,
/// therefore they can hurt iteration performance, especially in the worst case scenario where
/// the query solely consists of only optional components, since all entities will be iterated
/// over.
///
/// ## Single component access
///
/// If just a single component needs to be accessed, using a tuple as the first type parameter
/// of `Query` can be omitted.
///
/// ```
/// # use bevy_ecs::system::IntoSystem;
/// # use bevy_ecs::system::Query;
/// # struct MyComponent;
/// # fn tuple_system(
/// // This is correct, but can be avoided.
/// query: Query<(&MyComponent,)>
/// # ) {}
/// # tuple_system.system();
///
/// # fn non_tuple_system(
/// // This is the preferred method.
/// query: Query<&MyComponent>
/// # ) {}
/// # non_tuple_system.system();
/// ```
///
/// # Usage of query results
///
/// Inside the body of the system function, the `Query` is available as a function parameter.
/// This section shows various methods to access query results.
///
/// ## Iteration over every query result
///
/// The [`iter`](Self::iter) and [`iter_mut`](Self::iter_mut) methods are used to iterate
/// over every query result. Refer to the
/// [`Iterator` API docs](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html)
/// for advanced iterator usage.
///
/// ```
/// # use bevy_ecs::system::IntoSystem;
/// # use bevy_ecs::system::Query;
/// # struct ComponentA;
/// # struct ComponentB;
/// fn immutable_query_system(mut query: Query<(&ComponentA, &ComponentB)>) {
/// for (a, b) in query.iter() {
/// // Here, `a` and `b` are normal references to components, relatively of
/// // `&ComponentA` and `&ComponentB` types.
/// }
/// }
/// # immutable_query_system.system();
///
/// fn mutable_query_system(mut query: Query<(&mut ComponentA, &ComponentB)>) {
/// for (mut a, b) in query.iter_mut() {
/// // Similar to the above system, but this time `ComponentA` can be accessed mutably.
/// // Note the usage of `mut` in the tuple and the call to `iter_mut` instead of `iter`.
/// }
/// }
/// # mutable_query_system.system();
/// ```
///
/// ## Getting the query result for a particular entity
///
/// If you have an [`Entity`] ID, you can use the [`get`](Self::get) or
/// [`get_mut`](Self::get_mut) methods to access the query result for that particular entity.
///
/// ## Getting a single query result
///
/// While it's possible to get a single result from a query by using `iter.next()`, a more
/// idiomatic approach would use the [`single`](Self::single) or [`single_mut`](Self::single_mut)
/// methods instead. Keep in mind though that they will return a [`QuerySingleError`] if the
/// number of query results differ from being exactly one. If that's the case, use `iter.next()`
/// (or `iter_mut.next()`) to only get the first query result.
pub struct Query<'world, 'state, Q: WorldQuery, F: WorldQuery = ()>
where
F::Fetch: FilterFetch,
@ -144,7 +267,26 @@ where
/// Returns an [`Iterator`] over the query results.
///
/// This can only be called for read-only queries, see [`Self::iter_mut`] for write-queries.
/// This can only be called for read-only queries (due to the [`ReadOnlyFetch`] trait
/// bound). See [`Self::iter_mut`] for queries that contain at least one mutable component.
///
/// # Example
///
/// Here, the `report_names_system` iterates over the `Player` component of every entity
/// that contains it:
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Player { name: String }
/// #
/// fn report_names_system(query: Query<&Player>) {
/// for player in query.iter() {
/// println!("Say hello to {}!", player.name);
/// }
/// }
/// # report_names_system.system();
/// ```
#[inline]
pub fn iter(&'s self) -> QueryIter<'w, 's, Q, F>
where
@ -159,6 +301,24 @@ where
}
/// Returns an [`Iterator`] over the query results.
///
/// # Example
///
/// Here, the `gravity_system` iterates over the `Velocity` component of every entity in
/// the world that contains it in order to update it:
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Velocity { x: f32, y: f32, z: f32 }
/// fn gravity_system(mut query: Query<&mut Velocity>) {
/// const DELTA: f32 = 1.0 / 60.0;
/// for mut velocity in query.iter_mut() {
/// velocity.y -= 9.8 * DELTA;
/// }
/// }
/// # gravity_system.system();
/// ```
#[inline]
pub fn iter_mut(&mut self) -> QueryIter<'_, '_, Q, F> {
// SAFE: system runs without conflicts with other systems.
@ -265,6 +425,24 @@ where
/// be chained like a normal [`Iterator`].
///
/// This can only be called for read-only queries, see [`Self::for_each_mut`] for write-queries.
///
/// # Example
///
/// Here, the `report_names_system` iterates over the `Player` component of every entity
/// that contains it:
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Player { name: String }
/// #
/// fn report_names_system(query: Query<&Player>) {
/// query.for_each(|player| {
/// println!("Say hello to {}!", player.name);
/// });
/// }
/// # report_names_system.system();
/// ```
#[inline]
pub fn for_each(&'s self, f: impl FnMut(<Q::Fetch as Fetch<'w, 's>>::Item))
where
@ -284,6 +462,24 @@ where
/// Runs `f` on each query result. This is faster than the equivalent iter() method, but cannot
/// be chained like a normal [`Iterator`].
///
/// # Example
///
/// Here, the `gravity_system` iterates over the `Velocity` component of every entity in
/// the world that contains it in order to update it:
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Velocity { x: f32, y: f32, z: f32 }
/// fn gravity_system(mut query: Query<&mut Velocity>) {
/// const DELTA: f32 = 1.0 / 60.0;
/// query.for_each_mut(|mut velocity| {
/// velocity.y -= 9.8 * DELTA;
/// });
/// }
/// # gravity_system.system();
/// ```
#[inline]
pub fn for_each_mut<'a>(&'a mut self, f: impl FnMut(<Q::Fetch as Fetch<'a, 'a>>::Item)) {
// SAFE: system runs without conflicts with other systems. same-system queries have runtime
@ -347,9 +543,36 @@ where
};
}
/// Gets the query result for the given [`Entity`].
/// Returns the query result for the given [`Entity`].
///
/// This can only be called for read-only queries, see [`Self::get_mut`] for write-queries.
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
/// returned instead.
///
/// This can only be called for read-only queries (due to the [`ReadOnlyFetch`] trait bound).
/// see [`get_mut`](Self::get_mut) for queries that contain at least one mutable component.
///
/// # Example
///
/// Here, `get` is used to retrieve the exact query result of the entity specified by the
/// `SelectedCharacter` resource.
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct SelectedCharacter { entity: Entity }
/// # struct Character { name: String }
/// #
/// fn print_selected_character_name_system(
/// query: Query<&Character>,
/// selection: Res<SelectedCharacter>
/// )
/// {
/// if let Ok(selected_character) = query.get(selection.entity) {
/// println!("{}", selected_character.name);
/// }
/// }
/// # print_selected_character_name_system.system();
/// ```
#[inline]
pub fn get(
&'s self,
@ -370,7 +593,29 @@ where
}
}
/// Gets the query result for the given [`Entity`].
/// Returns the query result for the given [`Entity`].
///
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
/// returned instead.
///
/// # Example
///
/// Here, `get_mut` is used to retrieve the exact query result of the entity specified by the
/// `PoisonedCharacter` resource.
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct PoisonedCharacter { character_id: Entity }
/// # struct Health(u32);
/// #
/// fn poison_system(mut query: Query<&mut Health>, poisoned: Res<PoisonedCharacter>) {
/// if let Ok(mut health) = query.get_mut(poisoned.character_id) {
/// health.0 -= 1;
/// }
/// }
/// # poison_system.system();
/// ```
#[inline]
pub fn get_mut(
&mut self,
@ -388,7 +633,10 @@ where
}
}
/// Gets the query result for the given [`Entity`].
/// Returns the query result for the given [`Entity`].
///
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
/// returned instead.
///
/// # Safety
///
@ -405,9 +653,33 @@ where
.get_unchecked_manual(self.world, entity, self.last_change_tick, self.change_tick)
}
/// Gets a reference to the [`Entity`]'s [`Component`] of the given type. This will fail if the
/// entity does not have the given component type or if the given component type does not match
/// this query.
/// Returns a reference to the [`Entity`]'s [`Component`] of the given type.
///
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
/// returned instead.
///
/// # Example
///
/// Here, `get_component` is used to retrieve the `Character` component of the entity
/// specified by the `SelectedCharacter` resource.
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct SelectedCharacter { entity: Entity }
/// # struct Character { name: String }
/// #
/// fn print_selected_character_name_system(
/// query: Query<&Character>,
/// selection: Res<SelectedCharacter>
/// )
/// {
/// if let Ok(selected_character) = query.get_component::<Character>(selection.entity) {
/// println!("{}", selected_character.name);
/// }
/// }
/// # print_selected_character_name_system.system();
/// ```
#[inline]
pub fn get_component<T: Component>(
&self,
@ -438,9 +710,29 @@ where
}
}
/// Gets a mutable reference to the [`Entity`]'s [`Component`] of the given type. This will fail
/// if the entity does not have the given component type or if the given component type does not
/// match this query.
/// Returns a mutable reference to the [`Entity`]'s [`Component`] of the given type.
///
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
/// returned instead.
///
/// # Example
///
/// Here, `get_component_mut` is used to retrieve the `Health` component of the entity
/// specified by the `PoisonedCharacter` resource.
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct PoisonedCharacter { character_id: Entity }
/// # struct Health(u32);
/// #
/// fn poison_system(mut query: Query<&mut Health>, poisoned: Res<PoisonedCharacter>) {
/// if let Ok(mut health) = query.get_component_mut::<Health>(poisoned.character_id) {
/// health.0 -= 1;
/// }
/// }
/// # poison_system.system();
/// ```
#[inline]
pub fn get_component_mut<T: Component>(
&mut self,
@ -450,9 +742,10 @@ where
unsafe { self.get_component_unchecked_mut(entity) }
}
/// Gets a mutable reference to the [`Entity`]'s [`Component`] of the given type. This will fail
/// if the entity does not have the given component type or the component does not match the
/// query.
/// Returns a mutable reference to the [`Entity`]'s [`Component`] of the given type.
///
/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
/// returned instead.
///
/// # Safety
///
@ -488,25 +781,30 @@ where
}
}
/// Gets the result of a single-result query.
/// Returns a single immutable query result when there is exactly one entity matching
/// the query.
///
/// Assumes this query has only one result and panics if there are no or multiple results.
/// Use [`Self::get_single`] to handle the error cases explicitly
/// This can only be called for read-only queries (due to the [`ReadOnlyFetch`] trait
/// bound). Use [`single_mut`](Self::single_mut) for queries that contain at least one
/// mutable component.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::{IntoSystem, Query, With};
/// struct Player;
/// struct Position(f32, f32);
/// # use bevy_ecs::prelude::{IntoSystem, Query, With};
/// # struct Player;
/// # struct Position(f32, f32);
/// fn player_system(query: Query<&Position, With<Player>>) {
/// let player_position = query.single();
/// // do something with player_position
/// }
/// # let _check_that_its_a_system = player_system.system();
/// # player_system.system();
/// ```
///
/// This can only be called for read-only queries, see [`Self::single_mut`] for write-queries.
/// # Panics
///
/// Panics if the number of query results is not exactly one. Use
/// [`get_single`](Self::get_single) to return a `Result` instead of panicking.
#[track_caller]
pub fn single(&'s self) -> <Q::Fetch as Fetch<'w, 's>>::Item
where
@ -515,36 +813,37 @@ where
self.get_single().unwrap()
}
/// Gets the result of a single-result query.
/// Returns a single immutable query result when there is exactly one entity matching
/// the query.
///
/// If the query has exactly one result, returns the result inside `Ok`
/// otherwise returns either [`QuerySingleError::NoEntities`]
/// or [`QuerySingleError::MultipleEntities`], as appropriate.
/// This can only be called for read-only queries (due to the [`ReadOnlyFetch`] trait
/// bound). Use [`get_single_mut`](Self::get_single_mut) for queries that contain at least one
/// mutable component.
///
/// # Examples
/// If the number of query results is not exactly one, a [`QuerySingleError`] is returned
/// instead.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::{IntoSystem, With};
/// # use bevy_ecs::system::{Query, QuerySingleError};
/// struct Player;
/// struct Position(f32, f32);
/// fn player_system(query: Query<&Position, With<Player>>) {
/// # use bevy_ecs::prelude::IntoSystem;
/// # struct PlayerScore(i32);
/// fn player_scoring_system(query: Query<&PlayerScore>) {
/// match query.get_single() {
/// Ok(position) => {
/// // do something with position
/// Ok(PlayerScore(score)) => {
/// println!("Score: {}", score);
/// }
/// Err(QuerySingleError::NoEntities(_)) => {
/// // no position with Player
/// println!("Error: There is no player!");
/// }
/// Err(QuerySingleError::MultipleEntities(_)) => {
/// // multiple position with Player
/// println!("Error: There is more than one player!");
/// }
/// }
/// }
/// # let _check_that_its_a_system = player_system.system();
/// # player_scoring_system.system();
/// ```
///
/// This can only be called for read-only queries, see [`Self::get_single_mut`] for write-queries.
pub fn get_single(&'s self) -> Result<<Q::Fetch as Fetch<'w, 's>>::Item, QuerySingleError>
where
Q::Fetch: ReadOnlyFetch,
@ -562,15 +861,53 @@ where
}
}
/// Gets the query result if it is only a single result, otherwise panics
/// If you want to handle the error case yourself you can use the [`Self::get_single_mut`] variant.
/// Returns a single mutable query result when there is exactly one entity matching
/// the query.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Player;
/// # struct Health(u32);
/// #
/// fn regenerate_player_health_system(mut query: Query<&mut Health, With<Player>>) {
/// let mut health = query.single_mut();
/// health.0 += 1;
/// }
/// # regenerate_player_health_system.system();
/// ```
///
/// # Panics
///
/// Panics if the number of query results is not exactly one. Use
/// [`get_single_mut`](Self::get_single_mut) to return a `Result` instead of panicking.
#[track_caller]
pub fn single_mut(&mut self) -> <Q::Fetch as Fetch<'_, '_>>::Item {
self.get_single_mut().unwrap()
}
/// Gets the query result if it is only a single result, otherwise returns a
/// [`QuerySingleError`].
/// Returns a single mutable query result when there is exactly one entity matching
/// the query.
///
/// If the number of query results is not exactly one, a [`QuerySingleError`] is returned
/// instead.
///
/// # Example
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Player;
/// # struct Health(u32);
/// #
/// fn regenerate_player_health_system(mut query: Query<&mut Health, With<Player>>) {
/// let mut health = query.get_single_mut().expect("Error: Could not find a single player.");
/// health.0 += 1;
/// }
/// # regenerate_player_health_system.system();
/// ```
pub fn get_single_mut(
&mut self,
) -> Result<<Q::Fetch as Fetch<'_, '_>>::Item, QuerySingleError> {
@ -587,7 +924,25 @@ where
}
}
/// Returns true if this query contains no elements.
/// Returns `true` if there are no query results.
///
/// # Example
///
/// Here, the score is increased only if an entity with a `Player` component is present
/// in the world:
///
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # struct Player;
/// # struct Score(u32);
/// fn update_score_system(query: Query<(), With<Player>>, mut score: ResMut<Score>) {
/// if !query.is_empty() {
/// score.0 += 1;
/// }
/// }
/// # update_score_system.system();
/// ```
#[inline]
pub fn is_empty(&self) -> bool {
// TODO: This code can be replaced with `self.iter().next().is_none()` if/when

View file

@ -23,7 +23,8 @@ use std::{
///
/// # Derive
///
/// This trait can be derived with the [`derive@super::SystemParam`] macro.
/// This trait can be derived with the [`derive@super::SystemParam`] macro. The only requirement
/// is that every struct field must also implement `SystemParam`.
///
/// ```
/// # use bevy_ecs::prelude::*;
@ -201,6 +202,10 @@ impl_query_set!();
/// Shared borrow of a resource.
///
/// See the [`World`] documentation to see the usage of a resource.
///
/// If you need a unique mutable borrow, use [`ResMut`] instead.
///
/// # Panics
///
/// Panics when used as a [`SystemParameter`](SystemParam) if the resource does not exist.

View file

@ -34,11 +34,48 @@ impl Default for WorldId {
}
}
/// [World] stores and exposes operations on [entities](Entity), [components](Component),
/// Stores and exposes operations on [entities](Entity), [components](Component), resources,
/// and their associated metadata.
///
/// Each [Entity] has a set of components. Each component can have up to one instance of each
/// component type. Entity components can be created, updated, removed, and queried using a given
/// [World].
///
/// # Resources
///
/// Worlds can also store *resources*, which are unique instances of a given type that don't
/// belong to a specific Entity. There are also *non send resources*, which can only be
/// accessed on the main thread.
///
/// ## Usage of global resources
///
/// 1. Insert the resource into the `World`, using [`World::insert_resource`].
/// 2. Fetch the resource from a system, using [`Res`](crate::system::Res) or [`ResMut`](crate::system::ResMut).
///
/// ```
/// # let mut world = World::default();
/// # let mut schedule = Schedule::default();
/// # schedule.add_stage("update", SystemStage::parallel());
/// # use bevy_ecs::prelude::*;
/// #
/// struct MyResource { value: u32 }
///
/// world.insert_resource(MyResource { value: 42 });
///
/// fn read_resource_system(resource: Res<MyResource>) {
/// assert_eq!(resource.value, 42);
/// }
///
/// fn write_resource_system(mut resource: ResMut<MyResource>) {
/// assert_eq!(resource.value, 42);
/// resource.value = 0;
/// assert_eq!(resource.value, 0);
/// }
/// #
/// # schedule.add_system_to_stage("update", read_resource_system.label("first"));
/// # schedule.add_system_to_stage("update", write_resource_system.after("first"));
/// # schedule.run_once(&mut world);
/// ```
pub struct World {
id: WorldId,
pub(crate) entities: Entities,