Skip to content

Commit

Permalink
Improve bevy_ecs::system module docs (#1932)
Browse files Browse the repository at this point in the history
This includes a lot of single line comments where either saying more wasn't helpful or due to me not knowing enough about things yet to be able to go more indepth. Proofreading is very much welcome.
  • Loading branch information
Veykril committed Apr 15, 2021
1 parent 9657f58 commit 0a6fee5
Show file tree
Hide file tree
Showing 6 changed files with 297 additions and 65 deletions.
47 changes: 26 additions & 21 deletions crates/bevy_ecs/src/system/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,50 +7,56 @@ 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<Self>, world: &mut World);
}

/// A queue of [`Command`]s.
#[derive(Default)]
pub struct CommandQueue {
commands: Vec<Box<dyn Command>>,
}

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(..) {
command.write(world);
}
}

/// Push a boxed [`Command`] onto the queue.
#[inline]
pub fn push_boxed(&mut self, command: Box<dyn Command>) {
self.commands.push(command);
}

/// Push a [`Command`] onto the queue.
#[inline]
pub fn push<T: Command>(&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,
entities: world.entities(),
}
}

/// 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
///
Expand Down Expand Up @@ -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`].
///
Expand Down Expand Up @@ -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
///
Expand Down Expand Up @@ -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<T: Component>(&mut self, resource: T) {
self.queue.push(InsertResource { resource })
}

/// Queue a resource removal.
pub fn remove_resource<T: Component>(&mut self) {
self.queue.push(RemoveResource::<T> {
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<C: Command>(&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,
Expand All @@ -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
///
Expand All @@ -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::*;
Expand Down Expand Up @@ -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<T>(&mut self) -> &mut Self
where
T: Bundle,
Expand All @@ -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<T>(&mut self) -> &mut Self
where
T: Component,
Expand All @@ -273,6 +277,7 @@ impl<'a, 'b> EntityCommands<'a, 'b> {
})
}

/// Returns the underlying `[Commands]`.
pub fn commands(&mut self) -> &mut Commands<'a> {
self.commands
}
Expand Down Expand Up @@ -323,7 +328,7 @@ impl Command for Despawn {
}
}

pub struct InsertBundle<T> {
pub(crate) struct InsertBundle<T> {
entity: Entity,
bundle: T,
}
Expand Down Expand Up @@ -388,7 +393,7 @@ where
}
}

pub struct InsertResource<T: Component> {
pub(crate) struct InsertResource<T: Component> {
resource: T,
}

Expand All @@ -398,7 +403,7 @@ impl<T: Component> Command for InsertResource<T> {
}
}

pub struct RemoveResource<T: Component> {
pub(crate) struct RemoveResource<T: Component> {
phantom: PhantomData<T>,
}

Expand Down
67 changes: 67 additions & 0 deletions crates/bevy_ecs/src/system/into_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand All @@ -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<usize>) {}
///
/// let system = my_system_function.system();
/// ```
pub trait IntoSystem<Params, SystemType: System> {
/// Turns this value into its corresponding [`System`].
fn system(self) -> SystemType;
}

Expand All @@ -55,9 +75,40 @@ impl<Sys: System> 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>) -> usize {
/// input * input
/// }
/// ```
pub struct In<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<In, Out, Param, Marker, F>
where
Param: SystemParam,
Expand All @@ -71,6 +122,21 @@ where
}

impl<In, Out, Param: SystemParam, Marker, F> FunctionSystem<In, Out, Param, Marker, F> {
/// 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<usize>) {
/// 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 <Param::Fetch as SystemParamState>::Config),
Expand Down Expand Up @@ -180,6 +246,7 @@ where
}
}

/// A trait implemented for all functions that can be used as [`System`]s.
pub trait SystemParamFunction<In, Out, Param: SystemParam, Marker>: Send + Sync + 'static {
fn run(
&mut self,
Expand Down
Loading

0 comments on commit 0a6fee5

Please sign in to comment.