mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
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:
parent
064af63400
commit
615d43b998
18 changed files with 1348 additions and 202 deletions
|
@ -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 {
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Types for declaring and storing [`Component`]s.
|
||||
|
||||
use crate::storage::SparseSetIndex;
|
||||
use std::{
|
||||
alloc::Layout,
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Event handling types.
|
||||
|
||||
use crate as bevy_ecs;
|
||||
use crate::{
|
||||
component::Component,
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Types that enable reflection support.
|
||||
|
||||
pub use crate::change_detection::ReflectMut;
|
||||
use crate::{
|
||||
component::Component,
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Storage layouts for ECS data.
|
||||
|
||||
mod blob_vec;
|
||||
mod sparse_set;
|
||||
mod table;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue