Path: blob/main/crates/bevy_ecs/src/system/commands/mod.rs
9408 views
pub mod command;1pub mod entity_command;23#[cfg(feature = "std")]4mod parallel_scope;56use bevy_ptr::move_as_ptr;7pub use command::Command;8pub use entity_command::EntityCommand;910#[cfg(feature = "std")]11pub use parallel_scope::*;1213use alloc::boxed::Box;14use core::marker::PhantomData;1516use crate::{17self as bevy_ecs,18bundle::{Bundle, InsertMode, NoBundleEffect},19change_detection::{MaybeLocation, Mut},20component::{Component, ComponentId, Mutable},21entity::{22Entities, Entity, EntityAllocator, EntityClonerBuilder, EntityNotSpawnedError,23InvalidEntityError, OptIn, OptOut,24},25error::{warn, BevyError, CommandWithEntity, ErrorContext, HandleError},26event::{EntityEvent, Event},27message::Message,28observer::{IntoEntityObserver, IntoObserver},29resource::Resource,30schedule::ScheduleLabel,31system::{32Deferred, IntoSystem, RegisteredSystem, SystemId, SystemInput, SystemParamValidationError,33},34world::{35command_queue::RawCommandQueue, unsafe_world_cell::UnsafeWorldCell, CommandQueue,36EntityWorldMut, FromWorld, World,37},38};3940/// A [`Command`] queue to perform structural changes to the [`World`].41///42/// Since each command requires exclusive access to the `World`,43/// all queued commands are automatically applied in sequence44/// when the `ApplyDeferred` system runs (see [`ApplyDeferred`] documentation for more details).45///46/// Each command can be used to modify the [`World`] in arbitrary ways:47/// * spawning or despawning entities48/// * inserting components on new or existing entities49/// * inserting resources50/// * etc.51///52/// For a version of [`Commands`] that works in parallel contexts (such as53/// within [`Query::par_iter`](crate::system::Query::par_iter)) see54/// [`ParallelCommands`]55///56/// # Usage57///58/// Add `mut commands: Commands` as a function argument to your system to get a59/// copy of this struct that will be applied the next time a copy of [`ApplyDeferred`] runs.60/// Commands are almost always used as a [`SystemParam`](crate::system::SystemParam).61///62/// ```63/// # use bevy_ecs::prelude::*;64/// fn my_system(mut commands: Commands) {65/// // ...66/// }67/// # bevy_ecs::system::assert_is_system(my_system);68/// ```69///70/// # Implementing71///72/// Each built-in command is implemented as a separate method, e.g. [`Commands::spawn`].73/// In addition to the pre-defined command methods, you can add commands with any arbitrary74/// behavior using [`Commands::queue`], which accepts any type implementing [`Command`].75///76/// Since closures and other functions implement this trait automatically, this allows one-shot,77/// anonymous custom commands.78///79/// ```80/// # use bevy_ecs::prelude::*;81/// # fn foo(mut commands: Commands) {82/// // NOTE: type inference fails here, so annotations are required on the closure.83/// commands.queue(|w: &mut World| {84/// // Mutate the world however you want...85/// });86/// # }87/// ```88///89/// # Error handling90///91/// A [`Command`] can return a [`Result`](crate::error::Result),92/// which will be passed to an [error handler](crate::error) if the `Result` is an error.93///94/// The default error handler panics. It can be configured via95/// the [`DefaultErrorHandler`](crate::error::DefaultErrorHandler) resource.96///97/// Alternatively, you can customize the error handler for a specific command98/// by calling [`Commands::queue_handled`].99///100/// The [`error`](crate::error) module provides some simple error handlers for convenience.101///102/// [`ApplyDeferred`]: crate::schedule::ApplyDeferred103pub struct Commands<'w, 's> {104queue: InternalQueue<'s>,105entities: &'w Entities,106allocator: &'w EntityAllocator,107}108109// SAFETY: All commands [`Command`] implement [`Send`]110unsafe impl Send for Commands<'_, '_> {}111112// SAFETY: `Commands` never gives access to the inner commands.113unsafe impl Sync for Commands<'_, '_> {}114115const _: () = {116type __StructFieldsAlias<'w, 's> = (117Deferred<'s, CommandQueue>,118&'w EntityAllocator,119&'w Entities,120);121#[doc(hidden)]122pub struct FetchState {123state: <__StructFieldsAlias<'static, 'static> as bevy_ecs::system::SystemParam>::State,124}125// SAFETY: Only reads Entities126unsafe impl bevy_ecs::system::SystemParam for Commands<'_, '_> {127type State = FetchState;128129type Item<'w, 's> = Commands<'w, 's>;130131#[track_caller]132fn init_state(world: &mut World) -> Self::State {133FetchState {134state: <__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::init_state(135world,136),137}138}139140fn init_access(141state: &Self::State,142system_meta: &mut bevy_ecs::system::SystemMeta,143component_access_set: &mut bevy_ecs::query::FilteredAccessSet,144world: &mut World,145) {146<__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::init_access(147&state.state,148system_meta,149component_access_set,150world,151);152}153154fn apply(155state: &mut Self::State,156system_meta: &bevy_ecs::system::SystemMeta,157world: &mut World,158) {159<__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::apply(160&mut state.state,161system_meta,162world,163);164}165166fn queue(167state: &mut Self::State,168system_meta: &bevy_ecs::system::SystemMeta,169world: bevy_ecs::world::DeferredWorld,170) {171<__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::queue(172&mut state.state,173system_meta,174world,175);176}177178#[inline]179unsafe fn validate_param(180state: &mut Self::State,181system_meta: &bevy_ecs::system::SystemMeta,182world: UnsafeWorldCell,183) -> Result<(), SystemParamValidationError> {184// SAFETY: Upheld by caller185unsafe {186<__StructFieldsAlias as bevy_ecs::system::SystemParam>::validate_param(187&mut state.state,188system_meta,189world,190)191}192}193194#[inline]195#[track_caller]196unsafe fn get_param<'w, 's>(197state: &'s mut Self::State,198system_meta: &bevy_ecs::system::SystemMeta,199world: UnsafeWorldCell<'w>,200change_tick: bevy_ecs::change_detection::Tick,201) -> Self::Item<'w, 's> {202// SAFETY: Upheld by caller203let params = unsafe {204<__StructFieldsAlias as bevy_ecs::system::SystemParam>::get_param(205&mut state.state,206system_meta,207world,208change_tick,209)210};211Commands {212queue: InternalQueue::CommandQueue(params.0),213allocator: params.1,214entities: params.2,215}216}217}218// SAFETY: Only reads Entities219unsafe impl<'w, 's> bevy_ecs::system::ReadOnlySystemParam for Commands<'w, 's>220where221Deferred<'s, CommandQueue>: bevy_ecs::system::ReadOnlySystemParam,222&'w Entities: bevy_ecs::system::ReadOnlySystemParam,223{224}225};226227enum InternalQueue<'s> {228CommandQueue(Deferred<'s, CommandQueue>),229RawCommandQueue(RawCommandQueue),230}231232impl<'w, 's> Commands<'w, 's> {233/// Returns a new `Commands` instance from a [`CommandQueue`] and a [`World`].234pub fn new(queue: &'s mut CommandQueue, world: &'w World) -> Self {235Self::new_from_entities(queue, &world.entity_allocator, &world.entities)236}237238/// Returns a new `Commands` instance from a [`CommandQueue`] and an [`Entities`] reference.239pub fn new_from_entities(240queue: &'s mut CommandQueue,241allocator: &'w EntityAllocator,242entities: &'w Entities,243) -> Self {244Self {245queue: InternalQueue::CommandQueue(Deferred(queue)),246allocator,247entities,248}249}250251/// Returns a new `Commands` instance from a [`RawCommandQueue`] and an [`Entities`] reference.252///253/// This is used when constructing [`Commands`] from a [`DeferredWorld`](crate::world::DeferredWorld).254///255/// # Safety256///257/// * Caller ensures that `queue` must outlive `'w`258pub(crate) unsafe fn new_raw_from_entities(259queue: RawCommandQueue,260allocator: &'w EntityAllocator,261entities: &'w Entities,262) -> Self {263Self {264queue: InternalQueue::RawCommandQueue(queue),265allocator,266entities,267}268}269270/// Returns a [`Commands`] with a smaller lifetime.271///272/// This is useful if you have `&mut Commands` but need `Commands`.273///274/// # Example275///276/// ```277/// # use bevy_ecs::prelude::*;278/// fn my_system(mut commands: Commands) {279/// // We do our initialization in a separate function,280/// // which expects an owned `Commands`.281/// do_initialization(commands.reborrow());282///283/// // Since we only reborrowed the commands instead of moving them, we can still use them.284/// commands.spawn_empty();285/// }286/// #287/// # fn do_initialization(_: Commands) {}288/// ```289pub fn reborrow(&mut self) -> Commands<'w, '_> {290Commands {291queue: match &mut self.queue {292InternalQueue::CommandQueue(queue) => InternalQueue::CommandQueue(queue.reborrow()),293InternalQueue::RawCommandQueue(queue) => {294InternalQueue::RawCommandQueue(queue.clone())295}296},297allocator: self.allocator,298entities: self.entities,299}300}301302/// Take all commands from `other` and append them to `self`, leaving `other` empty.303pub fn append(&mut self, other: &mut CommandQueue) {304match &mut self.queue {305InternalQueue::CommandQueue(queue) => queue.bytes.append(&mut other.bytes),306InternalQueue::RawCommandQueue(queue) => {307// SAFETY: Pointers in `RawCommandQueue` are never null308unsafe { queue.bytes.as_mut() }.append(&mut other.bytes);309}310}311}312313/// Spawns a new empty [`Entity`] and returns its corresponding [`EntityCommands`].314///315/// # Example316///317/// ```318/// # use bevy_ecs::prelude::*;319/// #[derive(Component)]320/// struct Label(&'static str);321/// #[derive(Component)]322/// struct Strength(u32);323/// #[derive(Component)]324/// struct Agility(u32);325///326/// fn example_system(mut commands: Commands) {327/// // Create a new empty entity.328/// commands.spawn_empty();329///330/// // Create another empty entity.331/// commands.spawn_empty()332/// // Add a new component bundle to the entity.333/// .insert((Strength(1), Agility(2)))334/// // Add a single component to the entity.335/// .insert(Label("hello world"));336/// }337/// # bevy_ecs::system::assert_is_system(example_system);338/// ```339///340/// # See also341///342/// - [`spawn`](Self::spawn) to spawn an entity with components.343/// - [`spawn_batch`](Self::spawn_batch) to spawn many entities344/// with the same combination of components.345#[track_caller]346pub fn spawn_empty(&mut self) -> EntityCommands<'_> {347let entity = self.allocator.alloc();348let caller = MaybeLocation::caller();349self.queue(move |world: &mut World| {350world.spawn_empty_at_with_caller(entity, caller).map(|_| ())351});352self.entity(entity)353}354355/// Spawns a new [`Entity`] with the given components356/// and returns the entity's corresponding [`EntityCommands`].357///358/// To spawn many entities with the same combination of components,359/// [`spawn_batch`](Self::spawn_batch) can be used for better performance.360///361/// # Example362///363/// ```364/// # use bevy_ecs::prelude::*;365/// #[derive(Component)]366/// struct ComponentA(u32);367/// #[derive(Component)]368/// struct ComponentB(u32);369///370/// #[derive(Bundle)]371/// struct ExampleBundle {372/// a: ComponentA,373/// b: ComponentB,374/// }375///376/// fn example_system(mut commands: Commands) {377/// // Create a new entity with a single component.378/// commands.spawn(ComponentA(1));379///380/// // Create a new entity with two components using a "tuple bundle".381/// commands.spawn((ComponentA(2), ComponentB(1)));382///383/// // Create a new entity with a component bundle.384/// commands.spawn(ExampleBundle {385/// a: ComponentA(3),386/// b: ComponentB(2),387/// });388/// }389/// # bevy_ecs::system::assert_is_system(example_system);390/// ```391///392/// # See also393///394/// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without any components.395/// - [`spawn_batch`](Self::spawn_batch) to spawn many entities396/// with the same combination of components.397#[track_caller]398pub fn spawn<T: Bundle>(&mut self, bundle: T) -> EntityCommands<'_> {399let entity = self.allocator.alloc();400let caller = MaybeLocation::caller();401self.queue(move |world: &mut World| {402move_as_ptr!(bundle);403world404.spawn_at_with_caller(entity, bundle, caller)405.map(|_| ())406});407self.entity(entity)408}409410/// Returns the [`EntityCommands`] for the given [`Entity`].411///412/// This method does not guarantee that commands queued by the returned `EntityCommands`413/// will be successful, since the entity could be despawned before they are executed.414///415/// # Example416///417/// ```418/// # use bevy_ecs::prelude::*;419/// #[derive(Resource)]420/// struct PlayerEntity {421/// entity: Entity422/// }423///424/// #[derive(Component)]425/// struct Label(&'static str);426///427/// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) {428/// // Get the entity and add a component.429/// commands.entity(player.entity).insert(Label("hello world"));430/// }431/// # bevy_ecs::system::assert_is_system(example_system);432/// ```433///434/// # See also435///436/// - [`get_entity`](Self::get_entity) for the fallible version.437#[inline]438#[track_caller]439pub fn entity(&mut self, entity: Entity) -> EntityCommands<'_> {440EntityCommands {441entity,442commands: self.reborrow(),443}444}445446/// Returns the [`EntityCommands`] for the requested [`Entity`] if it is valid.447/// This method does not guarantee that commands queued by the returned `EntityCommands`448/// will be successful, since the entity could be despawned before they are executed.449/// This also does not error when the entity has not been spawned.450/// For that behavior, see [`get_spawned_entity`](Self::get_spawned_entity),451/// which should be preferred for accessing entities you expect to already be spawned, like those found from a query.452/// For details on entity spawning vs validity, see [`entity`](crate::entity) module docs.453///454/// # Errors455///456/// Returns [`InvalidEntityError`] if the requested entity does not exist.457///458/// # Example459///460/// ```461/// # use bevy_ecs::prelude::*;462/// #[derive(Resource)]463/// struct PlayerEntity {464/// entity: Entity465/// }466///467/// #[derive(Component)]468/// struct Label(&'static str);469///470/// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) -> Result {471/// // Get the entity if it still exists and store the `EntityCommands`.472/// // If it doesn't exist, the `?` operator will propagate the returned error473/// // to the system, and the system will pass it to an error handler.474/// let mut entity_commands = commands.get_entity(player.entity)?;475///476/// // Add a component to the entity.477/// entity_commands.insert(Label("hello world"));478///479/// // Return from the system successfully.480/// Ok(())481/// }482/// # bevy_ecs::system::assert_is_system::<(), (), _>(example_system);483/// ```484///485/// # See also486///487/// - [`entity`](Self::entity) for the infallible version.488#[inline]489#[track_caller]490pub fn get_entity(&mut self, entity: Entity) -> Result<EntityCommands<'_>, InvalidEntityError> {491let _location = self.entities.get(entity)?;492Ok(EntityCommands {493entity,494commands: self.reborrow(),495})496}497498/// Returns the [`EntityCommands`] for the requested [`Entity`] if it spawned in the world *now*.499/// Note that for entities that have not been spawned *yet*, like ones from [`spawn`](Self::spawn), this will error.500/// If that is not desired, try [`get_entity`](Self::get_entity).501/// This should be used over [`get_entity`](Self::get_entity) when you expect the entity to already be spawned in the world.502/// If the entity is valid but not yet spawned, this will error that information, where [`get_entity`](Self::get_entity) would succeed, leading to potentially surprising results.503/// For details on entity spawning vs validity, see [`entity`](crate::entity) module docs.504///505/// This method does not guarantee that commands queued by the returned `EntityCommands`506/// will be successful, since the entity could be despawned before they are executed.507///508/// # Errors509///510/// Returns [`EntityNotSpawnedError`] if the requested entity does not exist.511///512/// # Example513///514/// ```515/// # use bevy_ecs::prelude::*;516/// #[derive(Resource)]517/// struct PlayerEntity {518/// entity: Entity519/// }520///521/// #[derive(Component)]522/// struct Label(&'static str);523///524/// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) -> Result {525/// // Get the entity if it still exists and store the `EntityCommands`.526/// // If it doesn't exist, the `?` operator will propagate the returned error527/// // to the system, and the system will pass it to an error handler.528/// let mut entity_commands = commands.get_spawned_entity(player.entity)?;529///530/// // Add a component to the entity.531/// entity_commands.insert(Label("hello world"));532///533/// // Return from the system successfully.534/// Ok(())535/// }536/// # bevy_ecs::system::assert_is_system::<(), (), _>(example_system);537/// ```538///539/// # See also540///541/// - [`entity`](Self::entity) for the infallible version.542#[inline]543#[track_caller]544pub fn get_spawned_entity(545&mut self,546entity: Entity,547) -> Result<EntityCommands<'_>, EntityNotSpawnedError> {548let _location = self.entities.get_spawned(entity)?;549Ok(EntityCommands {550entity,551commands: self.reborrow(),552})553}554555/// Spawns multiple entities with the same combination of components,556/// based on a batch of [`Bundles`](Bundle).557///558/// A batch can be any type that implements [`IntoIterator`] and contains bundles,559/// such as a [`Vec<Bundle>`](alloc::vec::Vec) or an array `[Bundle; N]`.560///561/// This method is equivalent to iterating the batch562/// and calling [`spawn`](Self::spawn) for each bundle,563/// but is faster by pre-allocating memory and having exclusive [`World`] access.564///565/// # Example566///567/// ```568/// use bevy_ecs::prelude::*;569///570/// #[derive(Component)]571/// struct Score(u32);572///573/// fn example_system(mut commands: Commands) {574/// commands.spawn_batch([575/// (Name::new("Alice"), Score(0)),576/// (Name::new("Bob"), Score(0)),577/// ]);578/// }579/// # bevy_ecs::system::assert_is_system(example_system);580/// ```581///582/// # See also583///584/// - [`spawn`](Self::spawn) to spawn an entity with components.585/// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without components.586#[track_caller]587pub fn spawn_batch<I>(&mut self, batch: I)588where589I: IntoIterator + Send + Sync + 'static,590I::Item: Bundle<Effect: NoBundleEffect>,591{592self.queue(command::spawn_batch(batch));593}594595/// Pushes a generic [`Command`] to the command queue.596///597/// If the [`Command`] returns a [`Result`],598/// it will be handled using the [default error handler](crate::error::DefaultErrorHandler).599///600/// To use a custom error handler, see [`Commands::queue_handled`].601///602/// The command can be:603/// - A custom struct that implements [`Command`].604/// - A closure or function that matches one of the following signatures:605/// - [`(&mut World)`](World)606/// - A built-in command from the [`command`] module.607///608/// # Example609///610/// ```611/// # use bevy_ecs::prelude::*;612/// #[derive(Resource, Default)]613/// struct Counter(u64);614///615/// struct AddToCounter(String);616///617/// impl Command<Result> for AddToCounter {618/// fn apply(self, world: &mut World) -> Result {619/// let mut counter = world.get_resource_or_insert_with(Counter::default);620/// let amount: u64 = self.0.parse()?;621/// counter.0 += amount;622/// Ok(())623/// }624/// }625///626/// fn add_three_to_counter_system(mut commands: Commands) {627/// commands.queue(AddToCounter("3".to_string()));628/// }629///630/// fn add_twenty_five_to_counter_system(mut commands: Commands) {631/// commands.queue(|world: &mut World| {632/// let mut counter = world.get_resource_or_insert_with(Counter::default);633/// counter.0 += 25;634/// });635/// }636/// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);637/// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);638/// ```639pub fn queue<C: Command<T> + HandleError<T>, T>(&mut self, command: C) {640self.queue_internal(command.handle_error());641}642643/// Pushes a generic [`Command`] to the command queue.644///645/// If the [`Command`] returns a [`Result`],646/// the given `error_handler` will be used to handle error cases.647///648/// To implicitly use the default error handler, see [`Commands::queue`].649///650/// The command can be:651/// - A custom struct that implements [`Command`].652/// - A closure or function that matches one of the following signatures:653/// - [`(&mut World)`](World)654/// - [`(&mut World)`](World) `->` [`Result`]655/// - A built-in command from the [`command`] module.656///657/// # Example658///659/// ```660/// # use bevy_ecs::prelude::*;661/// use bevy_ecs::error::warn;662///663/// #[derive(Resource, Default)]664/// struct Counter(u64);665///666/// struct AddToCounter(String);667///668/// impl Command<Result> for AddToCounter {669/// fn apply(self, world: &mut World) -> Result {670/// let mut counter = world.get_resource_or_insert_with(Counter::default);671/// let amount: u64 = self.0.parse()?;672/// counter.0 += amount;673/// Ok(())674/// }675/// }676///677/// fn add_three_to_counter_system(mut commands: Commands) {678/// commands.queue_handled(AddToCounter("3".to_string()), warn);679/// }680///681/// fn add_twenty_five_to_counter_system(mut commands: Commands) {682/// commands.queue(|world: &mut World| {683/// let mut counter = world.get_resource_or_insert_with(Counter::default);684/// counter.0 += 25;685/// });686/// }687/// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);688/// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);689/// ```690pub fn queue_handled<C: Command<T> + HandleError<T>, T>(691&mut self,692command: C,693error_handler: fn(BevyError, ErrorContext),694) {695self.queue_internal(command.handle_error_with(error_handler));696}697698/// Pushes a generic [`Command`] to the queue like [`Commands::queue_handled`], but instead silently ignores any errors.699pub fn queue_silenced<C: Command<T> + HandleError<T>, T>(&mut self, command: C) {700self.queue_internal(command.ignore_error());701}702703fn queue_internal(&mut self, command: impl Command) {704match &mut self.queue {705InternalQueue::CommandQueue(queue) => {706queue.push(command);707}708InternalQueue::RawCommandQueue(queue) => {709// SAFETY: `RawCommandQueue` is only every constructed in `Commands::new_raw_from_entities`710// where the caller of that has ensured that `queue` outlives `self`711unsafe {712queue.push(command);713}714}715}716}717718/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,719/// based on a batch of `(Entity, Bundle)` pairs.720///721/// A batch can be any type that implements [`IntoIterator`]722/// and contains `(Entity, Bundle)` tuples,723/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)724/// or an array `[(Entity, Bundle); N]`.725///726/// This will overwrite any pre-existing components shared by the [`Bundle`] type.727/// Use [`Commands::insert_batch_if_new`] to keep the pre-existing components instead.728///729/// This method is equivalent to iterating the batch730/// and calling [`insert`](EntityCommands::insert) for each pair,731/// but is faster by caching data that is shared between entities.732///733/// # Fallible734///735/// This command will fail if any of the given entities do not exist.736///737/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),738/// which will be handled by the [default error handler](crate::error::DefaultErrorHandler).739#[track_caller]740pub fn insert_batch<I, B>(&mut self, batch: I)741where742I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,743B: Bundle<Effect: NoBundleEffect>,744{745self.queue(command::insert_batch(batch, InsertMode::Replace));746}747748/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,749/// based on a batch of `(Entity, Bundle)` pairs.750///751/// A batch can be any type that implements [`IntoIterator`]752/// and contains `(Entity, Bundle)` tuples,753/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)754/// or an array `[(Entity, Bundle); N]`.755///756/// This will keep any pre-existing components shared by the [`Bundle`] type757/// and discard the new values.758/// Use [`Commands::insert_batch`] to overwrite the pre-existing components instead.759///760/// This method is equivalent to iterating the batch761/// and calling [`insert_if_new`](EntityCommands::insert_if_new) for each pair,762/// but is faster by caching data that is shared between entities.763///764/// # Fallible765///766/// This command will fail if any of the given entities do not exist.767///768/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),769/// which will be handled by the [default error handler](crate::error::DefaultErrorHandler).770#[track_caller]771pub fn insert_batch_if_new<I, B>(&mut self, batch: I)772where773I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,774B: Bundle<Effect: NoBundleEffect>,775{776self.queue(command::insert_batch(batch, InsertMode::Keep));777}778779/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,780/// based on a batch of `(Entity, Bundle)` pairs.781///782/// A batch can be any type that implements [`IntoIterator`]783/// and contains `(Entity, Bundle)` tuples,784/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)785/// or an array `[(Entity, Bundle); N]`.786///787/// This will overwrite any pre-existing components shared by the [`Bundle`] type.788/// Use [`Commands::try_insert_batch_if_new`] to keep the pre-existing components instead.789///790/// This method is equivalent to iterating the batch791/// and calling [`insert`](EntityCommands::insert) for each pair,792/// but is faster by caching data that is shared between entities.793///794/// # Fallible795///796/// This command will fail if any of the given entities do not exist.797///798/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),799/// which will be handled by [logging the error at the `warn` level](warn).800#[track_caller]801pub fn try_insert_batch<I, B>(&mut self, batch: I)802where803I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,804B: Bundle<Effect: NoBundleEffect>,805{806self.queue(command::insert_batch(batch, InsertMode::Replace).handle_error_with(warn));807}808809/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,810/// based on a batch of `(Entity, Bundle)` pairs.811///812/// A batch can be any type that implements [`IntoIterator`]813/// and contains `(Entity, Bundle)` tuples,814/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)815/// or an array `[(Entity, Bundle); N]`.816///817/// This will keep any pre-existing components shared by the [`Bundle`] type818/// and discard the new values.819/// Use [`Commands::try_insert_batch`] to overwrite the pre-existing components instead.820///821/// This method is equivalent to iterating the batch822/// and calling [`insert_if_new`](EntityCommands::insert_if_new) for each pair,823/// but is faster by caching data that is shared between entities.824///825/// # Fallible826///827/// This command will fail if any of the given entities do not exist.828///829/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),830/// which will be handled by [logging the error at the `warn` level](warn).831#[track_caller]832pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I)833where834I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,835B: Bundle<Effect: NoBundleEffect>,836{837self.queue(command::insert_batch(batch, InsertMode::Keep).handle_error_with(warn));838}839840/// Inserts a [`Resource`] into the [`World`] with an inferred value.841///842/// The inferred value is determined by the [`FromWorld`] trait of the resource.843/// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],844/// and those default values will be used.845///846/// If the resource already exists when the command is applied, nothing happens.847///848/// # Example849///850/// ```851/// # use bevy_ecs::prelude::*;852/// #[derive(Resource, Default)]853/// struct Scoreboard {854/// current_score: u32,855/// high_score: u32,856/// }857///858/// fn initialize_scoreboard(mut commands: Commands) {859/// commands.init_resource::<Scoreboard>();860/// }861/// # bevy_ecs::system::assert_is_system(initialize_scoreboard);862/// ```863#[track_caller]864pub fn init_resource<R: Resource + FromWorld>(&mut self) {865self.queue(command::init_resource::<R>());866}867868/// Inserts a [`Resource`] into the [`World`] with a specific value.869///870/// This will overwrite any previous value of the same resource type.871///872/// # Example873///874/// ```875/// # use bevy_ecs::prelude::*;876/// #[derive(Resource)]877/// struct Scoreboard {878/// current_score: u32,879/// high_score: u32,880/// }881///882/// fn system(mut commands: Commands) {883/// commands.insert_resource(Scoreboard {884/// current_score: 0,885/// high_score: 0,886/// });887/// }888/// # bevy_ecs::system::assert_is_system(system);889/// ```890#[track_caller]891pub fn insert_resource<R: Resource>(&mut self, resource: R) {892self.queue(command::insert_resource(resource));893}894895/// Removes a [`Resource`] from the [`World`].896///897/// # Example898///899/// ```900/// # use bevy_ecs::prelude::*;901/// #[derive(Resource)]902/// struct Scoreboard {903/// current_score: u32,904/// high_score: u32,905/// }906///907/// fn system(mut commands: Commands) {908/// commands.remove_resource::<Scoreboard>();909/// }910/// # bevy_ecs::system::assert_is_system(system);911/// ```912pub fn remove_resource<R: Resource>(&mut self) {913self.queue(command::remove_resource::<R>());914}915916/// Runs the system corresponding to the given [`SystemId`].917/// Before running a system, it must first be registered via918/// [`Commands::register_system`] or [`World::register_system`].919///920/// The system is run in an exclusive and single-threaded way.921/// Running slow systems can become a bottleneck.922///923/// There is no way to get the output of a system when run as a command, because the924/// execution of the system happens later. To get the output of a system, use925/// [`World::run_system`] or [`World::run_system_with`] instead of running the system as a command.926///927/// # Fallible928///929/// This command will fail if the given [`SystemId`]930/// does not correspond to a [`System`](crate::system::System).931///932/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),933/// which will be handled by [logging the error at the `warn` level](warn).934pub fn run_system(&mut self, id: SystemId) {935self.queue(command::run_system(id).handle_error_with(warn));936}937938/// Runs the system corresponding to the given [`SystemId`] with input.939/// Before running a system, it must first be registered via940/// [`Commands::register_system`] or [`World::register_system`].941///942/// The system is run in an exclusive and single-threaded way.943/// Running slow systems can become a bottleneck.944///945/// There is no way to get the output of a system when run as a command, because the946/// execution of the system happens later. To get the output of a system, use947/// [`World::run_system`] or [`World::run_system_with`] instead of running the system as a command.948///949/// # Fallible950///951/// This command will fail if the given [`SystemId`]952/// does not correspond to a [`System`](crate::system::System).953///954/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),955/// which will be handled by [logging the error at the `warn` level](warn).956pub fn run_system_with<I>(&mut self, id: SystemId<I>, input: I::Inner<'static>)957where958I: SystemInput<Inner<'static>: Send> + 'static,959{960self.queue(command::run_system_with(id, input).handle_error_with(warn));961}962963/// Registers a system and returns its [`SystemId`] so it can later be called by964/// [`Commands::run_system`] or [`World::run_system`].965///966/// This is different from adding systems to a [`Schedule`](crate::schedule::Schedule),967/// because the [`SystemId`] that is returned can be used anywhere in the [`World`] to run the associated system.968///969/// Using a [`Schedule`](crate::schedule::Schedule) is still preferred for most cases970/// due to its better performance and ability to run non-conflicting systems simultaneously.971///972/// # Note973///974/// If the same system is registered more than once,975/// each registration will be considered a different system,976/// and they will each be given their own [`SystemId`].977///978/// If you want to avoid registering the same system multiple times,979/// consider using [`Commands::run_system_cached`] or storing the [`SystemId`]980/// in a [`Local`](crate::system::Local).981///982/// # Example983///984/// ```985/// # use bevy_ecs::{prelude::*, world::CommandQueue, system::SystemId};986/// #[derive(Resource)]987/// struct Counter(i32);988///989/// fn register_system(990/// mut commands: Commands,991/// mut local_system: Local<Option<SystemId>>,992/// ) {993/// if let Some(system) = *local_system {994/// commands.run_system(system);995/// } else {996/// *local_system = Some(commands.register_system(increment_counter));997/// }998/// }999///1000/// fn increment_counter(mut value: ResMut<Counter>) {1001/// value.0 += 1;1002/// }1003///1004/// # let mut world = World::default();1005/// # world.insert_resource(Counter(0));1006/// # let mut queue_1 = CommandQueue::default();1007/// # let systemid = {1008/// # let mut commands = Commands::new(&mut queue_1, &world);1009/// # commands.register_system(increment_counter)1010/// # };1011/// # let mut queue_2 = CommandQueue::default();1012/// # {1013/// # let mut commands = Commands::new(&mut queue_2, &world);1014/// # commands.run_system(systemid);1015/// # }1016/// # queue_1.append(&mut queue_2);1017/// # queue_1.apply(&mut world);1018/// # assert_eq!(1, world.resource::<Counter>().0);1019/// # bevy_ecs::system::assert_is_system(register_system);1020/// ```1021pub fn register_system<I, O, M>(1022&mut self,1023system: impl IntoSystem<I, O, M> + 'static,1024) -> SystemId<I, O>1025where1026I: SystemInput + Send + 'static,1027O: Send + 'static,1028{1029let entity = self.spawn_empty().id();1030let system = RegisteredSystem::<I, O>::new(Box::new(IntoSystem::into_system(system)));1031self.entity(entity).insert(system);1032SystemId::from_entity(entity)1033}10341035/// Removes a system previously registered with [`Commands::register_system`]1036/// or [`World::register_system`].1037///1038/// After removing a system, the [`SystemId`] becomes invalid1039/// and attempting to use it afterwards will result in an error.1040/// Re-adding the removed system will register it with a new `SystemId`.1041///1042/// # Fallible1043///1044/// This command will fail if the given [`SystemId`]1045/// does not correspond to a [`System`](crate::system::System).1046///1047/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),1048/// which will be handled by [logging the error at the `warn` level](warn).1049pub fn unregister_system<I, O>(&mut self, system_id: SystemId<I, O>)1050where1051I: SystemInput + Send + 'static,1052O: Send + 'static,1053{1054self.queue(command::unregister_system(system_id).handle_error_with(warn));1055}10561057/// Removes a system previously registered with one of the following:1058/// - [`Commands::run_system_cached`]1059/// - [`World::run_system_cached`]1060/// - [`World::register_system_cached`]1061///1062/// # Fallible1063///1064/// This command will fail if the given system1065/// is not currently cached in a [`CachedSystemId`](crate::system::CachedSystemId) resource.1066///1067/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),1068/// which will be handled by [logging the error at the `warn` level](warn).1069pub fn unregister_system_cached<I, O, M, S>(&mut self, system: S)1070where1071I: SystemInput + Send + 'static,1072O: 'static,1073M: 'static,1074S: IntoSystem<I, O, M> + Send + 'static,1075{1076self.queue(command::unregister_system_cached(system).handle_error_with(warn));1077}10781079/// Runs a cached system, registering it if necessary.1080///1081/// Unlike [`Commands::run_system`], this method does not require manual registration.1082///1083/// The first time this method is called for a particular system,1084/// it will register the system and store its [`SystemId`] in a1085/// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.1086///1087/// If you would rather manage the [`SystemId`] yourself,1088/// or register multiple copies of the same system,1089/// use [`Commands::register_system`] instead.1090///1091/// # Limitations1092///1093/// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of1094/// the same type must be equal. This means that closures that capture the environment, and1095/// function pointers, are not accepted.1096///1097/// If you want to access values from the environment within a system,1098/// consider passing them in as inputs via [`Commands::run_system_cached_with`].1099///1100/// If that's not an option, consider [`Commands::register_system`] instead.1101pub fn run_system_cached<M, S>(&mut self, system: S)1102where1103M: 'static,1104S: IntoSystem<(), (), M> + Send + 'static,1105{1106self.queue(command::run_system_cached(system).handle_error_with(warn));1107}11081109/// Runs a cached system with an input, registering it if necessary.1110///1111/// Unlike [`Commands::run_system_with`], this method does not require manual registration.1112///1113/// The first time this method is called for a particular system,1114/// it will register the system and store its [`SystemId`] in a1115/// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.1116///1117/// If you would rather manage the [`SystemId`] yourself,1118/// or register multiple copies of the same system,1119/// use [`Commands::register_system`] instead.1120///1121/// # Limitations1122///1123/// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of1124/// the same type must be equal. This means that closures that capture the environment, and1125/// function pointers, are not accepted.1126///1127/// If you want to access values from the environment within a system,1128/// consider passing them in as inputs.1129///1130/// If that's not an option, consider [`Commands::register_system`] instead.1131pub fn run_system_cached_with<I, M, S>(&mut self, system: S, input: I::Inner<'static>)1132where1133I: SystemInput<Inner<'static>: Send> + Send + 'static,1134M: 'static,1135S: IntoSystem<I, (), M> + Send + 'static,1136{1137self.queue(command::run_system_cached_with(system, input).handle_error_with(warn));1138}11391140/// Triggers the given [`Event`], which will run any [`Observer`]s watching for it.1141///1142/// [`Observer`]: crate::observer::Observer1143#[track_caller]1144pub fn trigger<'a>(&mut self, event: impl Event<Trigger<'a>: Default>) {1145self.queue(command::trigger(event));1146}11471148/// Triggers the given [`Event`] using the given [`Trigger`], which will run any [`Observer`]s watching for it.1149///1150/// [`Trigger`]: crate::event::Trigger1151/// [`Observer`]: crate::observer::Observer1152#[track_caller]1153pub fn trigger_with<E: Event<Trigger<'static>: Send + Sync>>(1154&mut self,1155event: E,1156trigger: E::Trigger<'static>,1157) {1158self.queue(command::trigger_with(event, trigger));1159}11601161/// Spawns an [`Observer`](crate::observer::Observer) and returns the [`EntityCommands`] associated1162/// with the entity that stores the observer.1163///1164/// `observer` can be any system whose first parameter is [`On`].1165///1166/// **Calling [`observe`](EntityCommands::observe) on the returned1167/// [`EntityCommands`] will observe the observer itself, which you very1168/// likely do not want.**1169///1170/// # Panics1171///1172/// Panics if the given system is an exclusive system.1173///1174/// [`On`]: crate::observer::On1175pub fn add_observer<M>(&mut self, observer: impl IntoObserver<M>) -> EntityCommands<'_> {1176self.spawn(observer.into_observer())1177}11781179/// Writes an arbitrary [`Message`].1180///1181/// This is a convenience method for writing messages1182/// without requiring a [`MessageWriter`](crate::message::MessageWriter).1183///1184/// # Performance1185///1186/// Since this is a command, exclusive world access is used, which means that it will not profit from1187/// system-level parallelism on supported platforms.1188///1189/// If these messages are performance-critical or very frequently sent,1190/// consider using a [`MessageWriter`](crate::message::MessageWriter) instead.1191#[track_caller]1192pub fn write_message<M: Message>(&mut self, message: M) -> &mut Self {1193self.queue(command::write_message(message));1194self1195}11961197/// Runs the schedule corresponding to the given [`ScheduleLabel`].1198///1199/// Calls [`World::try_run_schedule`](World::try_run_schedule).1200///1201/// # Fallible1202///1203/// This command will fail if the given [`ScheduleLabel`]1204/// does not correspond to a [`Schedule`](crate::schedule::Schedule).1205///1206/// It will internally return a [`TryRunScheduleError`](crate::world::error::TryRunScheduleError),1207/// which will be handled by [logging the error at the `warn` level](warn).1208///1209/// # Example1210///1211/// ```1212/// # use bevy_ecs::prelude::*;1213/// # use bevy_ecs::schedule::ScheduleLabel;1214/// # #[derive(Default, Resource)]1215/// # struct Counter(u32);1216/// #[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone, Copy)]1217/// struct FooSchedule;1218///1219/// # fn foo_system(mut counter: ResMut<Counter>) {1220/// # counter.0 += 1;1221/// # }1222/// #1223/// # let mut schedule = Schedule::new(FooSchedule);1224/// # schedule.add_systems(foo_system);1225/// #1226/// # let mut world = World::default();1227/// #1228/// # world.init_resource::<Counter>();1229/// # world.add_schedule(schedule);1230/// #1231/// # assert_eq!(world.resource::<Counter>().0, 0);1232/// #1233/// # let mut commands = world.commands();1234/// commands.run_schedule(FooSchedule);1235/// #1236/// # world.flush();1237/// #1238/// # assert_eq!(world.resource::<Counter>().0, 1);1239/// ```1240pub fn run_schedule(&mut self, label: impl ScheduleLabel) {1241self.queue(command::run_schedule(label).handle_error_with(warn));1242}1243}12441245/// A list of commands that will be run to modify an [`Entity`].1246///1247/// # Note1248///1249/// Most [`Commands`] (and thereby [`EntityCommands`]) are deferred:1250/// when you call the command, if it requires mutable access to the [`World`]1251/// (that is, if it removes, adds, or changes something), it's not executed immediately.1252///1253/// Instead, the command is added to a "command queue."1254/// The command queue is applied later1255/// when the [`ApplyDeferred`](crate::schedule::ApplyDeferred) system runs.1256/// Commands are executed one-by-one so that1257/// each command can have exclusive access to the `World`.1258///1259/// # Fallible1260///1261/// Due to their deferred nature, an entity you're trying to change with an [`EntityCommand`]1262/// can be despawned by the time the command is executed.1263///1264/// All deferred entity commands will check whether the entity exists at the time of execution1265/// and will return an error if it doesn't.1266///1267/// # Error handling1268///1269/// An [`EntityCommand`] can return a [`Result`](crate::error::Result),1270/// which will be passed to an [error handler](crate::error) if the `Result` is an error.1271///1272/// The default error handler panics. It can be configured via1273/// the [`DefaultErrorHandler`](crate::error::DefaultErrorHandler) resource.1274///1275/// Alternatively, you can customize the error handler for a specific command1276/// by calling [`EntityCommands::queue_handled`].1277///1278/// The [`error`](crate::error) module provides some simple error handlers for convenience.1279pub struct EntityCommands<'a> {1280pub(crate) entity: Entity,1281pub(crate) commands: Commands<'a, 'a>,1282}12831284impl<'a> EntityCommands<'a> {1285/// Returns the [`Entity`] id of the entity.1286///1287/// # Example1288///1289/// ```1290/// # use bevy_ecs::prelude::*;1291/// #1292/// fn my_system(mut commands: Commands) {1293/// let entity_id = commands.spawn_empty().id();1294/// }1295/// # bevy_ecs::system::assert_is_system(my_system);1296/// ```1297#[inline]1298#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]1299pub fn id(&self) -> Entity {1300self.entity1301}13021303/// Returns an [`EntityCommands`] with a smaller lifetime.1304///1305/// This is useful if you have `&mut EntityCommands` but you need `EntityCommands`.1306pub fn reborrow(&mut self) -> EntityCommands<'_> {1307EntityCommands {1308entity: self.entity,1309commands: self.commands.reborrow(),1310}1311}13121313/// Get an [`EntityEntryCommands`] for the [`Component`] `T`,1314/// allowing you to modify it or insert it if it isn't already present.1315///1316/// See also [`insert_if_new`](Self::insert_if_new),1317/// which lets you insert a [`Bundle`] without overwriting it.1318///1319/// # Example1320///1321/// ```1322/// # use bevy_ecs::prelude::*;1323/// # #[derive(Resource)]1324/// # struct PlayerEntity { entity: Entity }1325/// #[derive(Component)]1326/// struct Level(u32);1327///1328///1329/// #[derive(Component, Default)]1330/// struct Mana {1331/// max: u32,1332/// current: u32,1333/// }1334///1335/// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {1336/// // If a component already exists then modify it, otherwise insert a default value1337/// commands1338/// .entity(player.entity)1339/// .entry::<Level>()1340/// .and_modify(|mut lvl| lvl.0 += 1)1341/// .or_insert(Level(0));1342///1343/// // Add a default value if none exists, and then modify the existing or new value1344/// commands1345/// .entity(player.entity)1346/// .entry::<Mana>()1347/// .or_default()1348/// .and_modify(|mut mana| {1349/// mana.max += 10;1350/// mana.current = mana.max;1351/// });1352/// }1353///1354/// # bevy_ecs::system::assert_is_system(level_up_system);1355/// ```1356pub fn entry<T: Component>(&mut self) -> EntityEntryCommands<'_, T> {1357EntityEntryCommands {1358entity_commands: self.reborrow(),1359marker: PhantomData,1360}1361}13621363/// Adds a [`Bundle`] of components to the entity.1364///1365/// This will overwrite any previous value(s) of the same component type.1366/// See [`EntityCommands::insert_if_new`] to keep the old value instead.1367///1368/// # Example1369///1370/// ```1371/// # use bevy_ecs::prelude::*;1372/// # #[derive(Resource)]1373/// # struct PlayerEntity { entity: Entity }1374/// #[derive(Component)]1375/// struct Health(u32);1376/// #[derive(Component)]1377/// struct Strength(u32);1378/// #[derive(Component)]1379/// struct Defense(u32);1380///1381/// #[derive(Bundle)]1382/// struct CombatBundle {1383/// health: Health,1384/// strength: Strength,1385/// }1386///1387/// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1388/// commands1389/// .entity(player.entity)1390/// // You can insert individual components:1391/// .insert(Defense(10))1392/// // You can also insert pre-defined bundles of components:1393/// .insert(CombatBundle {1394/// health: Health(100),1395/// strength: Strength(40),1396/// })1397/// // You can also insert tuples of components and bundles.1398/// // This is equivalent to the calls above:1399/// .insert((1400/// Defense(10),1401/// CombatBundle {1402/// health: Health(100),1403/// strength: Strength(40),1404/// },1405/// ));1406/// }1407/// # bevy_ecs::system::assert_is_system(add_combat_stats_system);1408/// ```1409#[track_caller]1410pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self {1411self.queue(entity_command::insert(bundle, InsertMode::Replace))1412}14131414/// Adds a [`Bundle`] of components to the entity if the predicate returns true.1415///1416/// This is useful for chaining method calls.1417///1418/// # Example1419///1420/// ```1421/// # use bevy_ecs::prelude::*;1422/// # #[derive(Resource)]1423/// # struct PlayerEntity { entity: Entity }1424/// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }1425/// #[derive(Component)]1426/// struct StillLoadingStats;1427/// #[derive(Component)]1428/// struct Health(u32);1429///1430/// fn add_health_system(mut commands: Commands, player: Res<PlayerEntity>) {1431/// commands1432/// .entity(player.entity)1433/// .insert_if(Health(10), || !player.is_spectator())1434/// .remove::<StillLoadingStats>();1435/// }1436/// # bevy_ecs::system::assert_is_system(add_health_system);1437/// ```1438#[track_caller]1439pub fn insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1440where1441F: FnOnce() -> bool,1442{1443if condition() {1444self.insert(bundle)1445} else {1446self1447}1448}14491450/// Adds a [`Bundle`] of components to the entity without overwriting.1451///1452/// This is the same as [`EntityCommands::insert`], but in case of duplicate1453/// components will leave the old values instead of replacing them with new ones.1454///1455/// See also [`entry`](Self::entry), which lets you modify a [`Component`] if it's present,1456/// as well as initialize it with a default value.1457#[track_caller]1458pub fn insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {1459self.queue(entity_command::insert(bundle, InsertMode::Keep))1460}14611462/// Adds a [`Bundle`] of components to the entity without overwriting if the1463/// predicate returns true.1464///1465/// This is the same as [`EntityCommands::insert_if`], but in case of duplicate1466/// components will leave the old values instead of replacing them with new ones.1467#[track_caller]1468pub fn insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1469where1470F: FnOnce() -> bool,1471{1472if condition() {1473self.insert_if_new(bundle)1474} else {1475self1476}1477}14781479/// Adds a dynamic [`Component`] to the entity.1480///1481/// This will overwrite any previous value(s) of the same component type.1482///1483/// You should prefer to use the typed API [`EntityCommands::insert`] where possible.1484///1485/// # Safety1486///1487/// - [`ComponentId`] must be from the same world as `self`.1488/// - `T` must have the same layout as the one passed during `component_id` creation.1489#[track_caller]1490pub unsafe fn insert_by_id<T: Send + 'static>(1491&mut self,1492component_id: ComponentId,1493value: T,1494) -> &mut Self {1495self.queue(1496// SAFETY:1497// - `ComponentId` safety is ensured by the caller.1498// - `T` safety is ensured by the caller.1499unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },1500)1501}15021503/// Adds a dynamic [`Component`] to the entity.1504///1505/// This will overwrite any previous value(s) of the same component type.1506///1507/// You should prefer to use the typed API [`EntityCommands::try_insert`] where possible.1508///1509/// # Note1510///1511/// If the entity does not exist when this command is executed,1512/// the resulting error will be ignored.1513///1514/// # Safety1515///1516/// - [`ComponentId`] must be from the same world as `self`.1517/// - `T` must have the same layout as the one passed during `component_id` creation.1518#[track_caller]1519pub unsafe fn try_insert_by_id<T: Send + 'static>(1520&mut self,1521component_id: ComponentId,1522value: T,1523) -> &mut Self {1524self.queue_silenced(1525// SAFETY:1526// - `ComponentId` safety is ensured by the caller.1527// - `T` safety is ensured by the caller.1528unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },1529)1530}15311532/// Adds a [`Bundle`] of components to the entity.1533///1534/// This will overwrite any previous value(s) of the same component type.1535///1536/// # Note1537///1538/// If the entity does not exist when this command is executed,1539/// the resulting error will be ignored.1540///1541/// # Example1542///1543/// ```1544/// # use bevy_ecs::prelude::*;1545/// # #[derive(Resource)]1546/// # struct PlayerEntity { entity: Entity }1547/// #[derive(Component)]1548/// struct Health(u32);1549/// #[derive(Component)]1550/// struct Strength(u32);1551/// #[derive(Component)]1552/// struct Defense(u32);1553///1554/// #[derive(Bundle)]1555/// struct CombatBundle {1556/// health: Health,1557/// strength: Strength,1558/// }1559///1560/// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1561/// commands.entity(player.entity)1562/// // You can insert individual components:1563/// .try_insert(Defense(10))1564/// // You can also insert tuples of components:1565/// .try_insert(CombatBundle {1566/// health: Health(100),1567/// strength: Strength(40),1568/// });1569///1570/// // Suppose this occurs in a parallel adjacent system or process.1571/// commands.entity(player.entity).despawn();1572///1573/// // This will not panic nor will it add the component.1574/// commands.entity(player.entity).try_insert(Defense(5));1575/// }1576/// # bevy_ecs::system::assert_is_system(add_combat_stats_system);1577/// ```1578#[track_caller]1579pub fn try_insert(&mut self, bundle: impl Bundle) -> &mut Self {1580self.queue_silenced(entity_command::insert(bundle, InsertMode::Replace))1581}15821583/// Adds a [`Bundle`] of components to the entity if the predicate returns true.1584///1585/// This is useful for chaining method calls.1586///1587/// # Note1588///1589/// If the entity does not exist when this command is executed,1590/// the resulting error will be ignored.1591#[track_caller]1592pub fn try_insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1593where1594F: FnOnce() -> bool,1595{1596if condition() {1597self.try_insert(bundle)1598} else {1599self1600}1601}16021603/// Adds a [`Bundle`] of components to the entity without overwriting if the1604/// predicate returns true.1605///1606/// This is the same as [`EntityCommands::try_insert_if`], but in case of duplicate1607/// components will leave the old values instead of replacing them with new ones.1608///1609/// # Note1610///1611/// If the entity does not exist when this command is executed,1612/// the resulting error will be ignored.1613#[track_caller]1614pub fn try_insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1615where1616F: FnOnce() -> bool,1617{1618if condition() {1619self.try_insert_if_new(bundle)1620} else {1621self1622}1623}16241625/// Adds a [`Bundle`] of components to the entity without overwriting.1626///1627/// This is the same as [`EntityCommands::try_insert`], but in case of duplicate1628/// components will leave the old values instead of replacing them with new ones.1629///1630/// # Note1631///1632/// If the entity does not exist when this command is executed,1633/// the resulting error will be ignored.1634#[track_caller]1635pub fn try_insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {1636self.queue_silenced(entity_command::insert(bundle, InsertMode::Keep))1637}16381639/// Removes a [`Bundle`] of components from the entity.1640///1641/// This will remove all components that intersect with the provided bundle;1642/// the entity does not need to have all the components in the bundle.1643///1644/// This will emit a warning if the entity does not exist.1645///1646/// # Example1647///1648/// ```1649/// # use bevy_ecs::prelude::*;1650/// # #[derive(Resource)]1651/// # struct PlayerEntity { entity: Entity }1652/// #[derive(Component)]1653/// struct Health(u32);1654/// #[derive(Component)]1655/// struct Strength(u32);1656/// #[derive(Component)]1657/// struct Defense(u32);1658///1659/// #[derive(Bundle)]1660/// struct CombatBundle {1661/// health: Health,1662/// strength: Strength,1663/// }1664///1665/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1666/// commands1667/// .entity(player.entity)1668/// // You can remove individual components:1669/// .remove::<Defense>()1670/// // You can also remove pre-defined bundles of components:1671/// .remove::<CombatBundle>()1672/// // You can also remove tuples of components and bundles.1673/// // This is equivalent to the calls above:1674/// .remove::<(Defense, CombatBundle)>();1675/// }1676/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1677/// ```1678#[track_caller]1679pub fn remove<B: Bundle>(&mut self) -> &mut Self {1680self.queue_handled(entity_command::remove::<B>(), warn)1681}16821683/// Removes a [`Bundle`] of components from the entity if the predicate returns true.1684///1685/// This is useful for chaining method calls.1686///1687/// # Example1688///1689/// ```1690/// # use bevy_ecs::prelude::*;1691/// # #[derive(Resource)]1692/// # struct PlayerEntity { entity: Entity }1693/// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }1694/// #[derive(Component)]1695/// struct Health(u32);1696/// #[derive(Component)]1697/// struct Strength(u32);1698/// #[derive(Component)]1699/// struct Defense(u32);1700///1701/// #[derive(Bundle)]1702/// struct CombatBundle {1703/// health: Health,1704/// strength: Strength,1705/// }1706///1707/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1708/// commands1709/// .entity(player.entity)1710/// .remove_if::<(Defense, CombatBundle)>(|| !player.is_spectator());1711/// }1712/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1713/// ```1714#[track_caller]1715pub fn remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {1716if condition() {1717self.remove::<B>()1718} else {1719self1720}1721}17221723/// Removes a [`Bundle`] of components from the entity if the predicate returns true.1724///1725/// This is useful for chaining method calls.1726///1727/// # Note1728///1729/// If the entity does not exist when this command is executed,1730/// the resulting error will be ignored.1731#[track_caller]1732pub fn try_remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {1733if condition() {1734self.try_remove::<B>()1735} else {1736self1737}1738}17391740/// Removes a [`Bundle`] of components from the entity.1741///1742/// This will remove all components that intersect with the provided bundle;1743/// the entity does not need to have all the components in the bundle.1744///1745/// Unlike [`Self::remove`],1746/// this will not emit a warning if the entity does not exist.1747///1748/// # Example1749///1750/// ```1751/// # use bevy_ecs::prelude::*;1752/// # #[derive(Resource)]1753/// # struct PlayerEntity { entity: Entity }1754/// #[derive(Component)]1755/// struct Health(u32);1756/// #[derive(Component)]1757/// struct Strength(u32);1758/// #[derive(Component)]1759/// struct Defense(u32);1760///1761/// #[derive(Bundle)]1762/// struct CombatBundle {1763/// health: Health,1764/// strength: Strength,1765/// }1766///1767/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1768/// commands1769/// .entity(player.entity)1770/// // You can remove individual components:1771/// .try_remove::<Defense>()1772/// // You can also remove pre-defined bundles of components:1773/// .try_remove::<CombatBundle>()1774/// // You can also remove tuples of components and bundles.1775/// // This is equivalent to the calls above:1776/// .try_remove::<(Defense, CombatBundle)>();1777/// }1778/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1779/// ```1780pub fn try_remove<B: Bundle>(&mut self) -> &mut Self {1781self.queue_silenced(entity_command::remove::<B>())1782}17831784/// Removes a [`Bundle`] of components from the entity,1785/// and also removes any components required by the components in the bundle.1786///1787/// This will remove all components that intersect with the provided bundle;1788/// the entity does not need to have all the components in the bundle.1789///1790/// # Example1791///1792/// ```1793/// # use bevy_ecs::prelude::*;1794/// # #[derive(Resource)]1795/// # struct PlayerEntity { entity: Entity }1796/// #1797/// #[derive(Component)]1798/// #[require(B)]1799/// struct A;1800/// #[derive(Component, Default)]1801/// struct B;1802///1803/// fn remove_with_requires_system(mut commands: Commands, player: Res<PlayerEntity>) {1804/// commands1805/// .entity(player.entity)1806/// // Removes both A and B from the entity, because B is required by A.1807/// .remove_with_requires::<A>();1808/// }1809/// # bevy_ecs::system::assert_is_system(remove_with_requires_system);1810/// ```1811#[track_caller]1812pub fn remove_with_requires<B: Bundle>(&mut self) -> &mut Self {1813self.queue(entity_command::remove_with_requires::<B>())1814}18151816/// Removes a dynamic [`Component`] from the entity if it exists.1817///1818/// # Panics1819///1820/// Panics if the provided [`ComponentId`] does not exist in the [`World`].1821#[track_caller]1822pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {1823self.queue(entity_command::remove_by_id(component_id))1824}18251826/// Removes all components associated with the entity.1827#[track_caller]1828pub fn clear(&mut self) -> &mut Self {1829self.queue(entity_command::clear())1830}18311832/// Despawns the entity.1833///1834/// This will emit a warning if the entity does not exist.1835///1836/// # Note1837///1838/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)1839/// that is configured to despawn descendants.1840///1841/// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1842///1843/// # Example1844///1845/// ```1846/// # use bevy_ecs::prelude::*;1847/// # #[derive(Resource)]1848/// # struct CharacterToRemove { entity: Entity }1849/// #1850/// fn remove_character_system(1851/// mut commands: Commands,1852/// character_to_remove: Res<CharacterToRemove>1853/// ) {1854/// commands.entity(character_to_remove.entity).despawn();1855/// }1856/// # bevy_ecs::system::assert_is_system(remove_character_system);1857/// ```1858#[track_caller]1859pub fn despawn(&mut self) {1860self.queue_handled(entity_command::despawn(), warn);1861}18621863/// Despawns the entity.1864///1865/// Unlike [`Self::despawn`],1866/// this will not emit a warning if the entity does not exist.1867///1868/// # Note1869///1870/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)1871/// that is configured to despawn descendants.1872///1873/// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1874pub fn try_despawn(&mut self) {1875self.queue_silenced(entity_command::despawn());1876}18771878/// Pushes an [`EntityCommand`] to the queue,1879/// which will get executed for the current [`Entity`].1880///1881/// The [default error handler](crate::error::DefaultErrorHandler)1882/// will be used to handle error cases.1883/// Every [`EntityCommand`] checks whether the entity exists at the time of execution1884/// and returns an error if it does not.1885///1886/// To use a custom error handler, see [`EntityCommands::queue_handled`].1887///1888/// The command can be:1889/// - A custom struct that implements [`EntityCommand`].1890/// - A closure or function that matches the following signature:1891/// - [`(EntityWorldMut)`](EntityWorldMut)1892/// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]1893/// - A built-in command from the [`entity_command`] module.1894///1895/// # Example1896///1897/// ```1898/// # use bevy_ecs::prelude::*;1899/// # fn my_system(mut commands: Commands) {1900/// commands1901/// .spawn_empty()1902/// // Closures with this signature implement `EntityCommand`.1903/// .queue(|entity: EntityWorldMut| {1904/// println!("Executed an EntityCommand for {}", entity.id());1905/// });1906/// # }1907/// # bevy_ecs::system::assert_is_system(my_system);1908/// ```1909pub fn queue<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(1910&mut self,1911command: C,1912) -> &mut Self {1913self.commands.queue(command.with_entity(self.entity));1914self1915}19161917/// Pushes an [`EntityCommand`] to the queue,1918/// which will get executed for the current [`Entity`].1919///1920/// The given `error_handler` will be used to handle error cases.1921/// Every [`EntityCommand`] checks whether the entity exists at the time of execution1922/// and returns an error if it does not.1923///1924/// To implicitly use the default error handler, see [`EntityCommands::queue`].1925///1926/// The command can be:1927/// - A custom struct that implements [`EntityCommand`].1928/// - A closure or function that matches the following signature:1929/// - [`(EntityWorldMut)`](EntityWorldMut)1930/// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]1931/// - A built-in command from the [`entity_command`] module.1932///1933/// # Example1934///1935/// ```1936/// # use bevy_ecs::prelude::*;1937/// # fn my_system(mut commands: Commands) {1938/// use bevy_ecs::error::warn;1939///1940/// commands1941/// .spawn_empty()1942/// // Closures with this signature implement `EntityCommand`.1943/// .queue_handled(1944/// |entity: EntityWorldMut| -> Result {1945/// let value: usize = "100".parse()?;1946/// println!("Successfully parsed the value {} for entity {}", value, entity.id());1947/// Ok(())1948/// },1949/// warn1950/// );1951/// # }1952/// # bevy_ecs::system::assert_is_system(my_system);1953/// ```1954pub fn queue_handled<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(1955&mut self,1956command: C,1957error_handler: fn(BevyError, ErrorContext),1958) -> &mut Self {1959self.commands1960.queue_handled(command.with_entity(self.entity), error_handler);1961self1962}19631964/// Pushes an [`EntityCommand`] to the queue, which will get executed for the current [`Entity`].1965///1966/// Unlike [`EntityCommands::queue_handled`], this will completely ignore any errors that occur.1967pub fn queue_silenced<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(1968&mut self,1969command: C,1970) -> &mut Self {1971self.commands1972.queue_silenced(command.with_entity(self.entity));1973self1974}19751976/// Removes all components except the given [`Bundle`] from the entity.1977///1978/// # Example1979///1980/// ```1981/// # use bevy_ecs::prelude::*;1982/// # #[derive(Resource)]1983/// # struct PlayerEntity { entity: Entity }1984/// #[derive(Component)]1985/// struct Health(u32);1986/// #[derive(Component)]1987/// struct Strength(u32);1988/// #[derive(Component)]1989/// struct Defense(u32);1990///1991/// #[derive(Bundle)]1992/// struct CombatBundle {1993/// health: Health,1994/// strength: Strength,1995/// }1996///1997/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1998/// commands1999/// .entity(player.entity)2000/// // You can retain a pre-defined Bundle of components,2001/// // with this removing only the Defense component.2002/// .retain::<CombatBundle>()2003/// // You can also retain only a single component.2004/// .retain::<Health>();2005/// }2006/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);2007/// ```2008#[track_caller]2009pub fn retain<B: Bundle>(&mut self) -> &mut Self {2010self.queue(entity_command::retain::<B>())2011}20122013/// Logs the components of the entity at the [`info`](log::info) level.2014pub fn log_components(&mut self) -> &mut Self {2015self.queue(entity_command::log_components())2016}20172018/// Returns the underlying [`Commands`].2019pub fn commands(&mut self) -> Commands<'_, '_> {2020self.commands.reborrow()2021}20222023/// Returns a mutable reference to the underlying [`Commands`].2024pub fn commands_mut(&mut self) -> &mut Commands<'a, 'a> {2025&mut self.commands2026}20272028/// Creates an [`Observer`](crate::observer::Observer) watching for an [`EntityEvent`] of type `E` whose [`EntityEvent::event_target`]2029/// targets this entity.2030pub fn observe<M>(&mut self, observer: impl IntoEntityObserver<M>) -> &mut Self {2031self.queue(entity_command::observe(observer))2032}20332034/// Clones parts of an entity (components, observers, etc.) onto another entity,2035/// configured through [`EntityClonerBuilder`].2036///2037/// The other entity will receive all the components of the original that implement2038/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are2039/// [denied](EntityClonerBuilder::deny) in the `config`.2040///2041/// # Panics2042///2043/// The command will panic when applied if the target entity does not exist.2044///2045/// # Example2046///2047/// Configure through [`EntityClonerBuilder<OptOut>`] as follows:2048/// ```2049/// # use bevy_ecs::prelude::*;2050/// #[derive(Component, Clone)]2051/// struct ComponentA(u32);2052/// #[derive(Component, Clone)]2053/// struct ComponentB(u32);2054///2055/// fn example_system(mut commands: Commands) {2056/// // Create an empty entity.2057/// let target = commands.spawn_empty().id();2058///2059/// // Create a new entity and keep its EntityCommands.2060/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2061///2062/// // Clone ComponentA but not ComponentB onto the target.2063/// entity.clone_with_opt_out(target, |builder| {2064/// builder.deny::<ComponentB>();2065/// });2066/// }2067/// # bevy_ecs::system::assert_is_system(example_system);2068/// ```2069///2070/// See [`EntityClonerBuilder`] for more options.2071pub fn clone_with_opt_out(2072&mut self,2073target: Entity,2074config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,2075) -> &mut Self {2076self.queue(entity_command::clone_with_opt_out(target, config))2077}20782079/// Clones parts of an entity (components, observers, etc.) onto another entity,2080/// configured through [`EntityClonerBuilder`].2081///2082/// The other entity will receive only the components of the original that implement2083/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are2084/// [allowed](EntityClonerBuilder::allow) in the `config`.2085///2086/// # Panics2087///2088/// The command will panic when applied if the target entity does not exist.2089///2090/// # Example2091///2092/// Configure through [`EntityClonerBuilder<OptIn>`] as follows:2093/// ```2094/// # use bevy_ecs::prelude::*;2095/// #[derive(Component, Clone)]2096/// struct ComponentA(u32);2097/// #[derive(Component, Clone)]2098/// struct ComponentB(u32);2099///2100/// fn example_system(mut commands: Commands) {2101/// // Create an empty entity.2102/// let target = commands.spawn_empty().id();2103///2104/// // Create a new entity and keep its EntityCommands.2105/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2106///2107/// // Clone ComponentA but not ComponentB onto the target.2108/// entity.clone_with_opt_in(target, |builder| {2109/// builder.allow::<ComponentA>();2110/// });2111/// }2112/// # bevy_ecs::system::assert_is_system(example_system);2113/// ```2114///2115/// See [`EntityClonerBuilder`] for more options.2116pub fn clone_with_opt_in(2117&mut self,2118target: Entity,2119config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,2120) -> &mut Self {2121self.queue(entity_command::clone_with_opt_in(target, config))2122}21232124/// Spawns a clone of this entity and returns the [`EntityCommands`] of the clone.2125///2126/// The clone will receive all the components of the original that implement2127/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).2128///2129/// To configure cloning behavior (such as only cloning certain components),2130/// use [`EntityCommands::clone_and_spawn_with_opt_out`]/2131/// [`opt_out`](EntityCommands::clone_and_spawn_with_opt_out).2132///2133/// # Note2134///2135/// If the original entity does not exist when this command is applied,2136/// the returned entity will have no components.2137///2138/// # Example2139///2140/// ```2141/// # use bevy_ecs::prelude::*;2142/// #[derive(Component, Clone)]2143/// struct ComponentA(u32);2144/// #[derive(Component, Clone)]2145/// struct ComponentB(u32);2146///2147/// fn example_system(mut commands: Commands) {2148/// // Create a new entity and store its EntityCommands.2149/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2150///2151/// // Create a clone of the entity.2152/// let mut entity_clone = entity.clone_and_spawn();2153/// }2154/// # bevy_ecs::system::assert_is_system(example_system);2155pub fn clone_and_spawn(&mut self) -> EntityCommands<'_> {2156self.clone_and_spawn_with_opt_out(|_| {})2157}21582159/// Spawns a clone of this entity and allows configuring cloning behavior2160/// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.2161///2162/// The clone will receive all the components of the original that implement2163/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are2164/// [denied](EntityClonerBuilder::deny) in the `config`.2165///2166/// See the methods on [`EntityClonerBuilder<OptOut>`] for more options.2167///2168/// # Note2169///2170/// If the original entity does not exist when this command is applied,2171/// the returned entity will have no components.2172///2173/// # Example2174///2175/// ```2176/// # use bevy_ecs::prelude::*;2177/// #[derive(Component, Clone)]2178/// struct ComponentA(u32);2179/// #[derive(Component, Clone)]2180/// struct ComponentB(u32);2181///2182/// fn example_system(mut commands: Commands) {2183/// // Create a new entity and store its EntityCommands.2184/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2185///2186/// // Create a clone of the entity with ComponentA but without ComponentB.2187/// let mut entity_clone = entity.clone_and_spawn_with_opt_out(|builder| {2188/// builder.deny::<ComponentB>();2189/// });2190/// }2191/// # bevy_ecs::system::assert_is_system(example_system);2192pub fn clone_and_spawn_with_opt_out(2193&mut self,2194config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,2195) -> EntityCommands<'_> {2196let entity_clone = self.commands().spawn_empty().id();2197self.clone_with_opt_out(entity_clone, config);2198EntityCommands {2199commands: self.commands_mut().reborrow(),2200entity: entity_clone,2201}2202}22032204/// Spawns a clone of this entity and allows configuring cloning behavior2205/// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.2206///2207/// The clone will receive only the components of the original that implement2208/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are2209/// [allowed](EntityClonerBuilder::allow) in the `config`.2210///2211/// See the methods on [`EntityClonerBuilder<OptIn>`] for more options.2212///2213/// # Note2214///2215/// If the original entity does not exist when this command is applied,2216/// the returned entity will have no components.2217///2218/// # Example2219///2220/// ```2221/// # use bevy_ecs::prelude::*;2222/// #[derive(Component, Clone)]2223/// struct ComponentA(u32);2224/// #[derive(Component, Clone)]2225/// struct ComponentB(u32);2226///2227/// fn example_system(mut commands: Commands) {2228/// // Create a new entity and store its EntityCommands.2229/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2230///2231/// // Create a clone of the entity with ComponentA but without ComponentB.2232/// let mut entity_clone = entity.clone_and_spawn_with_opt_in(|builder| {2233/// builder.allow::<ComponentA>();2234/// });2235/// }2236/// # bevy_ecs::system::assert_is_system(example_system);2237pub fn clone_and_spawn_with_opt_in(2238&mut self,2239config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,2240) -> EntityCommands<'_> {2241let entity_clone = self.commands().spawn_empty().id();2242self.clone_with_opt_in(entity_clone, config);2243EntityCommands {2244commands: self.commands_mut().reborrow(),2245entity: entity_clone,2246}2247}22482249/// Clones the specified components of this entity and inserts them into another entity.2250///2251/// Components can only be cloned if they implement2252/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).2253///2254/// # Panics2255///2256/// The command will panic when applied if the target entity does not exist.2257pub fn clone_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {2258self.queue(entity_command::clone_components::<B>(target))2259}22602261/// Moves the specified components of this entity into another entity.2262///2263/// Components with [`Ignore`] clone behavior will not be moved, while components that2264/// have a [`Custom`] clone behavior will be cloned using it and then removed from the source entity.2265/// All other components will be moved without any other special handling.2266///2267/// Note that this will trigger `on_remove` hooks/observers on this entity and `on_insert`/`on_add` hooks/observers on the target entity.2268///2269/// # Panics2270///2271/// The command will panic when applied if the target entity does not exist.2272///2273/// [`Ignore`]: crate::component::ComponentCloneBehavior::Ignore2274/// [`Custom`]: crate::component::ComponentCloneBehavior::Custom2275pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {2276self.queue(entity_command::move_components::<B>(target))2277}22782279/// Passes the current entity into the given function, and triggers the [`EntityEvent`] returned by that function.2280///2281/// # Example2282///2283/// A surprising number of functions meet the trait bounds for `event_fn`:2284///2285/// ```rust2286/// # use bevy_ecs::prelude::*;2287///2288/// #[derive(EntityEvent)]2289/// struct Explode(Entity);2290///2291/// impl From<Entity> for Explode {2292/// fn from(entity: Entity) -> Self {2293/// Explode(entity)2294/// }2295/// }2296///2297///2298/// fn trigger_via_constructor(mut commands: Commands) {2299/// // The fact that `Explode` is a single-field tuple struct2300/// // ensures that `Explode(entity)` is a function that generates2301/// // an EntityEvent, meeting the trait bounds for `event_fn`.2302/// commands.spawn_empty().trigger(Explode);2303///2304/// }2305///2306///2307/// fn trigger_via_from_trait(mut commands: Commands) {2308/// // This variant also works for events like `struct Explode { entity: Entity }`2309/// commands.spawn_empty().trigger(Explode::from);2310/// }2311///2312/// fn trigger_via_closure(mut commands: Commands) {2313/// commands.spawn_empty().trigger(|entity| Explode(entity));2314/// }2315/// ```2316#[track_caller]2317pub fn trigger<'t, E: EntityEvent<Trigger<'t>: Default>>(2318&mut self,2319event_fn: impl FnOnce(Entity) -> E,2320) -> &mut Self {2321let event = (event_fn)(self.entity);2322self.commands.trigger(event);2323self2324}2325}23262327/// A wrapper around [`EntityCommands`] with convenience methods for working with a specified component type.2328pub struct EntityEntryCommands<'a, T> {2329entity_commands: EntityCommands<'a>,2330marker: PhantomData<T>,2331}23322333impl<'a, T: Component<Mutability = Mutable>> EntityEntryCommands<'a, T> {2334/// Modify the component `T` if it exists, using the function `modify`.2335pub fn and_modify(&mut self, modify: impl FnOnce(Mut<T>) + Send + Sync + 'static) -> &mut Self {2336self.entity_commands2337.queue(move |mut entity: EntityWorldMut| {2338if let Some(value) = entity.get_mut() {2339modify(value);2340}2341});2342self2343}2344}23452346impl<'a, T: Component> EntityEntryCommands<'a, T> {2347/// [Insert](EntityCommands::insert) `default` into this entity,2348/// if `T` is not already present.2349#[track_caller]2350pub fn or_insert(&mut self, default: T) -> &mut Self {2351self.entity_commands.insert_if_new(default);2352self2353}23542355/// [Insert](EntityCommands::insert) `default` into this entity,2356/// if `T` is not already present.2357///2358/// # Note2359///2360/// If the entity does not exist when this command is executed,2361/// the resulting error will be ignored.2362#[track_caller]2363pub fn or_try_insert(&mut self, default: T) -> &mut Self {2364self.entity_commands.try_insert_if_new(default);2365self2366}23672368/// [Insert](EntityCommands::insert) the value returned from `default` into this entity,2369/// if `T` is not already present.2370///2371/// `default` will only be invoked if the component will actually be inserted.2372#[track_caller]2373pub fn or_insert_with<F>(&mut self, default: F) -> &mut Self2374where2375F: FnOnce() -> T + Send + 'static,2376{2377self.entity_commands2378.queue(entity_command::insert_with(default, InsertMode::Keep));2379self2380}23812382/// [Insert](EntityCommands::insert) the value returned from `default` into this entity,2383/// if `T` is not already present.2384///2385/// `default` will only be invoked if the component will actually be inserted.2386///2387/// # Note2388///2389/// If the entity does not exist when this command is executed,2390/// the resulting error will be ignored.2391#[track_caller]2392pub fn or_try_insert_with<F>(&mut self, default: F) -> &mut Self2393where2394F: FnOnce() -> T + Send + 'static,2395{2396self.entity_commands2397.queue_silenced(entity_command::insert_with(default, InsertMode::Keep));2398self2399}24002401/// [Insert](EntityCommands::insert) `T::default` into this entity,2402/// if `T` is not already present.2403///2404/// `T::default` will only be invoked if the component will actually be inserted.2405#[track_caller]2406pub fn or_default(&mut self) -> &mut Self2407where2408T: Default,2409{2410self.or_insert_with(T::default)2411}24122413/// [Insert](EntityCommands::insert) `T::from_world` into this entity,2414/// if `T` is not already present.2415///2416/// `T::from_world` will only be invoked if the component will actually be inserted.2417#[track_caller]2418pub fn or_from_world(&mut self) -> &mut Self2419where2420T: FromWorld,2421{2422self.entity_commands2423.queue(entity_command::insert_from_world::<T>(InsertMode::Keep));2424self2425}24262427/// Get the [`EntityCommands`] from which the [`EntityEntryCommands`] was initiated.2428///2429/// This allows you to continue chaining method calls after calling [`EntityCommands::entry`].2430///2431/// # Example2432///2433/// ```2434/// # use bevy_ecs::prelude::*;2435/// # #[derive(Resource)]2436/// # struct PlayerEntity { entity: Entity }2437/// #[derive(Component)]2438/// struct Level(u32);2439///2440/// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {2441/// commands2442/// .entity(player.entity)2443/// .entry::<Level>()2444/// // Modify the component if it exists.2445/// .and_modify(|mut lvl| lvl.0 += 1)2446/// // Otherwise, insert a default value.2447/// .or_insert(Level(0))2448/// // Return the EntityCommands for the entity.2449/// .entity()2450/// // Continue chaining method calls.2451/// .insert(Name::new("Player"));2452/// }2453/// # bevy_ecs::system::assert_is_system(level_up_system);2454/// ```2455pub fn entity(&mut self) -> EntityCommands<'_> {2456self.entity_commands.reborrow()2457}2458}24592460#[cfg(test)]2461mod tests {2462use crate::{2463component::Component,2464resource::Resource,2465system::Commands,2466world::{CommandQueue, FromWorld, World},2467};2468use alloc::{string::String, sync::Arc, vec, vec::Vec};2469use core::{2470any::TypeId,2471sync::atomic::{AtomicUsize, Ordering},2472};24732474#[expect(2475dead_code,2476reason = "This struct is used to test how `Drop` behavior works in regards to SparseSet storage, and as such is solely a wrapper around `DropCk` to make it use the SparseSet storage. Because of this, the inner field is intentionally never read."2477)]2478#[derive(Component)]2479#[component(storage = "SparseSet")]2480struct SparseDropCk(DropCk);24812482#[derive(Component)]2483struct DropCk(Arc<AtomicUsize>);2484impl DropCk {2485fn new_pair() -> (Self, Arc<AtomicUsize>) {2486let atomic = Arc::new(AtomicUsize::new(0));2487(DropCk(atomic.clone()), atomic)2488}2489}24902491impl Drop for DropCk {2492fn drop(&mut self) {2493self.0.as_ref().fetch_add(1, Ordering::Relaxed);2494}2495}24962497#[derive(Component)]2498struct W<T>(T);24992500#[derive(Resource)]2501struct V<T>(T);25022503fn simple_command(world: &mut World) {2504world.spawn((W(0u32), W(42u64)));2505}25062507impl FromWorld for W<String> {2508fn from_world(world: &mut World) -> Self {2509let v = world.resource::<V<usize>>();2510Self("*".repeat(v.0))2511}2512}25132514impl Default for W<u8> {2515fn default() -> Self {2516unreachable!()2517}2518}25192520#[test]2521fn entity_commands_entry() {2522let mut world = World::default();2523let mut queue = CommandQueue::default();2524let mut commands = Commands::new(&mut queue, &world);2525let entity = commands.spawn_empty().id();2526commands2527.entity(entity)2528.entry::<W<u32>>()2529.and_modify(|_| unreachable!());2530queue.apply(&mut world);2531assert!(!world.entity(entity).contains::<W<u32>>());2532let mut commands = Commands::new(&mut queue, &world);2533commands2534.entity(entity)2535.entry::<W<u32>>()2536.or_insert(W(0))2537.and_modify(|mut val| {2538val.0 = 21;2539});2540queue.apply(&mut world);2541assert_eq!(21, world.get::<W<u32>>(entity).unwrap().0);2542let mut commands = Commands::new(&mut queue, &world);2543commands2544.entity(entity)2545.entry::<W<u64>>()2546.and_modify(|_| unreachable!())2547.or_insert(W(42));2548queue.apply(&mut world);2549assert_eq!(42, world.get::<W<u64>>(entity).unwrap().0);2550world.insert_resource(V(5_usize));2551let mut commands = Commands::new(&mut queue, &world);2552commands.entity(entity).entry::<W<String>>().or_from_world();2553queue.apply(&mut world);2554assert_eq!("*****", &world.get::<W<String>>(entity).unwrap().0);2555let mut commands = Commands::new(&mut queue, &world);2556let id = commands.entity(entity).entry::<W<u64>>().entity().id();2557queue.apply(&mut world);2558assert_eq!(id, entity);2559let mut commands = Commands::new(&mut queue, &world);2560commands2561.entity(entity)2562.entry::<W<u8>>()2563.or_insert_with(|| W(5))2564.or_insert_with(|| unreachable!())2565.or_try_insert_with(|| unreachable!())2566.or_default()2567.or_from_world();2568queue.apply(&mut world);2569assert_eq!(5, world.get::<W<u8>>(entity).unwrap().0);2570}25712572#[test]2573fn commands() {2574let mut world = World::default();2575let mut command_queue = CommandQueue::default();2576let entity = Commands::new(&mut command_queue, &world)2577.spawn((W(1u32), W(2u64)))2578.id();2579command_queue.apply(&mut world);2580assert_eq!(world.query::<&W<u32>>().query(&world).count(), 1);2581let results = world2582.query::<(&W<u32>, &W<u64>)>()2583.iter(&world)2584.map(|(a, b)| (a.0, b.0))2585.collect::<Vec<_>>();2586assert_eq!(results, vec![(1u32, 2u64)]);2587// test entity despawn2588{2589let mut commands = Commands::new(&mut command_queue, &world);2590commands.entity(entity).despawn();2591commands.entity(entity).despawn(); // double despawn shouldn't panic2592}2593command_queue.apply(&mut world);2594let results2 = world2595.query::<(&W<u32>, &W<u64>)>()2596.iter(&world)2597.map(|(a, b)| (a.0, b.0))2598.collect::<Vec<_>>();2599assert_eq!(results2, vec![]);26002601// test adding simple (FnOnce) commands2602{2603let mut commands = Commands::new(&mut command_queue, &world);26042605// set up a simple command using a closure that adds one additional entity2606commands.queue(|world: &mut World| {2607world.spawn((W(42u32), W(0u64)));2608});26092610// set up a simple command using a function that adds one additional entity2611commands.queue(simple_command);2612}2613command_queue.apply(&mut world);2614let results3 = world2615.query::<(&W<u32>, &W<u64>)>()2616.iter(&world)2617.map(|(a, b)| (a.0, b.0))2618.collect::<Vec<_>>();26192620assert_eq!(results3, vec![(42u32, 0u64), (0u32, 42u64)]);2621}26222623#[test]2624fn insert_components() {2625let mut world = World::default();2626let mut command_queue1 = CommandQueue::default();26272628// insert components2629let entity = Commands::new(&mut command_queue1, &world)2630.spawn(())2631.insert_if(W(1u8), || true)2632.insert_if(W(2u8), || false)2633.insert_if_new(W(1u16))2634.insert_if_new(W(2u16))2635.insert_if_new_and(W(1u32), || false)2636.insert_if_new_and(W(2u32), || true)2637.insert_if_new_and(W(3u32), || true)2638.id();2639command_queue1.apply(&mut world);26402641let results = world2642.query::<(&W<u8>, &W<u16>, &W<u32>)>()2643.iter(&world)2644.map(|(a, b, c)| (a.0, b.0, c.0))2645.collect::<Vec<_>>();2646assert_eq!(results, vec![(1u8, 1u16, 2u32)]);26472648// try to insert components after despawning entity2649// in another command queue2650Commands::new(&mut command_queue1, &world)2651.entity(entity)2652.try_insert_if_new_and(W(1u64), || true);26532654let mut command_queue2 = CommandQueue::default();2655Commands::new(&mut command_queue2, &world)2656.entity(entity)2657.despawn();2658command_queue2.apply(&mut world);2659command_queue1.apply(&mut world);2660}26612662#[test]2663fn remove_components() {2664let mut world = World::default();26652666let mut command_queue = CommandQueue::default();2667let (dense_dropck, dense_is_dropped) = DropCk::new_pair();2668let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();2669let sparse_dropck = SparseDropCk(sparse_dropck);26702671let entity = Commands::new(&mut command_queue, &world)2672.spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))2673.id();2674command_queue.apply(&mut world);2675let results_before = world2676.query::<(&W<u32>, &W<u64>)>()2677.iter(&world)2678.map(|(a, b)| (a.0, b.0))2679.collect::<Vec<_>>();2680assert_eq!(results_before, vec![(1u32, 2u64)]);26812682// test component removal2683Commands::new(&mut command_queue, &world)2684.entity(entity)2685.remove::<W<u32>>()2686.remove::<(W<u32>, W<u64>, SparseDropCk, DropCk)>();26872688assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);2689assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);2690command_queue.apply(&mut world);2691assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);2692assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);26932694let results_after = world2695.query::<(&W<u32>, &W<u64>)>()2696.iter(&world)2697.map(|(a, b)| (a.0, b.0))2698.collect::<Vec<_>>();2699assert_eq!(results_after, vec![]);2700let results_after_u64 = world2701.query::<&W<u64>>()2702.iter(&world)2703.map(|v| v.0)2704.collect::<Vec<_>>();2705assert_eq!(results_after_u64, vec![]);2706}27072708#[test]2709fn remove_components_by_id() {2710let mut world = World::default();27112712let mut command_queue = CommandQueue::default();2713let (dense_dropck, dense_is_dropped) = DropCk::new_pair();2714let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();2715let sparse_dropck = SparseDropCk(sparse_dropck);27162717let entity = Commands::new(&mut command_queue, &world)2718.spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))2719.id();2720command_queue.apply(&mut world);2721let results_before = world2722.query::<(&W<u32>, &W<u64>)>()2723.iter(&world)2724.map(|(a, b)| (a.0, b.0))2725.collect::<Vec<_>>();2726assert_eq!(results_before, vec![(1u32, 2u64)]);27272728// test component removal2729Commands::new(&mut command_queue, &world)2730.entity(entity)2731.remove_by_id(world.components().get_id(TypeId::of::<W<u32>>()).unwrap())2732.remove_by_id(world.components().get_id(TypeId::of::<W<u64>>()).unwrap())2733.remove_by_id(world.components().get_id(TypeId::of::<DropCk>()).unwrap())2734.remove_by_id(2735world2736.components()2737.get_id(TypeId::of::<SparseDropCk>())2738.unwrap(),2739);27402741assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);2742assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);2743command_queue.apply(&mut world);2744assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);2745assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);27462747let results_after = world2748.query::<(&W<u32>, &W<u64>)>()2749.iter(&world)2750.map(|(a, b)| (a.0, b.0))2751.collect::<Vec<_>>();2752assert_eq!(results_after, vec![]);2753let results_after_u64 = world2754.query::<&W<u64>>()2755.iter(&world)2756.map(|v| v.0)2757.collect::<Vec<_>>();2758assert_eq!(results_after_u64, vec![]);2759}27602761#[test]2762fn remove_resources() {2763let mut world = World::default();2764let mut queue = CommandQueue::default();2765{2766let mut commands = Commands::new(&mut queue, &world);2767commands.insert_resource(V(123i32));2768commands.insert_resource(V(456.0f64));2769}27702771queue.apply(&mut world);2772assert!(world.contains_resource::<V<i32>>());2773assert!(world.contains_resource::<V<f64>>());27742775{2776let mut commands = Commands::new(&mut queue, &world);2777// test resource removal2778commands.remove_resource::<V<i32>>();2779}2780queue.apply(&mut world);2781assert!(!world.contains_resource::<V<i32>>());2782assert!(world.contains_resource::<V<f64>>());2783}27842785#[test]2786fn remove_component_with_required_components() {2787#[derive(Component)]2788#[require(Y)]2789struct X;27902791#[derive(Component, Default)]2792struct Y;27932794#[derive(Component)]2795struct Z;27962797let mut world = World::default();2798let mut queue = CommandQueue::default();2799let e = {2800let mut commands = Commands::new(&mut queue, &world);2801commands.spawn((X, Z)).id()2802};2803queue.apply(&mut world);28042805assert!(world.get::<Y>(e).is_some());2806assert!(world.get::<X>(e).is_some());2807assert!(world.get::<Z>(e).is_some());28082809{2810let mut commands = Commands::new(&mut queue, &world);2811commands.entity(e).remove_with_requires::<X>();2812}2813queue.apply(&mut world);28142815assert!(world.get::<Y>(e).is_none());2816assert!(world.get::<X>(e).is_none());28172818assert!(world.get::<Z>(e).is_some());2819}28202821#[test]2822fn unregister_system_cached_commands() {2823let mut world = World::default();2824let mut queue = CommandQueue::default();28252826fn nothing() {}28272828let resources = world.iter_resources().count();2829let id = world.register_system_cached(nothing);2830assert_eq!(world.iter_resources().count(), resources + 1);2831assert!(world.get_entity(id.entity).is_ok());28322833let mut commands = Commands::new(&mut queue, &world);2834commands.unregister_system_cached(nothing);2835queue.apply(&mut world);2836assert_eq!(world.iter_resources().count(), resources);2837assert!(world.get_entity(id.entity).is_err());2838}28392840fn is_send<T: Send>() {}2841fn is_sync<T: Sync>() {}28422843#[test]2844fn test_commands_are_send_and_sync() {2845is_send::<Commands>();2846is_sync::<Commands>();2847}28482849#[test]2850fn append() {2851let mut world = World::default();2852let mut queue_1 = CommandQueue::default();2853{2854let mut commands = Commands::new(&mut queue_1, &world);2855commands.insert_resource(V(123i32));2856}2857let mut queue_2 = CommandQueue::default();2858{2859let mut commands = Commands::new(&mut queue_2, &world);2860commands.insert_resource(V(456.0f64));2861}2862queue_1.append(&mut queue_2);2863queue_1.apply(&mut world);2864assert!(world.contains_resource::<V<i32>>());2865assert!(world.contains_resource::<V<f64>>());2866}28672868#[test]2869fn track_spawn_ticks() {2870let mut world = World::default();2871world.increment_change_tick();2872let expected = world.change_tick();2873let id = world.commands().spawn_empty().id();2874world.flush();2875assert_eq!(2876Some(expected),2877world.entities().entity_get_spawn_or_despawn_tick(id)2878);2879}2880}288128822883