diff --git a/crates/bevy_ecs/src/system/commands.rs b/crates/bevy_ecs/src/system/commands.rs index c8f5a5731d..aa31646b56 100644 --- a/crates/bevy_ecs/src/system/commands.rs +++ b/crates/bevy_ecs/src/system/commands.rs @@ -7,17 +7,20 @@ use crate::{ use bevy_utils::tracing::debug; use std::marker::PhantomData; -/// A [World] mutation +/// A [`World`] mutation. pub trait Command: Send + Sync + 'static { fn write(self: Box, world: &mut World); } +/// A queue of [`Command`]s. #[derive(Default)] pub struct CommandQueue { commands: Vec>, } impl CommandQueue { + /// Execute the queued [`Command`]s in the world. + /// This clears the queue. pub fn apply(&mut self, world: &mut World) { world.flush(); for command in self.commands.drain(..) { @@ -25,24 +28,27 @@ impl CommandQueue { } } + /// Push a boxed [`Command`] onto the queue. #[inline] pub fn push_boxed(&mut self, command: Box) { self.commands.push(command); } + /// Push a [`Command`] onto the queue. #[inline] pub fn push(&mut self, command: T) { self.push_boxed(Box::new(command)); } } -/// A list of commands that will be run to modify a `World` +/// A list of commands that will be run to modify a [`World`]. pub struct Commands<'a> { queue: &'a mut CommandQueue, entities: &'a Entities, } impl<'a> Commands<'a> { + /// Create a new `Commands` from a queue and a world. pub fn new(queue: &'a mut CommandQueue, world: &'a World) -> Self { Self { queue, @@ -50,7 +56,7 @@ impl<'a> Commands<'a> { } } - /// Creates a new empty entity and returns an [EntityCommands] builder for it. + /// Creates a new empty [`Entity`] and returns an [`EntityCommands`] builder for it. /// /// # Example /// @@ -80,10 +86,10 @@ impl<'a> Commands<'a> { /// Creates a new entity with the components contained in `bundle`. /// - /// This returns an [EntityCommands] builder, which enables inserting more components and bundles + /// This returns an [`EntityCommands`] builder, which enables inserting more components and bundles /// using a "builder pattern". /// - /// Note that `bundle` is a [Bundle], which is a collection of components. [Bundle] is + /// Note that `bundle` is a [`Bundle`], which is a collection of components. [`Bundle`] is /// automatically implemented for tuples of components. You can also create your own bundle /// types by deriving [`derive@Bundle`]. /// @@ -124,7 +130,7 @@ impl<'a> Commands<'a> { e } - /// Returns an [EntityCommands] builder for the requested `entity`. + /// Returns an [`EntityCommands`] builder for the requested [`Entity`]. /// /// # Example /// @@ -160,39 +166,38 @@ impl<'a> Commands<'a> { self.queue.push(SpawnBatch { bundles_iter }); } - /// See [World::insert_resource]. + /// See [`World::insert_resource`]. pub fn insert_resource(&mut self, resource: T) { self.queue.push(InsertResource { resource }) } + /// Queue a resource removal. pub fn remove_resource(&mut self) { self.queue.push(RemoveResource:: { phantom: PhantomData, }); } - /// Adds a command directly to the command list. Prefer this to [`Self::add_command_boxed`] if - /// the type of `command` is statically known. + /// Adds a command directly to the command list. pub fn add(&mut self, command: C) { self.queue.push(command); } } +/// A list of commands that will be run to modify an [`Entity`]. pub struct EntityCommands<'a, 'b> { entity: Entity, commands: &'b mut Commands<'a>, } impl<'a, 'b> EntityCommands<'a, 'b> { - /// Retrieves the current entity's unique [Entity] id. + /// Retrieves the current entity's unique [`Entity`] id. #[inline] pub fn id(&self) -> Entity { self.entity } - /// Adds a bundle of components to the current entity. - /// - /// See [`Self::with`], [`Self::current_entity`]. + /// Adds a [`Bundle`] of components to the current entity. pub fn insert_bundle(&mut self, bundle: impl Bundle) -> &mut Self { self.commands.add(InsertBundle { entity: self.entity, @@ -201,9 +206,8 @@ impl<'a, 'b> EntityCommands<'a, 'b> { self } - /// Adds a single component to the current entity. + /// Adds a single [`Component`] to the current entity. /// - /// See [`Self::insert_bundle`], [`Self::id`]. /// /// # Warning /// @@ -214,7 +218,7 @@ impl<'a, 'b> EntityCommands<'a, 'b> { /// /// # Example /// - /// [`Self::insert`] can be chained with [`Self::spawn`]. + /// `Self::insert` can be chained with [`Commands::spawn`]. /// /// ``` /// use bevy_ecs::prelude::*; @@ -242,7 +246,7 @@ impl<'a, 'b> EntityCommands<'a, 'b> { self } - /// See [crate::world::EntityMut::remove_bundle]. + /// See [`EntityMut::remove_bundle`](crate::world::EntityMut::remove_bundle). pub fn remove_bundle(&mut self) -> &mut Self where T: Bundle, @@ -254,7 +258,7 @@ impl<'a, 'b> EntityCommands<'a, 'b> { self } - /// See [crate::world::EntityMut::remove]. + /// See [`EntityMut::remove`](crate::world::EntityMut::remove). pub fn remove(&mut self) -> &mut Self where T: Component, @@ -273,6 +277,7 @@ impl<'a, 'b> EntityCommands<'a, 'b> { }) } + /// Returns the underlying `[Commands]`. pub fn commands(&mut self) -> &mut Commands<'a> { self.commands } @@ -323,7 +328,7 @@ impl Command for Despawn { } } -pub struct InsertBundle { +pub(crate) struct InsertBundle { entity: Entity, bundle: T, } @@ -388,7 +393,7 @@ where } } -pub struct InsertResource { +pub(crate) struct InsertResource { resource: T, } @@ -398,7 +403,7 @@ impl Command for InsertResource { } } -pub struct RemoveResource { +pub(crate) struct RemoveResource { phantom: PhantomData, } diff --git a/crates/bevy_ecs/src/system/into_system.rs b/crates/bevy_ecs/src/system/into_system.rs index 4a48a3878e..5ec5b707e9 100644 --- a/crates/bevy_ecs/src/system/into_system.rs +++ b/crates/bevy_ecs/src/system/into_system.rs @@ -10,6 +10,7 @@ use crate::{ use bevy_ecs_macros::all_tuples; use std::{borrow::Cow, marker::PhantomData}; +/// The state of a [`System`]. pub struct SystemState { pub(crate) id: SystemId, pub(crate) name: Cow<'static, str>, @@ -33,18 +34,37 @@ impl SystemState { } } + /// Returns true if the system is [`Send`]. #[inline] pub fn is_send(&self) -> bool { self.is_send } + /// Sets the system to be not [`Send`]. + /// + /// This is irreversible. #[inline] pub fn set_non_send(&mut self) { self.is_send = false; } } +/// Conversion trait to turn something into a [`System`]. +/// +/// Use this to get a system from a function. Also note that every system implements this trait as well. +/// +/// # Examples +/// +/// ``` +/// use bevy_ecs::system::IntoSystem; +/// use bevy_ecs::system::Res; +/// +/// fn my_system_function(an_usize_resource: Res) {} +/// +/// let system = my_system_function.system(); +/// ``` pub trait IntoSystem { + /// Turns this value into its corresponding [`System`]. fn system(self) -> SystemType; } @@ -55,9 +75,40 @@ impl IntoSystem<(), Sys> for Sys { } } +/// Wrapper type to mark a [`SystemParam`] as an input. +/// +/// [`System`]s may take an optional input which they require to be passed to them when they +/// are being [`run`](System::run). For [`FunctionSystems`](FunctionSystem) the input may be marked +/// with this `In` type, but only the first param of a function may be tagged as an input. This also +/// means a system can only have one or zero input paramaters. +/// +/// # Examples +/// +/// Here is a simple example of a system that takes a [`usize`] returning the square of it. +/// +/// ``` +/// use bevy_ecs::prelude::*; +/// +/// fn main() { +/// let mut square_system = square.system(); +/// +/// let mut world = World::default(); +/// square_system.initialize(&mut world); +/// assert_eq!(square_system.run(12, &mut world), 144); +/// } +/// +/// fn square(In(input): In) -> usize { +/// input * input +/// } +/// ``` pub struct In(pub In); pub struct InputMarker; +/// The [`System`] counter part of an ordinary function. +/// +/// You get this by calling [`IntoSystem::system`] on a function that only accepts [`SystemParam`]s. +/// The output of the system becomes the functions return type, while the input becomes the functions +/// [`In`] tagged parameter or `()` if no such paramater exists. pub struct FunctionSystem where Param: SystemParam, @@ -71,6 +122,21 @@ where } impl FunctionSystem { + /// Gives mutable access to the systems config via a callback. This is useful to set up system + /// [`Local`](crate::system::Local)s. + /// + /// # Examples + /// + /// ``` + /// # use bevy_ecs::prelude::*; + /// # let world = &mut World::default(); + /// fn local_is_42(local: Local) { + /// assert_eq!(*local, 42); + /// } + /// let mut system = local_is_42.system().config(|config| config.0 = Some(42)); + /// system.initialize(world); + /// system.run((), world); + /// ``` pub fn config( mut self, f: impl FnOnce(&mut ::Config), @@ -180,6 +246,7 @@ where } } +/// A trait implemented for all functions that can be used as [`System`]s. pub trait SystemParamFunction: Send + Sync + 'static { fn run( &mut self, diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index d136f6f846..ca0144ec7d 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -10,7 +10,7 @@ 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 a [`World`] according to a given [`WorldQuery`] and query filter. pub struct Query<'w, Q: WorldQuery, F: WorldQuery = ()> where F::Fetch: FilterFetch, @@ -25,9 +25,12 @@ impl<'w, Q: WorldQuery, F: WorldQuery> Query<'w, Q, F> where F::Fetch: FilterFetch, { + /// Creates a new query. + /// /// # Safety - /// This will create a Query that could violate memory safety rules. Make sure that this is only - /// called in ways that ensure the Queries have unique mutable access. + /// + /// This will create a query that could violate memory safety rules. Make sure that this is only + /// called in ways that ensure the queries have unique mutable access. #[inline] pub(crate) unsafe fn new( world: &'w World, @@ -43,7 +46,9 @@ where } } - /// Iterates over the query results. This can only be called for read-only queries + /// Returns an [`Iterator`] over the query results. + /// + /// This can only be called for read-only queries, see [`Self::iter_mut`] for write-queries. #[inline] pub fn iter(&self) -> QueryIter<'_, '_, Q, F> where @@ -57,7 +62,7 @@ where } } - /// Iterates over the query results + /// Returns an [`Iterator`] over the query results. #[inline] pub fn iter_mut(&mut self) -> QueryIter<'_, '_, Q, F> { // SAFE: system runs without conflicts with other systems. @@ -68,11 +73,12 @@ where } } - /// Iterates over the query results + /// Returns an [`Iterator`] over the query results. /// /// # Safety - /// This allows aliased mutability. You must make sure this call does not result in multiple - /// mutable references to the same component + /// + /// This function makes it possible to violate Rust's aliasing guarantees. You must make sure + /// this call does not result in multiple mutable references to the same component #[inline] pub unsafe fn iter_unsafe(&self) -> QueryIter<'_, '_, Q, F> { // SEMI-SAFE: system runs without conflicts with other systems. @@ -82,7 +88,9 @@ where } /// Runs `f` on each query result. This is faster than the equivalent iter() method, but cannot - /// be chained like a normal iterator. This can only be called for read-only queries + /// be chained like a normal [`Iterator`]. + /// + /// This can only be called for read-only queries, see [`Self::for_each_mut`] for write-queries. #[inline] pub fn for_each(&self, f: impl FnMut(>::Item)) where @@ -101,7 +109,7 @@ where } /// Runs `f` on each query result. This is faster than the equivalent iter() method, but cannot - /// be chained like a normal iterator. + /// be chained like a normal [`Iterator`]. #[inline] pub fn for_each_mut(&self, f: impl FnMut(>::Item)) { // SAFE: system runs without conflicts with other systems. same-system queries have runtime @@ -117,6 +125,8 @@ where } /// Runs `f` on each query result in parallel using the given task pool. + /// + /// This can only be called for read-only queries, see [`Self::par_for_each_mut`] for write-queries. #[inline] pub fn par_for_each( &self, @@ -162,7 +172,9 @@ where }; } - /// Gets the query result for the given `entity` + /// Gets the query result for the given [`Entity`]. + /// + /// This can only be called for read-only queries, see [`Self::get_mut`] for write-queries. #[inline] pub fn get(&self, entity: Entity) -> Result<::Item, QueryEntityError> where @@ -180,7 +192,7 @@ where } } - /// Gets the query result for the given `entity` + /// Gets the query result for the given [`Entity`]. #[inline] pub fn get_mut( &mut self, @@ -198,11 +210,12 @@ where } } - /// Gets the query result for the given `entity` + /// Gets the query result for the given [`Entity`]. /// /// # Safety - /// This allows aliased mutability. You must make sure this call does not result in multiple - /// mutable references to the same component + /// + /// This function makes it possible to violate Rust's aliasing guarantees. You must make sure + /// this call does not result in multiple mutable references to the same component #[inline] pub unsafe fn get_unchecked( &self, @@ -214,8 +227,8 @@ 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 + /// 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. #[inline] pub fn get_component(&self, entity: Entity) -> Result<&T, QueryComponentError> { @@ -244,8 +257,8 @@ 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 + /// 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. #[inline] pub fn get_component_mut( @@ -256,12 +269,13 @@ 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. + /// 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. /// /// # Safety - /// This allows aliased mutability. You must make sure this call does not result in multiple - /// mutable references to the same component + /// + /// This function makes it possible to violate Rust's aliasing guarantees. You must make sure + /// this call does not result in multiple mutable references to the same component #[inline] pub unsafe fn get_component_unchecked_mut( &self, @@ -292,11 +306,11 @@ where } } - /// Gets the result of a single-result query + /// Gets the result of a single-result query. /// /// If the query has exactly one result, returns the result inside `Ok` - /// otherwise returns either `Err(QuerySingleError::NoEntities(...))` - /// or `Err(QuerySingleError::MultipleEntities(...))`, as appropriate + /// otherwise returns either [`QuerySingleError::NoEntities`] + /// or [`QuerySingleError::MultipleEntities`], as appropriate. /// /// # Examples /// @@ -319,6 +333,8 @@ where /// } /// # let _check_that_its_a_system = player_scoring_system.system(); /// ``` + /// + /// This can only be called for read-only queries, see [`Self::single_mut`] for write-queries. pub fn single(&self) -> Result<>::Item, QuerySingleError> where Q::Fetch: ReadOnlyFetch, @@ -336,7 +352,7 @@ where } } - /// See [`Query::single`] + /// Gets the query result if it is only a single result, otherwise returns a [`QuerySingleError`]. pub fn single_mut(&mut self) -> Result<>::Item, QuerySingleError> { let mut query = self.iter_mut(); let first = query.next(); @@ -352,7 +368,7 @@ where } } -/// An error that occurs when retrieving a specific [Entity]'s component from a [Query] +/// An error that occurs when retrieving a specific [`Entity`]'s component from a [`Query`] #[derive(Error, Debug)] pub enum QueryComponentError { #[error("This query does not have read access to the requested component.")] @@ -365,6 +381,8 @@ pub enum QueryComponentError { NoSuchEntity, } +/// An error that occurs when evaluating a [`Query`] as a single expected resulted via [`Query::single`] +/// or [`Query::single_mut`]. #[derive(Debug, Error)] pub enum QuerySingleError { #[error("No entities fit the query {0}")] diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 824cbc5e84..a13967bfa8 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -8,10 +8,12 @@ use crate::{ }; use std::borrow::Cow; +/// A [`System`] identifier. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub struct SystemId(pub usize); impl SystemId { + /// Creates a new random `SystemId`. #[allow(clippy::new_without_default)] pub fn new() -> Self { SystemId(rand::random::()) @@ -29,29 +31,46 @@ impl SystemId { /// It's possible to specify explicit execution order between specific systems, /// see [SystemDescriptor](crate::schedule::SystemDescriptor). pub trait System: Send + Sync + 'static { + /// The system's input. See [`In`](crate::system::In) for [`FunctionSystem`](crate::system::FunctionSystem)s. type In; + /// The system's output. type Out; + /// Returns the system's name. fn name(&self) -> Cow<'static, str>; + /// Returns the system's [`SystemId`]. fn id(&self) -> SystemId; + /// Register a new archetype for this system. fn new_archetype(&mut self, archetype: &Archetype); + /// Returns the system's component [`Access`]. fn component_access(&self) -> &Access; + /// Returns the system's archetype component [`Access`]. fn archetype_component_access(&self) -> &Access; + /// Returns true if the system is [`Send`]. fn is_send(&self) -> bool; + /// Runs the system with the given input in the world. Unlike [`System::run`], this function + /// takes a shared reference to [`World`] and may therefore break Rust's aliasing rules, making + /// it unsafe to call. + /// /// # Safety - /// This might access World and Resources in an unsafe manner. This should only be called in one - /// of the following contexts: 1. This system is the only system running on the given World - /// across all threads 2. This system only runs in parallel with other systems that do not - /// conflict with the `archetype_component_access()` + /// + /// This might access world and resources in an unsafe manner. This should only be called in one + /// of the following contexts: + /// 1. This system is the only system running on the given world across all threads. + /// 2. This system only runs in parallel with other systems that do not conflict with the + /// [`System::archetype_component_access()`]. unsafe fn run_unsafe(&mut self, input: Self::In, world: &World) -> Self::Out; + /// Runs the system with the given input in the world. fn run(&mut self, input: Self::In, world: &mut World) -> Self::Out { // SAFE: world and resources are exclusively borrowed unsafe { self.run_unsafe(input, world) } } fn apply_buffers(&mut self, world: &mut World); + /// Initialize the system. fn initialize(&mut self, _world: &mut World); fn check_change_tick(&mut self, change_tick: u32); } +/// A convenience type alias for a boxed [`System`] trait object. pub type BoxedSystem = Box>; pub(crate) fn check_system_change_tick( diff --git a/crates/bevy_ecs/src/system/system_chaining.rs b/crates/bevy_ecs/src/system/system_chaining.rs index 951d07ff13..95f5974098 100644 --- a/crates/bevy_ecs/src/system/system_chaining.rs +++ b/crates/bevy_ecs/src/system/system_chaining.rs @@ -7,6 +7,43 @@ use crate::{ }; use std::borrow::Cow; +/// A [`System`] that chains two systems together, creating a new system that routes the output of +/// the first system into the input of the second system, yielding the output of the second system. +/// +/// Given two systems A and B, A may be chained with B as `A.chain(B)` if the output type of A is +/// equal to the input type of B. +/// +/// Note that for [`FunctionSystem`](crate::system::FunctionSystem)s the output is the return value +/// of the function and the input is the first [`SystemParam`](crate::system::SystemParam) if it is +/// tagged with [`In`](crate::system::In) or `()` if the function has no designated input parameter. +/// +/// # Examples +/// +/// ``` +/// use std::num::ParseIntError; +/// +/// use bevy_ecs::prelude::*; +/// +/// fn main() { +/// let mut world = World::default(); +/// world.insert_resource(Message("42".to_string())); +/// +/// // chain the `parse_message_system`'s output into the `filter_system`s input +/// let mut chained_system = parse_message_system.system().chain(filter_system.system()); +/// chained_system.initialize(&mut world); +/// assert_eq!(chained_system.run((), &mut world), Some(42)); +/// } +/// +/// struct Message(String); +/// +/// fn parse_message_system(message: Res) -> Result { +/// message.0.parse::() +/// } +/// +/// fn filter_system(In(result): In>) -> Option { +/// result.ok().filter(|&n| n < 100) +/// } +/// ``` pub struct ChainSystem { system_a: SystemA, system_b: SystemB, @@ -75,10 +112,18 @@ impl> System for ChainSystem } } +/// An extension trait providing the [`IntoChainSystem::chain`] method for convenient [`System`] +/// chaining. +/// +/// This trait is blanket implemented for all system pairs that fulfill the chaining requirement. +/// +/// See [`ChainSystem`]. pub trait IntoChainSystem: System + Sized where SystemB: System, { + /// Chain this system `A` with another system `B` creating a new system that feeds system A's + /// output into system `B`, returning the output of system `B`. fn chain(self, system: SystemB) -> ChainSystem; } diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 99c9e26d8c..21e3e39e89 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -14,10 +14,11 @@ use std::{ ops::{Deref, DerefMut}, }; -/// A parameter that can be used in a system function +/// A parameter that can be used in a [`System`](super::System). /// /// # Derive -/// This trait can be derived. +/// +/// This trait can be derived with the [`derive@super::SystemParam`] macro. /// /// ``` /// # use bevy_ecs::prelude::*; @@ -36,9 +37,12 @@ pub trait SystemParam: Sized { type Fetch: for<'a> SystemParamFetch<'a>; } +/// The state of a [`SystemParam`]. +/// /// # Safety +/// /// It is the implementor's responsibility to ensure `system_state` is populated with the _exact_ -/// [World] access used by the SystemParamState (and associated FetchSystemParam). +/// [`World`] access used by the `SystemParamState` (and associated [`SystemParamFetch`]). /// Additionally, it is the implementor's responsibility to ensure there is no /// conflicting access across all SystemParams. pub unsafe trait SystemParamState: Send + Sync + 'static { @@ -54,8 +58,9 @@ pub unsafe trait SystemParamState: Send + Sync + 'static { pub trait SystemParamFetch<'a>: SystemParamState { type Item; /// # Safety + /// /// This call might access any of the input parameters in an unsafe way. Make sure the data - /// access is safe in the context of the system scheduler + /// access is safe in the context of the system scheduler. unsafe fn get_param( state: &'a mut Self, system_state: &'a SystemState, @@ -153,11 +158,13 @@ pub struct QuerySetState(T); impl_query_set!(); -/// Shared borrow of a Resource +/// Shared borrow of a resource. /// -/// When used as a system parameter, panics if resource does not exist. +/// # Panics /// -/// Use `Option>` if the resource might not always exist. +/// Panics when used as a [`SystemParameter`](SystemParam) if the resource does not exist. +/// +/// Use `Option>` instead if the resource might not always exist. pub struct Res<'w, T> { value: &'w T, ticks: &'w ComponentTicks, @@ -188,6 +195,7 @@ impl<'w, T: Component> Deref for Res<'w, T> { } } +/// The [`SystemParamState`] of [`Res`]. pub struct ResState { component_id: ComponentId, marker: PhantomData, @@ -256,6 +264,7 @@ impl<'a, T: Component> SystemParamFetch<'a> for ResState { } } +/// The [`SystemParamState`] of `Option>`. pub struct OptionResState(ResState); impl<'a, T: Component> SystemParam for Option> { @@ -293,11 +302,13 @@ impl<'a, T: Component> SystemParamFetch<'a> for OptionResState { } } -/// Unique borrow of a Resource +/// Unique borrow of a resource. /// -/// When used as a system parameter, panics if resource does not exist. +/// # Panics /// -/// Use `Option>` if the resource might not always exist. +/// Panics when used as a [`SystemParameter`](SystemParam) if the resource does not exist. +/// +/// Use `Option>` instead if the resource might not always exist. pub struct ResMut<'w, T> { value: &'w mut T, ticks: &'w mut ComponentTicks, @@ -335,6 +346,7 @@ impl<'w, T: Component> DerefMut for ResMut<'w, T> { } } +/// The [`SystemParamState`] of [`ResMut`]. pub struct ResMutState { component_id: ComponentId, marker: PhantomData, @@ -406,6 +418,7 @@ impl<'a, T: Component> SystemParamFetch<'a> for ResMutState { } } +/// The [`SystemParamState`] of `Option>`. pub struct OptionResMutState(ResMutState); impl<'a, T: Component> SystemParam for Option> { @@ -476,6 +489,32 @@ impl<'a> SystemParamFetch<'a> for CommandQueue { } } +/// A system local [`SystemParam`]. +/// +/// A local may only be accessed by the system itself and is therefore not visible to other systems. +/// If two or more systems specify the same local type each will have their own unique local. +/// +/// # Examples +/// +/// ``` +/// # use bevy_ecs::prelude::*; +/// # let world = &mut World::default(); +/// fn write_to_local(mut local: Local) { +/// *local = 42; +/// } +/// fn read_from_local(local: Local) -> usize { +/// *local +/// } +/// let mut write_system = write_to_local.system(); +/// let mut read_system = read_from_local.system(); +/// write_system.initialize(world); +/// read_system.initialize(world); +/// +/// assert_eq!(read_system.run((), world), 0); +/// write_system.run((), world); +/// // Note how the read local is still 0 due to the locals not being shared. +/// assert_eq!(read_system.run((), world), 0); +/// ``` pub struct Local<'a, T: Component>(&'a mut T); impl<'a, T: Component> Deref for Local<'a, T> { @@ -494,6 +533,7 @@ impl<'a, T: Component> DerefMut for Local<'a, T> { } } +/// The [`SystemParamState`] of [`Local`]. pub struct LocalState(T); impl<'a, T: Component + FromWorld> SystemParam for Local<'a, T> { @@ -527,6 +567,17 @@ impl<'a, T: Component + FromWorld> SystemParamFetch<'a> for LocalState { } } +/// A [`SystemParam`] that grants access to the entities that had their `T` [`Component`] removed. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ```ignore +/// fn react_on_removal(removed: RemovedComponents) { +/// removed.iter().for_each(|removed_entity| println!("{}", removed_entity)); +/// } +/// ``` pub struct RemovedComponents<'a, T> { world: &'a World, component_id: ComponentId, @@ -534,11 +585,13 @@ pub struct RemovedComponents<'a, T> { } impl<'a, T> RemovedComponents<'a, T> { + /// Returns an iterator over the entities that had their `T` [`Component`] removed. pub fn iter(&self) -> std::iter::Cloned> { self.world.removed_with_id(self.component_id) } } +/// The [`SystemParamState`] of [`RemovedComponents`]. pub struct RemovedComponentsState { component_id: ComponentId, marker: PhantomData, @@ -581,7 +634,16 @@ impl<'a, T: Component> SystemParamFetch<'a> for RemovedComponentsState { } } -/// Shared borrow of a NonSend resource +/// Shared borrow of a non-[`Send`] resource. +/// +/// Only `Send` resources may be accessed with the [`Res`] [`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. +/// +/// # Panics +/// +/// Panics when used as a `SystemParameter` if the resource does not exist. pub struct NonSend<'w, T> { pub(crate) value: &'w T, ticks: ComponentTicks, @@ -612,6 +674,7 @@ impl<'w, T: 'static> Deref for NonSend<'w, T> { } } +/// The [`SystemParamState`] of [`NonSend`]. pub struct NonSendState { component_id: ComponentId, marker: PhantomData T>, @@ -682,7 +745,16 @@ impl<'a, T: 'static> SystemParamFetch<'a> for NonSendState { } } -/// Unique borrow of a NonSend resource +/// Unique borrow of a non-[`Send`] resource. +/// +/// Only `Send` resources may be accessed with the [`ResMut`] [`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. +/// +/// # Panics +/// +/// Panics when used as a `SystemParameter` if the resource does not exist. pub struct NonSendMut<'a, T: 'static> { pub(crate) value: &'a mut T, ticks: &'a mut ComponentTicks, @@ -728,6 +800,7 @@ impl<'a, T: 'static + core::fmt::Debug> core::fmt::Debug for NonSendMut<'a, T> { } } +/// The [`SystemParamState`] of [`NonSendMut`]. pub struct NonSendMutState { component_id: ComponentId, marker: PhantomData T>, @@ -808,6 +881,7 @@ impl<'a> SystemParam for &'a Archetypes { type Fetch = ArchetypesState; } +/// The [`SystemParamState`] of [`Archetypes`]. pub struct ArchetypesState; // SAFE: no component value access @@ -839,6 +913,7 @@ impl<'a> SystemParam for &'a Components { type Fetch = ComponentsState; } +/// The [`SystemParamState`] of [`Components`]. pub struct ComponentsState; // SAFE: no component value access @@ -870,6 +945,7 @@ impl<'a> SystemParam for &'a Entities { type Fetch = EntitiesState; } +/// The [`SystemParamState`] of [`Entities`]. pub struct EntitiesState; // SAFE: no component value access @@ -901,6 +977,7 @@ impl<'a> SystemParam for &'a Bundles { type Fetch = BundlesState; } +/// The [`SystemParamState`] of [`Bundles`]. pub struct BundlesState; // SAFE: no component value access @@ -938,6 +1015,7 @@ impl SystemParam for SystemChangeTick { type Fetch = SystemChangeTickState; } +/// The [`SystemParamState`] of [`SystemChangeTickState`]. pub struct SystemChangeTickState {} unsafe impl SystemParamState for SystemChangeTickState {