Path: blob/main/crates/bevy_ecs/src/system/commands/mod.rs
6849 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::{Entities, Entity, EntityClonerBuilder, EntityDoesNotExistError, OptIn, OptOut},22error::{warn, BevyError, CommandWithEntity, ErrorContext, HandleError},23event::{EntityEvent, Event},24message::Message,25observer::Observer,26resource::Resource,27schedule::ScheduleLabel,28system::{29Deferred, IntoObserverSystem, IntoSystem, RegisteredSystem, SystemId, SystemInput,30SystemParamValidationError,31},32world::{33command_queue::RawCommandQueue, unsafe_world_cell::UnsafeWorldCell, CommandQueue,34EntityWorldMut, FromWorld, World,35},36};3738/// A [`Command`] queue to perform structural changes to the [`World`].39///40/// Since each command requires exclusive access to the `World`,41/// all queued commands are automatically applied in sequence42/// when the `ApplyDeferred` system runs (see [`ApplyDeferred`] documentation for more details).43///44/// Each command can be used to modify the [`World`] in arbitrary ways:45/// * spawning or despawning entities46/// * inserting components on new or existing entities47/// * inserting resources48/// * etc.49///50/// For a version of [`Commands`] that works in parallel contexts (such as51/// within [`Query::par_iter`](crate::system::Query::par_iter)) see52/// [`ParallelCommands`]53///54/// # Usage55///56/// Add `mut commands: Commands` as a function argument to your system to get a57/// copy of this struct that will be applied the next time a copy of [`ApplyDeferred`] runs.58/// Commands are almost always used as a [`SystemParam`](crate::system::SystemParam).59///60/// ```61/// # use bevy_ecs::prelude::*;62/// fn my_system(mut commands: Commands) {63/// // ...64/// }65/// # bevy_ecs::system::assert_is_system(my_system);66/// ```67///68/// # Implementing69///70/// Each built-in command is implemented as a separate method, e.g. [`Commands::spawn`].71/// In addition to the pre-defined command methods, you can add commands with any arbitrary72/// behavior using [`Commands::queue`], which accepts any type implementing [`Command`].73///74/// Since closures and other functions implement this trait automatically, this allows one-shot,75/// anonymous custom commands.76///77/// ```78/// # use bevy_ecs::prelude::*;79/// # fn foo(mut commands: Commands) {80/// // NOTE: type inference fails here, so annotations are required on the closure.81/// commands.queue(|w: &mut World| {82/// // Mutate the world however you want...83/// });84/// # }85/// ```86///87/// # Error handling88///89/// A [`Command`] can return a [`Result`](crate::error::Result),90/// which will be passed to an [error handler](crate::error) if the `Result` is an error.91///92/// The default error handler panics. It can be configured via93/// the [`DefaultErrorHandler`](crate::error::DefaultErrorHandler) resource.94///95/// Alternatively, you can customize the error handler for a specific command96/// by calling [`Commands::queue_handled`].97///98/// The [`error`](crate::error) module provides some simple error handlers for convenience.99///100/// [`ApplyDeferred`]: crate::schedule::ApplyDeferred101pub struct Commands<'w, 's> {102queue: InternalQueue<'s>,103entities: &'w Entities,104}105106// SAFETY: All commands [`Command`] implement [`Send`]107unsafe impl Send for Commands<'_, '_> {}108109// SAFETY: `Commands` never gives access to the inner commands.110unsafe impl Sync for Commands<'_, '_> {}111112const _: () = {113type __StructFieldsAlias<'w, 's> = (Deferred<'s, CommandQueue>, &'w Entities);114#[doc(hidden)]115pub struct FetchState {116state: <__StructFieldsAlias<'static, 'static> as bevy_ecs::system::SystemParam>::State,117}118// SAFETY: Only reads Entities119unsafe impl bevy_ecs::system::SystemParam for Commands<'_, '_> {120type State = FetchState;121122type Item<'w, 's> = Commands<'w, 's>;123124fn init_state(world: &mut World) -> Self::State {125FetchState {126state: <__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::init_state(127world,128),129}130}131132fn init_access(133state: &Self::State,134system_meta: &mut bevy_ecs::system::SystemMeta,135component_access_set: &mut bevy_ecs::query::FilteredAccessSet,136world: &mut World,137) {138<__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::init_access(139&state.state,140system_meta,141component_access_set,142world,143);144}145146fn apply(147state: &mut Self::State,148system_meta: &bevy_ecs::system::SystemMeta,149world: &mut World,150) {151<__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::apply(152&mut state.state,153system_meta,154world,155);156}157158fn queue(159state: &mut Self::State,160system_meta: &bevy_ecs::system::SystemMeta,161world: bevy_ecs::world::DeferredWorld,162) {163<__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::queue(164&mut state.state,165system_meta,166world,167);168}169170#[inline]171unsafe fn validate_param(172state: &mut Self::State,173system_meta: &bevy_ecs::system::SystemMeta,174world: UnsafeWorldCell,175) -> Result<(), SystemParamValidationError> {176<(Deferred<CommandQueue>, &Entities) as bevy_ecs::system::SystemParam>::validate_param(177&mut state.state,178system_meta,179world,180)181}182183#[inline]184unsafe fn get_param<'w, 's>(185state: &'s mut Self::State,186system_meta: &bevy_ecs::system::SystemMeta,187world: UnsafeWorldCell<'w>,188change_tick: bevy_ecs::component::Tick,189) -> Self::Item<'w, 's> {190let(f0, f1) = <(Deferred<'s, CommandQueue>, &'w Entities) as bevy_ecs::system::SystemParam>::get_param(&mut state.state, system_meta, world, change_tick);191Commands {192queue: InternalQueue::CommandQueue(f0),193entities: f1,194}195}196}197// SAFETY: Only reads Entities198unsafe impl<'w, 's> bevy_ecs::system::ReadOnlySystemParam for Commands<'w, 's>199where200Deferred<'s, CommandQueue>: bevy_ecs::system::ReadOnlySystemParam,201&'w Entities: bevy_ecs::system::ReadOnlySystemParam,202{203}204};205206enum InternalQueue<'s> {207CommandQueue(Deferred<'s, CommandQueue>),208RawCommandQueue(RawCommandQueue),209}210211impl<'w, 's> Commands<'w, 's> {212/// Returns a new `Commands` instance from a [`CommandQueue`] and a [`World`].213pub fn new(queue: &'s mut CommandQueue, world: &'w World) -> Self {214Self::new_from_entities(queue, &world.entities)215}216217/// Returns a new `Commands` instance from a [`CommandQueue`] and an [`Entities`] reference.218pub fn new_from_entities(queue: &'s mut CommandQueue, entities: &'w Entities) -> Self {219Self {220queue: InternalQueue::CommandQueue(Deferred(queue)),221entities,222}223}224225/// Returns a new `Commands` instance from a [`RawCommandQueue`] and an [`Entities`] reference.226///227/// This is used when constructing [`Commands`] from a [`DeferredWorld`](crate::world::DeferredWorld).228///229/// # Safety230///231/// * Caller ensures that `queue` must outlive `'w`232pub(crate) unsafe fn new_raw_from_entities(233queue: RawCommandQueue,234entities: &'w Entities,235) -> Self {236Self {237queue: InternalQueue::RawCommandQueue(queue),238entities,239}240}241242/// Returns a [`Commands`] with a smaller lifetime.243///244/// This is useful if you have `&mut Commands` but need `Commands`.245///246/// # Example247///248/// ```249/// # use bevy_ecs::prelude::*;250/// fn my_system(mut commands: Commands) {251/// // We do our initialization in a separate function,252/// // which expects an owned `Commands`.253/// do_initialization(commands.reborrow());254///255/// // Since we only reborrowed the commands instead of moving them, we can still use them.256/// commands.spawn_empty();257/// }258/// #259/// # fn do_initialization(_: Commands) {}260/// ```261pub fn reborrow(&mut self) -> Commands<'w, '_> {262Commands {263queue: match &mut self.queue {264InternalQueue::CommandQueue(queue) => InternalQueue::CommandQueue(queue.reborrow()),265InternalQueue::RawCommandQueue(queue) => {266InternalQueue::RawCommandQueue(queue.clone())267}268},269entities: self.entities,270}271}272273/// Take all commands from `other` and append them to `self`, leaving `other` empty.274pub fn append(&mut self, other: &mut CommandQueue) {275match &mut self.queue {276InternalQueue::CommandQueue(queue) => queue.bytes.append(&mut other.bytes),277InternalQueue::RawCommandQueue(queue) => {278// SAFETY: Pointers in `RawCommandQueue` are never null279unsafe { queue.bytes.as_mut() }.append(&mut other.bytes);280}281}282}283284/// Spawns a new empty [`Entity`] and returns its corresponding [`EntityCommands`].285///286/// # Example287///288/// ```289/// # use bevy_ecs::prelude::*;290/// #[derive(Component)]291/// struct Label(&'static str);292/// #[derive(Component)]293/// struct Strength(u32);294/// #[derive(Component)]295/// struct Agility(u32);296///297/// fn example_system(mut commands: Commands) {298/// // Create a new empty entity.299/// commands.spawn_empty();300///301/// // Create another empty entity.302/// commands.spawn_empty()303/// // Add a new component bundle to the entity.304/// .insert((Strength(1), Agility(2)))305/// // Add a single component to the entity.306/// .insert(Label("hello world"));307/// }308/// # bevy_ecs::system::assert_is_system(example_system);309/// ```310///311/// # See also312///313/// - [`spawn`](Self::spawn) to spawn an entity with components.314/// - [`spawn_batch`](Self::spawn_batch) to spawn many entities315/// with the same combination of components.316#[track_caller]317pub fn spawn_empty(&mut self) -> EntityCommands<'_> {318let entity = self.entities.reserve_entity();319let mut entity_commands = EntityCommands {320entity,321commands: self.reborrow(),322};323let caller = MaybeLocation::caller();324entity_commands.queue(move |entity: EntityWorldMut| {325let index = entity.id().index();326let world = entity.into_world_mut();327let tick = world.change_tick();328// SAFETY: Entity has been flushed329unsafe {330world.entities_mut().mark_spawn_despawn(index, caller, tick);331}332});333entity_commands334}335336/// Spawns a new [`Entity`] with the given components337/// and returns the entity's corresponding [`EntityCommands`].338///339/// To spawn many entities with the same combination of components,340/// [`spawn_batch`](Self::spawn_batch) can be used for better performance.341///342/// # Example343///344/// ```345/// # use bevy_ecs::prelude::*;346/// #[derive(Component)]347/// struct ComponentA(u32);348/// #[derive(Component)]349/// struct ComponentB(u32);350///351/// #[derive(Bundle)]352/// struct ExampleBundle {353/// a: ComponentA,354/// b: ComponentB,355/// }356///357/// fn example_system(mut commands: Commands) {358/// // Create a new entity with a single component.359/// commands.spawn(ComponentA(1));360///361/// // Create a new entity with two components using a "tuple bundle".362/// commands.spawn((ComponentA(2), ComponentB(1)));363///364/// // Create a new entity with a component bundle.365/// commands.spawn(ExampleBundle {366/// a: ComponentA(3),367/// b: ComponentB(2),368/// });369/// }370/// # bevy_ecs::system::assert_is_system(example_system);371/// ```372///373/// # See also374///375/// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without any components.376/// - [`spawn_batch`](Self::spawn_batch) to spawn many entities377/// with the same combination of components.378#[track_caller]379pub fn spawn<T: Bundle>(&mut self, bundle: T) -> EntityCommands<'_> {380let entity = self.entities.reserve_entity();381let mut entity_commands = EntityCommands {382entity,383commands: self.reborrow(),384};385let caller = MaybeLocation::caller();386387entity_commands.queue(move |mut entity: EntityWorldMut| {388// Store metadata about the spawn operation.389// This is the same as in `spawn_empty`, but merged into390// the same command for better performance.391let index = entity.id().index();392entity.world_scope(|world| {393let tick = world.change_tick();394// SAFETY: Entity has been flushed395unsafe {396world.entities_mut().mark_spawn_despawn(index, caller, tick);397}398});399400move_as_ptr!(bundle);401entity.insert_with_caller(402bundle,403InsertMode::Replace,404caller,405crate::relationship::RelationshipHookMode::Run,406);407});408// entity_command::insert(bundle, InsertMode::Replace)409entity_commands410}411412/// Returns the [`EntityCommands`] for the given [`Entity`].413///414/// This method does not guarantee that commands queued by the returned `EntityCommands`415/// will be successful, since the entity could be despawned before they are executed.416///417/// # Example418///419/// ```420/// # use bevy_ecs::prelude::*;421/// #[derive(Resource)]422/// struct PlayerEntity {423/// entity: Entity424/// }425///426/// #[derive(Component)]427/// struct Label(&'static str);428///429/// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) {430/// // Get the entity and add a component.431/// commands.entity(player.entity).insert(Label("hello world"));432/// }433/// # bevy_ecs::system::assert_is_system(example_system);434/// ```435///436/// # See also437///438/// - [`get_entity`](Self::get_entity) for the fallible version.439#[inline]440#[track_caller]441pub fn entity(&mut self, entity: Entity) -> EntityCommands<'_> {442EntityCommands {443entity,444commands: self.reborrow(),445}446}447448/// Returns the [`EntityCommands`] for the requested [`Entity`] if it exists.449///450/// This method does not guarantee that commands queued by the returned `EntityCommands`451/// will be successful, since the entity could be despawned before they are executed.452///453/// # Errors454///455/// Returns [`EntityDoesNotExistError`] if the requested entity does not exist.456///457/// # Example458///459/// ```460/// # use bevy_ecs::prelude::*;461/// #[derive(Resource)]462/// struct PlayerEntity {463/// entity: Entity464/// }465///466/// #[derive(Component)]467/// struct Label(&'static str);468///469/// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) -> Result {470/// // Get the entity if it still exists and store the `EntityCommands`.471/// // If it doesn't exist, the `?` operator will propagate the returned error472/// // to the system, and the system will pass it to an error handler.473/// let mut entity_commands = commands.get_entity(player.entity)?;474///475/// // Add a component to the entity.476/// entity_commands.insert(Label("hello world"));477///478/// // Return from the system successfully.479/// Ok(())480/// }481/// # bevy_ecs::system::assert_is_system::<(), (), _>(example_system);482/// ```483///484/// # See also485///486/// - [`entity`](Self::entity) for the infallible version.487#[inline]488#[track_caller]489pub fn get_entity(490&mut self,491entity: Entity,492) -> Result<EntityCommands<'_>, EntityDoesNotExistError> {493if self.entities.contains(entity) {494Ok(EntityCommands {495entity,496commands: self.reborrow(),497})498} else {499Err(EntityDoesNotExistError::new(entity, self.entities))500}501}502503/// Spawns multiple entities with the same combination of components,504/// based on a batch of [`Bundles`](Bundle).505///506/// A batch can be any type that implements [`IntoIterator`] and contains bundles,507/// such as a [`Vec<Bundle>`](alloc::vec::Vec) or an array `[Bundle; N]`.508///509/// This method is equivalent to iterating the batch510/// and calling [`spawn`](Self::spawn) for each bundle,511/// but is faster by pre-allocating memory and having exclusive [`World`] access.512///513/// # Example514///515/// ```516/// use bevy_ecs::prelude::*;517///518/// #[derive(Component)]519/// struct Score(u32);520///521/// fn example_system(mut commands: Commands) {522/// commands.spawn_batch([523/// (Name::new("Alice"), Score(0)),524/// (Name::new("Bob"), Score(0)),525/// ]);526/// }527/// # bevy_ecs::system::assert_is_system(example_system);528/// ```529///530/// # See also531///532/// - [`spawn`](Self::spawn) to spawn an entity with components.533/// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without components.534#[track_caller]535pub fn spawn_batch<I>(&mut self, batch: I)536where537I: IntoIterator + Send + Sync + 'static,538I::Item: Bundle<Effect: NoBundleEffect>,539{540self.queue(command::spawn_batch(batch));541}542543/// Pushes a generic [`Command`] to the command queue.544///545/// If the [`Command`] returns a [`Result`],546/// it will be handled using the [default error handler](crate::error::DefaultErrorHandler).547///548/// To use a custom error handler, see [`Commands::queue_handled`].549///550/// The command can be:551/// - A custom struct that implements [`Command`].552/// - A closure or function that matches one of the following signatures:553/// - [`(&mut World)`](World)554/// - A built-in command from the [`command`] module.555///556/// # Example557///558/// ```559/// # use bevy_ecs::prelude::*;560/// #[derive(Resource, Default)]561/// struct Counter(u64);562///563/// struct AddToCounter(String);564///565/// impl Command<Result> for AddToCounter {566/// fn apply(self, world: &mut World) -> Result {567/// let mut counter = world.get_resource_or_insert_with(Counter::default);568/// let amount: u64 = self.0.parse()?;569/// counter.0 += amount;570/// Ok(())571/// }572/// }573///574/// fn add_three_to_counter_system(mut commands: Commands) {575/// commands.queue(AddToCounter("3".to_string()));576/// }577///578/// fn add_twenty_five_to_counter_system(mut commands: Commands) {579/// commands.queue(|world: &mut World| {580/// let mut counter = world.get_resource_or_insert_with(Counter::default);581/// counter.0 += 25;582/// });583/// }584/// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);585/// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);586/// ```587pub fn queue<C: Command<T> + HandleError<T>, T>(&mut self, command: C) {588self.queue_internal(command.handle_error());589}590591/// Pushes a generic [`Command`] to the command queue.592///593/// If the [`Command`] returns a [`Result`],594/// the given `error_handler` will be used to handle error cases.595///596/// To implicitly use the default error handler, see [`Commands::queue`].597///598/// The command can be:599/// - A custom struct that implements [`Command`].600/// - A closure or function that matches one of the following signatures:601/// - [`(&mut World)`](World)602/// - [`(&mut World)`](World) `->` [`Result`]603/// - A built-in command from the [`command`] module.604///605/// # Example606///607/// ```608/// # use bevy_ecs::prelude::*;609/// use bevy_ecs::error::warn;610///611/// #[derive(Resource, Default)]612/// struct Counter(u64);613///614/// struct AddToCounter(String);615///616/// impl Command<Result> for AddToCounter {617/// fn apply(self, world: &mut World) -> Result {618/// let mut counter = world.get_resource_or_insert_with(Counter::default);619/// let amount: u64 = self.0.parse()?;620/// counter.0 += amount;621/// Ok(())622/// }623/// }624///625/// fn add_three_to_counter_system(mut commands: Commands) {626/// commands.queue_handled(AddToCounter("3".to_string()), warn);627/// }628///629/// fn add_twenty_five_to_counter_system(mut commands: Commands) {630/// commands.queue(|world: &mut World| {631/// let mut counter = world.get_resource_or_insert_with(Counter::default);632/// counter.0 += 25;633/// });634/// }635/// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);636/// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);637/// ```638pub fn queue_handled<C: Command<T> + HandleError<T>, T>(639&mut self,640command: C,641error_handler: fn(BevyError, ErrorContext),642) {643self.queue_internal(command.handle_error_with(error_handler));644}645646/// Pushes a generic [`Command`] to the queue like [`Commands::queue_handled`], but instead silently ignores any errors.647pub fn queue_silenced<C: Command<T> + HandleError<T>, T>(&mut self, command: C) {648self.queue_internal(command.ignore_error());649}650651fn queue_internal(&mut self, command: impl Command) {652match &mut self.queue {653InternalQueue::CommandQueue(queue) => {654queue.push(command);655}656InternalQueue::RawCommandQueue(queue) => {657// SAFETY: `RawCommandQueue` is only every constructed in `Commands::new_raw_from_entities`658// where the caller of that has ensured that `queue` outlives `self`659unsafe {660queue.push(command);661}662}663}664}665666/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,667/// based on a batch of `(Entity, Bundle)` pairs.668///669/// A batch can be any type that implements [`IntoIterator`]670/// and contains `(Entity, Bundle)` tuples,671/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)672/// or an array `[(Entity, Bundle); N]`.673///674/// This will overwrite any pre-existing components shared by the [`Bundle`] type.675/// Use [`Commands::insert_batch_if_new`] to keep the pre-existing components instead.676///677/// This method is equivalent to iterating the batch678/// and calling [`insert`](EntityCommands::insert) for each pair,679/// but is faster by caching data that is shared between entities.680///681/// # Fallible682///683/// This command will fail if any of the given entities do not exist.684///685/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),686/// which will be handled by the [default error handler](crate::error::DefaultErrorHandler).687#[track_caller]688pub fn insert_batch<I, B>(&mut self, batch: I)689where690I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,691B: Bundle<Effect: NoBundleEffect>,692{693self.queue(command::insert_batch(batch, InsertMode::Replace));694}695696/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,697/// based on a batch of `(Entity, Bundle)` pairs.698///699/// A batch can be any type that implements [`IntoIterator`]700/// and contains `(Entity, Bundle)` tuples,701/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)702/// or an array `[(Entity, Bundle); N]`.703///704/// This will keep any pre-existing components shared by the [`Bundle`] type705/// and discard the new values.706/// Use [`Commands::insert_batch`] to overwrite the pre-existing components instead.707///708/// This method is equivalent to iterating the batch709/// and calling [`insert_if_new`](EntityCommands::insert_if_new) for each pair,710/// but is faster by caching data that is shared between entities.711///712/// # Fallible713///714/// This command will fail if any of the given entities do not exist.715///716/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),717/// which will be handled by the [default error handler](crate::error::DefaultErrorHandler).718#[track_caller]719pub fn insert_batch_if_new<I, B>(&mut self, batch: I)720where721I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,722B: Bundle<Effect: NoBundleEffect>,723{724self.queue(command::insert_batch(batch, InsertMode::Keep));725}726727/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,728/// based on a batch of `(Entity, Bundle)` pairs.729///730/// A batch can be any type that implements [`IntoIterator`]731/// and contains `(Entity, Bundle)` tuples,732/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)733/// or an array `[(Entity, Bundle); N]`.734///735/// This will overwrite any pre-existing components shared by the [`Bundle`] type.736/// Use [`Commands::try_insert_batch_if_new`] to keep the pre-existing components instead.737///738/// This method is equivalent to iterating the batch739/// and calling [`insert`](EntityCommands::insert) for each pair,740/// but is faster by caching data that is shared between entities.741///742/// # Fallible743///744/// This command will fail if any of the given entities do not exist.745///746/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),747/// which will be handled by [logging the error at the `warn` level](warn).748#[track_caller]749pub fn try_insert_batch<I, B>(&mut self, batch: I)750where751I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,752B: Bundle<Effect: NoBundleEffect>,753{754self.queue(command::insert_batch(batch, InsertMode::Replace).handle_error_with(warn));755}756757/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,758/// based on a batch of `(Entity, Bundle)` pairs.759///760/// A batch can be any type that implements [`IntoIterator`]761/// and contains `(Entity, Bundle)` tuples,762/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)763/// or an array `[(Entity, Bundle); N]`.764///765/// This will keep any pre-existing components shared by the [`Bundle`] type766/// and discard the new values.767/// Use [`Commands::try_insert_batch`] to overwrite the pre-existing components instead.768///769/// This method is equivalent to iterating the batch770/// and calling [`insert_if_new`](EntityCommands::insert_if_new) for each pair,771/// but is faster by caching data that is shared between entities.772///773/// # Fallible774///775/// This command will fail if any of the given entities do not exist.776///777/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),778/// which will be handled by [logging the error at the `warn` level](warn).779#[track_caller]780pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I)781where782I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,783B: Bundle<Effect: NoBundleEffect>,784{785self.queue(command::insert_batch(batch, InsertMode::Keep).handle_error_with(warn));786}787788/// Inserts a [`Resource`] into the [`World`] with an inferred value.789///790/// The inferred value is determined by the [`FromWorld`] trait of the resource.791/// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],792/// and those default values will be used.793///794/// If the resource already exists when the command is applied, nothing happens.795///796/// # Example797///798/// ```799/// # use bevy_ecs::prelude::*;800/// #[derive(Resource, Default)]801/// struct Scoreboard {802/// current_score: u32,803/// high_score: u32,804/// }805///806/// fn initialize_scoreboard(mut commands: Commands) {807/// commands.init_resource::<Scoreboard>();808/// }809/// # bevy_ecs::system::assert_is_system(initialize_scoreboard);810/// ```811#[track_caller]812pub fn init_resource<R: Resource + FromWorld>(&mut self) {813self.queue(command::init_resource::<R>());814}815816/// Inserts a [`Resource`] into the [`World`] with a specific value.817///818/// This will overwrite any previous value of the same resource type.819///820/// # Example821///822/// ```823/// # use bevy_ecs::prelude::*;824/// #[derive(Resource)]825/// struct Scoreboard {826/// current_score: u32,827/// high_score: u32,828/// }829///830/// fn system(mut commands: Commands) {831/// commands.insert_resource(Scoreboard {832/// current_score: 0,833/// high_score: 0,834/// });835/// }836/// # bevy_ecs::system::assert_is_system(system);837/// ```838#[track_caller]839pub fn insert_resource<R: Resource>(&mut self, resource: R) {840self.queue(command::insert_resource(resource));841}842843/// Removes a [`Resource`] from the [`World`].844///845/// # Example846///847/// ```848/// # use bevy_ecs::prelude::*;849/// #[derive(Resource)]850/// struct Scoreboard {851/// current_score: u32,852/// high_score: u32,853/// }854///855/// fn system(mut commands: Commands) {856/// commands.remove_resource::<Scoreboard>();857/// }858/// # bevy_ecs::system::assert_is_system(system);859/// ```860pub fn remove_resource<R: Resource>(&mut self) {861self.queue(command::remove_resource::<R>());862}863864/// Runs the system corresponding to the given [`SystemId`].865/// Before running a system, it must first be registered via866/// [`Commands::register_system`] or [`World::register_system`].867///868/// The system is run in an exclusive and single-threaded way.869/// Running slow systems can become a bottleneck.870///871/// There is no way to get the output of a system when run as a command, because the872/// execution of the system happens later. To get the output of a system, use873/// [`World::run_system`] or [`World::run_system_with`] instead of running the system as a command.874///875/// # Fallible876///877/// This command will fail if the given [`SystemId`]878/// does not correspond to a [`System`](crate::system::System).879///880/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),881/// which will be handled by [logging the error at the `warn` level](warn).882pub fn run_system(&mut self, id: SystemId) {883self.queue(command::run_system(id).handle_error_with(warn));884}885886/// Runs the system corresponding to the given [`SystemId`] with input.887/// Before running a system, it must first be registered via888/// [`Commands::register_system`] or [`World::register_system`].889///890/// The system is run in an exclusive and single-threaded way.891/// Running slow systems can become a bottleneck.892///893/// There is no way to get the output of a system when run as a command, because the894/// execution of the system happens later. To get the output of a system, use895/// [`World::run_system`] or [`World::run_system_with`] instead of running the system as a command.896///897/// # Fallible898///899/// This command will fail if the given [`SystemId`]900/// does not correspond to a [`System`](crate::system::System).901///902/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),903/// which will be handled by [logging the error at the `warn` level](warn).904pub fn run_system_with<I>(&mut self, id: SystemId<I>, input: I::Inner<'static>)905where906I: SystemInput<Inner<'static>: Send> + 'static,907{908self.queue(command::run_system_with(id, input).handle_error_with(warn));909}910911/// Registers a system and returns its [`SystemId`] so it can later be called by912/// [`Commands::run_system`] or [`World::run_system`].913///914/// This is different from adding systems to a [`Schedule`](crate::schedule::Schedule),915/// because the [`SystemId`] that is returned can be used anywhere in the [`World`] to run the associated system.916///917/// Using a [`Schedule`](crate::schedule::Schedule) is still preferred for most cases918/// due to its better performance and ability to run non-conflicting systems simultaneously.919///920/// # Note921///922/// If the same system is registered more than once,923/// each registration will be considered a different system,924/// and they will each be given their own [`SystemId`].925///926/// If you want to avoid registering the same system multiple times,927/// consider using [`Commands::run_system_cached`] or storing the [`SystemId`]928/// in a [`Local`](crate::system::Local).929///930/// # Example931///932/// ```933/// # use bevy_ecs::{prelude::*, world::CommandQueue, system::SystemId};934/// #[derive(Resource)]935/// struct Counter(i32);936///937/// fn register_system(938/// mut commands: Commands,939/// mut local_system: Local<Option<SystemId>>,940/// ) {941/// if let Some(system) = *local_system {942/// commands.run_system(system);943/// } else {944/// *local_system = Some(commands.register_system(increment_counter));945/// }946/// }947///948/// fn increment_counter(mut value: ResMut<Counter>) {949/// value.0 += 1;950/// }951///952/// # let mut world = World::default();953/// # world.insert_resource(Counter(0));954/// # let mut queue_1 = CommandQueue::default();955/// # let systemid = {956/// # let mut commands = Commands::new(&mut queue_1, &world);957/// # commands.register_system(increment_counter)958/// # };959/// # let mut queue_2 = CommandQueue::default();960/// # {961/// # let mut commands = Commands::new(&mut queue_2, &world);962/// # commands.run_system(systemid);963/// # }964/// # queue_1.append(&mut queue_2);965/// # queue_1.apply(&mut world);966/// # assert_eq!(1, world.resource::<Counter>().0);967/// # bevy_ecs::system::assert_is_system(register_system);968/// ```969pub fn register_system<I, O, M>(970&mut self,971system: impl IntoSystem<I, O, M> + 'static,972) -> SystemId<I, O>973where974I: SystemInput + Send + 'static,975O: Send + 'static,976{977let entity = self.spawn_empty().id();978let system = RegisteredSystem::<I, O>::new(Box::new(IntoSystem::into_system(system)));979self.entity(entity).insert(system);980SystemId::from_entity(entity)981}982983/// Removes a system previously registered with [`Commands::register_system`]984/// or [`World::register_system`].985///986/// After removing a system, the [`SystemId`] becomes invalid987/// and attempting to use it afterwards will result in an error.988/// Re-adding the removed system will register it with a new `SystemId`.989///990/// # Fallible991///992/// This command will fail if the given [`SystemId`]993/// does not correspond to a [`System`](crate::system::System).994///995/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),996/// which will be handled by [logging the error at the `warn` level](warn).997pub fn unregister_system<I, O>(&mut self, system_id: SystemId<I, O>)998where999I: SystemInput + Send + 'static,1000O: Send + 'static,1001{1002self.queue(command::unregister_system(system_id).handle_error_with(warn));1003}10041005/// Removes a system previously registered with one of the following:1006/// - [`Commands::run_system_cached`]1007/// - [`World::run_system_cached`]1008/// - [`World::register_system_cached`]1009///1010/// # Fallible1011///1012/// This command will fail if the given system1013/// is not currently cached in a [`CachedSystemId`](crate::system::CachedSystemId) resource.1014///1015/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),1016/// which will be handled by [logging the error at the `warn` level](warn).1017pub fn unregister_system_cached<I, O, M, S>(&mut self, system: S)1018where1019I: SystemInput + Send + 'static,1020O: 'static,1021M: 'static,1022S: IntoSystem<I, O, M> + Send + 'static,1023{1024self.queue(command::unregister_system_cached(system).handle_error_with(warn));1025}10261027/// Runs a cached system, registering it if necessary.1028///1029/// Unlike [`Commands::run_system`], this method does not require manual registration.1030///1031/// The first time this method is called for a particular system,1032/// it will register the system and store its [`SystemId`] in a1033/// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.1034///1035/// If you would rather manage the [`SystemId`] yourself,1036/// or register multiple copies of the same system,1037/// use [`Commands::register_system`] instead.1038///1039/// # Limitations1040///1041/// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of1042/// the same type must be equal. This means that closures that capture the environment, and1043/// function pointers, are not accepted.1044///1045/// If you want to access values from the environment within a system,1046/// consider passing them in as inputs via [`Commands::run_system_cached_with`].1047///1048/// If that's not an option, consider [`Commands::register_system`] instead.1049pub fn run_system_cached<M, S>(&mut self, system: S)1050where1051M: 'static,1052S: IntoSystem<(), (), M> + Send + 'static,1053{1054self.queue(command::run_system_cached(system).handle_error_with(warn));1055}10561057/// Runs a cached system with an input, registering it if necessary.1058///1059/// Unlike [`Commands::run_system_with`], this method does not require manual registration.1060///1061/// The first time this method is called for a particular system,1062/// it will register the system and store its [`SystemId`] in a1063/// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.1064///1065/// If you would rather manage the [`SystemId`] yourself,1066/// or register multiple copies of the same system,1067/// use [`Commands::register_system`] instead.1068///1069/// # Limitations1070///1071/// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of1072/// the same type must be equal. This means that closures that capture the environment, and1073/// function pointers, are not accepted.1074///1075/// If you want to access values from the environment within a system,1076/// consider passing them in as inputs.1077///1078/// If that's not an option, consider [`Commands::register_system`] instead.1079pub fn run_system_cached_with<I, M, S>(&mut self, system: S, input: I::Inner<'static>)1080where1081I: SystemInput<Inner<'static>: Send> + Send + 'static,1082M: 'static,1083S: IntoSystem<I, (), M> + Send + 'static,1084{1085self.queue(command::run_system_cached_with(system, input).handle_error_with(warn));1086}10871088/// Triggers the given [`Event`], which will run any [`Observer`]s watching for it.1089///1090/// [`Observer`]: crate::observer::Observer1091#[track_caller]1092pub fn trigger<'a>(&mut self, event: impl Event<Trigger<'a>: Default>) {1093self.queue(command::trigger(event));1094}10951096/// A deprecated alias for [`trigger`](Self::trigger) to ease migration.1097///1098/// Instead of specifying the trigger target separately,1099/// information about the target of the event is embedded in the data held by1100/// the event type itself.1101#[deprecated(since = "0.17.0", note = "Use `Commands::trigger` instead.")]1102pub fn trigger_targets<'a>(&mut self, event: impl Event<Trigger<'a>: Default>) {1103self.trigger(event);1104}11051106/// Triggers the given [`Event`] using the given [`Trigger`], which will run any [`Observer`]s watching for it.1107///1108/// [`Trigger`]: crate::event::Trigger1109/// [`Observer`]: crate::observer::Observer1110#[track_caller]1111pub fn trigger_with<E: Event<Trigger<'static>: Send + Sync>>(1112&mut self,1113event: E,1114trigger: E::Trigger<'static>,1115) {1116self.queue(command::trigger_with(event, trigger));1117}11181119/// Spawns an [`Observer`] and returns the [`EntityCommands`] associated1120/// with the entity that stores the observer.1121///1122/// `observer` can be any system whose first parameter is [`On`].1123///1124/// **Calling [`observe`](EntityCommands::observe) on the returned1125/// [`EntityCommands`] will observe the observer itself, which you very1126/// likely do not want.**1127///1128/// # Panics1129///1130/// Panics if the given system is an exclusive system.1131///1132/// [`On`]: crate::observer::On1133pub fn add_observer<E: Event, B: Bundle, M>(1134&mut self,1135observer: impl IntoObserverSystem<E, B, M>,1136) -> EntityCommands<'_> {1137self.spawn(Observer::new(observer))1138}11391140/// Writes an arbitrary [`Message`].1141///1142/// This is a convenience method for writing messages1143/// without requiring a [`MessageWriter`](crate::message::MessageWriter).1144///1145/// # Performance1146///1147/// Since this is a command, exclusive world access is used, which means that it will not profit from1148/// system-level parallelism on supported platforms.1149///1150/// If these messages are performance-critical or very frequently sent,1151/// consider using a [`MessageWriter`](crate::message::MessageWriter) instead.1152#[track_caller]1153pub fn write_message<M: Message>(&mut self, message: M) -> &mut Self {1154self.queue(command::write_message(message));1155self1156}11571158/// Writes an arbitrary [`Message`].1159///1160/// This is a convenience method for writing events1161/// without requiring a [`MessageWriter`](crate::message::MessageWriter).1162///1163/// # Performance1164///1165/// Since this is a command, exclusive world access is used, which means that it will not profit from1166/// system-level parallelism on supported platforms.1167///1168/// If these events are performance-critical or very frequently sent,1169/// consider using a typed [`MessageWriter`](crate::message::MessageWriter) instead.1170#[track_caller]1171#[deprecated(since = "0.17.0", note = "Use `Commands::write_message` instead.")]1172pub fn send_event<E: Message>(&mut self, event: E) -> &mut Self {1173self.write_message(event)1174}11751176/// Runs the schedule corresponding to the given [`ScheduleLabel`].1177///1178/// Calls [`World::try_run_schedule`](World::try_run_schedule).1179///1180/// # Fallible1181///1182/// This command will fail if the given [`ScheduleLabel`]1183/// does not correspond to a [`Schedule`](crate::schedule::Schedule).1184///1185/// It will internally return a [`TryRunScheduleError`](crate::world::error::TryRunScheduleError),1186/// which will be handled by [logging the error at the `warn` level](warn).1187///1188/// # Example1189///1190/// ```1191/// # use bevy_ecs::prelude::*;1192/// # use bevy_ecs::schedule::ScheduleLabel;1193/// # #[derive(Default, Resource)]1194/// # struct Counter(u32);1195/// #[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone, Copy)]1196/// struct FooSchedule;1197///1198/// # fn foo_system(mut counter: ResMut<Counter>) {1199/// # counter.0 += 1;1200/// # }1201/// #1202/// # let mut schedule = Schedule::new(FooSchedule);1203/// # schedule.add_systems(foo_system);1204/// #1205/// # let mut world = World::default();1206/// #1207/// # world.init_resource::<Counter>();1208/// # world.add_schedule(schedule);1209/// #1210/// # assert_eq!(world.resource::<Counter>().0, 0);1211/// #1212/// # let mut commands = world.commands();1213/// commands.run_schedule(FooSchedule);1214/// #1215/// # world.flush();1216/// #1217/// # assert_eq!(world.resource::<Counter>().0, 1);1218/// ```1219pub fn run_schedule(&mut self, label: impl ScheduleLabel) {1220self.queue(command::run_schedule(label).handle_error_with(warn));1221}1222}12231224/// A list of commands that will be run to modify an [`Entity`].1225///1226/// # Note1227///1228/// Most [`Commands`] (and thereby [`EntityCommands`]) are deferred:1229/// when you call the command, if it requires mutable access to the [`World`]1230/// (that is, if it removes, adds, or changes something), it's not executed immediately.1231///1232/// Instead, the command is added to a "command queue."1233/// The command queue is applied later1234/// when the [`ApplyDeferred`](crate::schedule::ApplyDeferred) system runs.1235/// Commands are executed one-by-one so that1236/// each command can have exclusive access to the `World`.1237///1238/// # Fallible1239///1240/// Due to their deferred nature, an entity you're trying to change with an [`EntityCommand`]1241/// can be despawned by the time the command is executed.1242///1243/// All deferred entity commands will check whether the entity exists at the time of execution1244/// and will return an error if it doesn't.1245///1246/// # Error handling1247///1248/// An [`EntityCommand`] can return a [`Result`](crate::error::Result),1249/// which will be passed to an [error handler](crate::error) if the `Result` is an error.1250///1251/// The default error handler panics. It can be configured via1252/// the [`DefaultErrorHandler`](crate::error::DefaultErrorHandler) resource.1253///1254/// Alternatively, you can customize the error handler for a specific command1255/// by calling [`EntityCommands::queue_handled`].1256///1257/// The [`error`](crate::error) module provides some simple error handlers for convenience.1258pub struct EntityCommands<'a> {1259pub(crate) entity: Entity,1260pub(crate) commands: Commands<'a, 'a>,1261}12621263impl<'a> EntityCommands<'a> {1264/// Returns the [`Entity`] id of the entity.1265///1266/// # Example1267///1268/// ```1269/// # use bevy_ecs::prelude::*;1270/// #1271/// fn my_system(mut commands: Commands) {1272/// let entity_id = commands.spawn_empty().id();1273/// }1274/// # bevy_ecs::system::assert_is_system(my_system);1275/// ```1276#[inline]1277#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]1278pub fn id(&self) -> Entity {1279self.entity1280}12811282/// Returns an [`EntityCommands`] with a smaller lifetime.1283///1284/// This is useful if you have `&mut EntityCommands` but you need `EntityCommands`.1285pub fn reborrow(&mut self) -> EntityCommands<'_> {1286EntityCommands {1287entity: self.entity,1288commands: self.commands.reborrow(),1289}1290}12911292/// Get an [`EntityEntryCommands`] for the [`Component`] `T`,1293/// allowing you to modify it or insert it if it isn't already present.1294///1295/// See also [`insert_if_new`](Self::insert_if_new),1296/// which lets you insert a [`Bundle`] without overwriting it.1297///1298/// # Example1299///1300/// ```1301/// # use bevy_ecs::prelude::*;1302/// # #[derive(Resource)]1303/// # struct PlayerEntity { entity: Entity }1304/// #[derive(Component)]1305/// struct Level(u32);1306///1307///1308/// #[derive(Component, Default)]1309/// struct Mana {1310/// max: u32,1311/// current: u32,1312/// }1313///1314/// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {1315/// // If a component already exists then modify it, otherwise insert a default value1316/// commands1317/// .entity(player.entity)1318/// .entry::<Level>()1319/// .and_modify(|mut lvl| lvl.0 += 1)1320/// .or_insert(Level(0));1321///1322/// // Add a default value if none exists, and then modify the existing or new value1323/// commands1324/// .entity(player.entity)1325/// .entry::<Mana>()1326/// .or_default()1327/// .and_modify(|mut mana| {1328/// mana.max += 10;1329/// mana.current = mana.max;1330/// });1331/// }1332///1333/// # bevy_ecs::system::assert_is_system(level_up_system);1334/// ```1335pub fn entry<T: Component>(&mut self) -> EntityEntryCommands<'_, T> {1336EntityEntryCommands {1337entity_commands: self.reborrow(),1338marker: PhantomData,1339}1340}13411342/// Adds a [`Bundle`] of components to the entity.1343///1344/// This will overwrite any previous value(s) of the same component type.1345/// See [`EntityCommands::insert_if_new`] to keep the old value instead.1346///1347/// # Example1348///1349/// ```1350/// # use bevy_ecs::prelude::*;1351/// # #[derive(Resource)]1352/// # struct PlayerEntity { entity: Entity }1353/// #[derive(Component)]1354/// struct Health(u32);1355/// #[derive(Component)]1356/// struct Strength(u32);1357/// #[derive(Component)]1358/// struct Defense(u32);1359///1360/// #[derive(Bundle)]1361/// struct CombatBundle {1362/// health: Health,1363/// strength: Strength,1364/// }1365///1366/// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1367/// commands1368/// .entity(player.entity)1369/// // You can insert individual components:1370/// .insert(Defense(10))1371/// // You can also insert pre-defined bundles of components:1372/// .insert(CombatBundle {1373/// health: Health(100),1374/// strength: Strength(40),1375/// })1376/// // You can also insert tuples of components and bundles.1377/// // This is equivalent to the calls above:1378/// .insert((1379/// Defense(10),1380/// CombatBundle {1381/// health: Health(100),1382/// strength: Strength(40),1383/// },1384/// ));1385/// }1386/// # bevy_ecs::system::assert_is_system(add_combat_stats_system);1387/// ```1388#[track_caller]1389pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self {1390self.queue(entity_command::insert(bundle, InsertMode::Replace))1391}13921393/// Adds a [`Bundle`] of components to the entity if the predicate returns true.1394///1395/// This is useful for chaining method calls.1396///1397/// # Example1398///1399/// ```1400/// # use bevy_ecs::prelude::*;1401/// # #[derive(Resource)]1402/// # struct PlayerEntity { entity: Entity }1403/// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }1404/// #[derive(Component)]1405/// struct StillLoadingStats;1406/// #[derive(Component)]1407/// struct Health(u32);1408///1409/// fn add_health_system(mut commands: Commands, player: Res<PlayerEntity>) {1410/// commands1411/// .entity(player.entity)1412/// .insert_if(Health(10), || !player.is_spectator())1413/// .remove::<StillLoadingStats>();1414/// }1415/// # bevy_ecs::system::assert_is_system(add_health_system);1416/// ```1417#[track_caller]1418pub fn insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1419where1420F: FnOnce() -> bool,1421{1422if condition() {1423self.insert(bundle)1424} else {1425self1426}1427}14281429/// Adds a [`Bundle`] of components to the entity without overwriting.1430///1431/// This is the same as [`EntityCommands::insert`], but in case of duplicate1432/// components will leave the old values instead of replacing them with new ones.1433///1434/// See also [`entry`](Self::entry), which lets you modify a [`Component`] if it's present,1435/// as well as initialize it with a default value.1436#[track_caller]1437pub fn insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {1438self.queue(entity_command::insert(bundle, InsertMode::Keep))1439}14401441/// Adds a [`Bundle`] of components to the entity without overwriting if the1442/// predicate returns true.1443///1444/// This is the same as [`EntityCommands::insert_if`], but in case of duplicate1445/// components will leave the old values instead of replacing them with new ones.1446#[track_caller]1447pub fn insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1448where1449F: FnOnce() -> bool,1450{1451if condition() {1452self.insert_if_new(bundle)1453} else {1454self1455}1456}14571458/// Adds a dynamic [`Component`] to the entity.1459///1460/// This will overwrite any previous value(s) of the same component type.1461///1462/// You should prefer to use the typed API [`EntityCommands::insert`] where possible.1463///1464/// # Safety1465///1466/// - [`ComponentId`] must be from the same world as `self`.1467/// - `T` must have the same layout as the one passed during `component_id` creation.1468#[track_caller]1469pub unsafe fn insert_by_id<T: Send + 'static>(1470&mut self,1471component_id: ComponentId,1472value: T,1473) -> &mut Self {1474self.queue(1475// SAFETY:1476// - `ComponentId` safety is ensured by the caller.1477// - `T` safety is ensured by the caller.1478unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },1479)1480}14811482/// Adds a dynamic [`Component`] to the entity.1483///1484/// This will overwrite any previous value(s) of the same component type.1485///1486/// You should prefer to use the typed API [`EntityCommands::try_insert`] where possible.1487///1488/// # Note1489///1490/// If the entity does not exist when this command is executed,1491/// the resulting error will be ignored.1492///1493/// # Safety1494///1495/// - [`ComponentId`] must be from the same world as `self`.1496/// - `T` must have the same layout as the one passed during `component_id` creation.1497#[track_caller]1498pub unsafe fn try_insert_by_id<T: Send + 'static>(1499&mut self,1500component_id: ComponentId,1501value: T,1502) -> &mut Self {1503self.queue_silenced(1504// SAFETY:1505// - `ComponentId` safety is ensured by the caller.1506// - `T` safety is ensured by the caller.1507unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },1508)1509}15101511/// Adds a [`Bundle`] of components to the entity.1512///1513/// This will overwrite any previous value(s) of the same component type.1514///1515/// # Note1516///1517/// If the entity does not exist when this command is executed,1518/// the resulting error will be ignored.1519///1520/// # Example1521///1522/// ```1523/// # use bevy_ecs::prelude::*;1524/// # #[derive(Resource)]1525/// # struct PlayerEntity { entity: Entity }1526/// #[derive(Component)]1527/// struct Health(u32);1528/// #[derive(Component)]1529/// struct Strength(u32);1530/// #[derive(Component)]1531/// struct Defense(u32);1532///1533/// #[derive(Bundle)]1534/// struct CombatBundle {1535/// health: Health,1536/// strength: Strength,1537/// }1538///1539/// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1540/// commands.entity(player.entity)1541/// // You can insert individual components:1542/// .try_insert(Defense(10))1543/// // You can also insert tuples of components:1544/// .try_insert(CombatBundle {1545/// health: Health(100),1546/// strength: Strength(40),1547/// });1548///1549/// // Suppose this occurs in a parallel adjacent system or process.1550/// commands.entity(player.entity).despawn();1551///1552/// // This will not panic nor will it add the component.1553/// commands.entity(player.entity).try_insert(Defense(5));1554/// }1555/// # bevy_ecs::system::assert_is_system(add_combat_stats_system);1556/// ```1557#[track_caller]1558pub fn try_insert(&mut self, bundle: impl Bundle) -> &mut Self {1559self.queue_silenced(entity_command::insert(bundle, InsertMode::Replace))1560}15611562/// Adds a [`Bundle`] of components to the entity if the predicate returns true.1563///1564/// This is useful for chaining method calls.1565///1566/// # Note1567///1568/// If the entity does not exist when this command is executed,1569/// the resulting error will be ignored.1570#[track_caller]1571pub fn try_insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1572where1573F: FnOnce() -> bool,1574{1575if condition() {1576self.try_insert(bundle)1577} else {1578self1579}1580}15811582/// Adds a [`Bundle`] of components to the entity without overwriting if the1583/// predicate returns true.1584///1585/// This is the same as [`EntityCommands::try_insert_if`], but in case of duplicate1586/// components will leave the old values instead of replacing them with new ones.1587///1588/// # Note1589///1590/// If the entity does not exist when this command is executed,1591/// the resulting error will be ignored.1592#[track_caller]1593pub fn try_insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1594where1595F: FnOnce() -> bool,1596{1597if condition() {1598self.try_insert_if_new(bundle)1599} else {1600self1601}1602}16031604/// Adds a [`Bundle`] of components to the entity without overwriting.1605///1606/// This is the same as [`EntityCommands::try_insert`], 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(&mut self, bundle: impl Bundle) -> &mut Self {1615self.queue_silenced(entity_command::insert(bundle, InsertMode::Keep))1616}16171618/// Removes a [`Bundle`] of components from the entity.1619///1620/// This will remove all components that intersect with the provided bundle;1621/// the entity does not need to have all the components in the bundle.1622///1623/// This will emit a warning if the entity does not exist.1624///1625/// # Example1626///1627/// ```1628/// # use bevy_ecs::prelude::*;1629/// # #[derive(Resource)]1630/// # struct PlayerEntity { entity: Entity }1631/// #[derive(Component)]1632/// struct Health(u32);1633/// #[derive(Component)]1634/// struct Strength(u32);1635/// #[derive(Component)]1636/// struct Defense(u32);1637///1638/// #[derive(Bundle)]1639/// struct CombatBundle {1640/// health: Health,1641/// strength: Strength,1642/// }1643///1644/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1645/// commands1646/// .entity(player.entity)1647/// // You can remove individual components:1648/// .remove::<Defense>()1649/// // You can also remove pre-defined bundles of components:1650/// .remove::<CombatBundle>()1651/// // You can also remove tuples of components and bundles.1652/// // This is equivalent to the calls above:1653/// .remove::<(Defense, CombatBundle)>();1654/// }1655/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1656/// ```1657#[track_caller]1658pub fn remove<B: Bundle>(&mut self) -> &mut Self {1659self.queue_handled(entity_command::remove::<B>(), warn)1660}16611662/// Removes a [`Bundle`] of components from the entity if the predicate returns true.1663///1664/// This is useful for chaining method calls.1665///1666/// # Example1667///1668/// ```1669/// # use bevy_ecs::prelude::*;1670/// # #[derive(Resource)]1671/// # struct PlayerEntity { entity: Entity }1672/// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }1673/// #[derive(Component)]1674/// struct Health(u32);1675/// #[derive(Component)]1676/// struct Strength(u32);1677/// #[derive(Component)]1678/// struct Defense(u32);1679///1680/// #[derive(Bundle)]1681/// struct CombatBundle {1682/// health: Health,1683/// strength: Strength,1684/// }1685///1686/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1687/// commands1688/// .entity(player.entity)1689/// .remove_if::<(Defense, CombatBundle)>(|| !player.is_spectator());1690/// }1691/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1692/// ```1693#[track_caller]1694pub fn remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {1695if condition() {1696self.remove::<B>()1697} else {1698self1699}1700}17011702/// Removes a [`Bundle`] of components from the entity if the predicate returns true.1703///1704/// This is useful for chaining method calls.1705///1706/// # Note1707///1708/// If the entity does not exist when this command is executed,1709/// the resulting error will be ignored.1710#[track_caller]1711pub fn try_remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {1712if condition() {1713self.try_remove::<B>()1714} else {1715self1716}1717}17181719/// Removes a [`Bundle`] of components from the entity.1720///1721/// This will remove all components that intersect with the provided bundle;1722/// the entity does not need to have all the components in the bundle.1723///1724/// Unlike [`Self::remove`],1725/// this will not emit a warning if the entity does not exist.1726///1727/// # Example1728///1729/// ```1730/// # use bevy_ecs::prelude::*;1731/// # #[derive(Resource)]1732/// # struct PlayerEntity { entity: Entity }1733/// #[derive(Component)]1734/// struct Health(u32);1735/// #[derive(Component)]1736/// struct Strength(u32);1737/// #[derive(Component)]1738/// struct Defense(u32);1739///1740/// #[derive(Bundle)]1741/// struct CombatBundle {1742/// health: Health,1743/// strength: Strength,1744/// }1745///1746/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1747/// commands1748/// .entity(player.entity)1749/// // You can remove individual components:1750/// .try_remove::<Defense>()1751/// // You can also remove pre-defined bundles of components:1752/// .try_remove::<CombatBundle>()1753/// // You can also remove tuples of components and bundles.1754/// // This is equivalent to the calls above:1755/// .try_remove::<(Defense, CombatBundle)>();1756/// }1757/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1758/// ```1759pub fn try_remove<B: Bundle>(&mut self) -> &mut Self {1760self.queue_silenced(entity_command::remove::<B>())1761}17621763/// Removes a [`Bundle`] of components from the entity,1764/// and also removes any components required by the components in the bundle.1765///1766/// This will remove all components that intersect with the provided bundle;1767/// the entity does not need to have all the components in the bundle.1768///1769/// # Example1770///1771/// ```1772/// # use bevy_ecs::prelude::*;1773/// # #[derive(Resource)]1774/// # struct PlayerEntity { entity: Entity }1775/// #1776/// #[derive(Component)]1777/// #[require(B)]1778/// struct A;1779/// #[derive(Component, Default)]1780/// struct B;1781///1782/// fn remove_with_requires_system(mut commands: Commands, player: Res<PlayerEntity>) {1783/// commands1784/// .entity(player.entity)1785/// // Removes both A and B from the entity, because B is required by A.1786/// .remove_with_requires::<A>();1787/// }1788/// # bevy_ecs::system::assert_is_system(remove_with_requires_system);1789/// ```1790#[track_caller]1791pub fn remove_with_requires<B: Bundle>(&mut self) -> &mut Self {1792self.queue(entity_command::remove_with_requires::<B>())1793}17941795/// Removes a dynamic [`Component`] from the entity if it exists.1796///1797/// # Panics1798///1799/// Panics if the provided [`ComponentId`] does not exist in the [`World`].1800#[track_caller]1801pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {1802self.queue(entity_command::remove_by_id(component_id))1803}18041805/// Removes all components associated with the entity.1806#[track_caller]1807pub fn clear(&mut self) -> &mut Self {1808self.queue(entity_command::clear())1809}18101811/// Despawns the entity.1812///1813/// This will emit a warning if the entity does not exist.1814///1815/// # Note1816///1817/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)1818/// that is configured to despawn descendants.1819///1820/// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1821///1822/// # Example1823///1824/// ```1825/// # use bevy_ecs::prelude::*;1826/// # #[derive(Resource)]1827/// # struct CharacterToRemove { entity: Entity }1828/// #1829/// fn remove_character_system(1830/// mut commands: Commands,1831/// character_to_remove: Res<CharacterToRemove>1832/// ) {1833/// commands.entity(character_to_remove.entity).despawn();1834/// }1835/// # bevy_ecs::system::assert_is_system(remove_character_system);1836/// ```1837#[track_caller]1838pub fn despawn(&mut self) {1839self.queue_handled(entity_command::despawn(), warn);1840}18411842/// Despawns the entity.1843///1844/// Unlike [`Self::despawn`],1845/// this will not emit a warning if the entity does not exist.1846///1847/// # Note1848///1849/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)1850/// that is configured to despawn descendants.1851///1852/// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1853pub fn try_despawn(&mut self) {1854self.queue_silenced(entity_command::despawn());1855}18561857/// Pushes an [`EntityCommand`] to the queue,1858/// which will get executed for the current [`Entity`].1859///1860/// The [default error handler](crate::error::DefaultErrorHandler)1861/// will be used to handle error cases.1862/// Every [`EntityCommand`] checks whether the entity exists at the time of execution1863/// and returns an error if it does not.1864///1865/// To use a custom error handler, see [`EntityCommands::queue_handled`].1866///1867/// The command can be:1868/// - A custom struct that implements [`EntityCommand`].1869/// - A closure or function that matches the following signature:1870/// - [`(EntityWorldMut)`](EntityWorldMut)1871/// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]1872/// - A built-in command from the [`entity_command`] module.1873///1874/// # Example1875///1876/// ```1877/// # use bevy_ecs::prelude::*;1878/// # fn my_system(mut commands: Commands) {1879/// commands1880/// .spawn_empty()1881/// // Closures with this signature implement `EntityCommand`.1882/// .queue(|entity: EntityWorldMut| {1883/// println!("Executed an EntityCommand for {}", entity.id());1884/// });1885/// # }1886/// # bevy_ecs::system::assert_is_system(my_system);1887/// ```1888pub fn queue<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(1889&mut self,1890command: C,1891) -> &mut Self {1892self.commands.queue(command.with_entity(self.entity));1893self1894}18951896/// Pushes an [`EntityCommand`] to the queue,1897/// which will get executed for the current [`Entity`].1898///1899/// The given `error_handler` will be used to handle error cases.1900/// Every [`EntityCommand`] checks whether the entity exists at the time of execution1901/// and returns an error if it does not.1902///1903/// To implicitly use the default error handler, see [`EntityCommands::queue`].1904///1905/// The command can be:1906/// - A custom struct that implements [`EntityCommand`].1907/// - A closure or function that matches the following signature:1908/// - [`(EntityWorldMut)`](EntityWorldMut)1909/// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]1910/// - A built-in command from the [`entity_command`] module.1911///1912/// # Example1913///1914/// ```1915/// # use bevy_ecs::prelude::*;1916/// # fn my_system(mut commands: Commands) {1917/// use bevy_ecs::error::warn;1918///1919/// commands1920/// .spawn_empty()1921/// // Closures with this signature implement `EntityCommand`.1922/// .queue_handled(1923/// |entity: EntityWorldMut| -> Result {1924/// let value: usize = "100".parse()?;1925/// println!("Successfully parsed the value {} for entity {}", value, entity.id());1926/// Ok(())1927/// },1928/// warn1929/// );1930/// # }1931/// # bevy_ecs::system::assert_is_system(my_system);1932/// ```1933pub fn queue_handled<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(1934&mut self,1935command: C,1936error_handler: fn(BevyError, ErrorContext),1937) -> &mut Self {1938self.commands1939.queue_handled(command.with_entity(self.entity), error_handler);1940self1941}19421943/// Pushes an [`EntityCommand`] to the queue, which will get executed for the current [`Entity`].1944///1945/// Unlike [`EntityCommands::queue_handled`], this will completely ignore any errors that occur.1946pub fn queue_silenced<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(1947&mut self,1948command: C,1949) -> &mut Self {1950self.commands1951.queue_silenced(command.with_entity(self.entity));1952self1953}19541955/// Removes all components except the given [`Bundle`] from the entity.1956///1957/// # Example1958///1959/// ```1960/// # use bevy_ecs::prelude::*;1961/// # #[derive(Resource)]1962/// # struct PlayerEntity { entity: Entity }1963/// #[derive(Component)]1964/// struct Health(u32);1965/// #[derive(Component)]1966/// struct Strength(u32);1967/// #[derive(Component)]1968/// struct Defense(u32);1969///1970/// #[derive(Bundle)]1971/// struct CombatBundle {1972/// health: Health,1973/// strength: Strength,1974/// }1975///1976/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1977/// commands1978/// .entity(player.entity)1979/// // You can retain a pre-defined Bundle of components,1980/// // with this removing only the Defense component.1981/// .retain::<CombatBundle>()1982/// // You can also retain only a single component.1983/// .retain::<Health>();1984/// }1985/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1986/// ```1987#[track_caller]1988pub fn retain<B: Bundle>(&mut self) -> &mut Self {1989self.queue(entity_command::retain::<B>())1990}19911992/// Logs the components of the entity at the [`info`](log::info) level.1993pub fn log_components(&mut self) -> &mut Self {1994self.queue(entity_command::log_components())1995}19961997/// Returns the underlying [`Commands`].1998pub fn commands(&mut self) -> Commands<'_, '_> {1999self.commands.reborrow()2000}20012002/// Returns a mutable reference to the underlying [`Commands`].2003pub fn commands_mut(&mut self) -> &mut Commands<'a, 'a> {2004&mut self.commands2005}20062007/// Creates an [`Observer`] watching for an [`EntityEvent`] of type `E` whose [`EntityEvent::event_target`]2008/// targets this entity.2009pub fn observe<E: EntityEvent, B: Bundle, M>(2010&mut self,2011observer: impl IntoObserverSystem<E, B, M>,2012) -> &mut Self {2013self.queue(entity_command::observe(observer))2014}20152016/// Clones parts of an entity (components, observers, etc.) onto another entity,2017/// configured through [`EntityClonerBuilder`].2018///2019/// The other entity will receive all the components of the original that implement2020/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are2021/// [denied](EntityClonerBuilder::deny) in the `config`.2022///2023/// # Panics2024///2025/// The command will panic when applied if the target entity does not exist.2026///2027/// # Example2028///2029/// Configure through [`EntityClonerBuilder<OptOut>`] as follows:2030/// ```2031/// # use bevy_ecs::prelude::*;2032/// #[derive(Component, Clone)]2033/// struct ComponentA(u32);2034/// #[derive(Component, Clone)]2035/// struct ComponentB(u32);2036///2037/// fn example_system(mut commands: Commands) {2038/// // Create an empty entity.2039/// let target = commands.spawn_empty().id();2040///2041/// // Create a new entity and keep its EntityCommands.2042/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2043///2044/// // Clone ComponentA but not ComponentB onto the target.2045/// entity.clone_with_opt_out(target, |builder| {2046/// builder.deny::<ComponentB>();2047/// });2048/// }2049/// # bevy_ecs::system::assert_is_system(example_system);2050/// ```2051///2052/// See [`EntityClonerBuilder`] for more options.2053pub fn clone_with_opt_out(2054&mut self,2055target: Entity,2056config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,2057) -> &mut Self {2058self.queue(entity_command::clone_with_opt_out(target, config))2059}20602061/// Clones parts of an entity (components, observers, etc.) onto another entity,2062/// configured through [`EntityClonerBuilder`].2063///2064/// The other entity will receive only the components of the original that implement2065/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are2066/// [allowed](EntityClonerBuilder::allow) in the `config`.2067///2068/// # Panics2069///2070/// The command will panic when applied if the target entity does not exist.2071///2072/// # Example2073///2074/// Configure through [`EntityClonerBuilder<OptIn>`] as follows:2075/// ```2076/// # use bevy_ecs::prelude::*;2077/// #[derive(Component, Clone)]2078/// struct ComponentA(u32);2079/// #[derive(Component, Clone)]2080/// struct ComponentB(u32);2081///2082/// fn example_system(mut commands: Commands) {2083/// // Create an empty entity.2084/// let target = commands.spawn_empty().id();2085///2086/// // Create a new entity and keep its EntityCommands.2087/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2088///2089/// // Clone ComponentA but not ComponentB onto the target.2090/// entity.clone_with_opt_in(target, |builder| {2091/// builder.allow::<ComponentA>();2092/// });2093/// }2094/// # bevy_ecs::system::assert_is_system(example_system);2095/// ```2096///2097/// See [`EntityClonerBuilder`] for more options.2098pub fn clone_with_opt_in(2099&mut self,2100target: Entity,2101config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,2102) -> &mut Self {2103self.queue(entity_command::clone_with_opt_in(target, config))2104}21052106/// Spawns a clone of this entity and returns the [`EntityCommands`] of the clone.2107///2108/// The clone will receive all the components of the original that implement2109/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).2110///2111/// To configure cloning behavior (such as only cloning certain components),2112/// use [`EntityCommands::clone_and_spawn_with_opt_out`]/2113/// [`opt_out`](EntityCommands::clone_and_spawn_with_opt_out).2114///2115/// # Note2116///2117/// If the original entity does not exist when this command is applied,2118/// the returned entity will have no components.2119///2120/// # Example2121///2122/// ```2123/// # use bevy_ecs::prelude::*;2124/// #[derive(Component, Clone)]2125/// struct ComponentA(u32);2126/// #[derive(Component, Clone)]2127/// struct ComponentB(u32);2128///2129/// fn example_system(mut commands: Commands) {2130/// // Create a new entity and store its EntityCommands.2131/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2132///2133/// // Create a clone of the entity.2134/// let mut entity_clone = entity.clone_and_spawn();2135/// }2136/// # bevy_ecs::system::assert_is_system(example_system);2137pub fn clone_and_spawn(&mut self) -> EntityCommands<'_> {2138self.clone_and_spawn_with_opt_out(|_| {})2139}21402141/// Spawns a clone of this entity and allows configuring cloning behavior2142/// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.2143///2144/// The clone will receive all the components of the original that implement2145/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are2146/// [denied](EntityClonerBuilder::deny) in the `config`.2147///2148/// See the methods on [`EntityClonerBuilder<OptOut>`] for more options.2149///2150/// # Note2151///2152/// If the original entity does not exist when this command is applied,2153/// the returned entity will have no components.2154///2155/// # Example2156///2157/// ```2158/// # use bevy_ecs::prelude::*;2159/// #[derive(Component, Clone)]2160/// struct ComponentA(u32);2161/// #[derive(Component, Clone)]2162/// struct ComponentB(u32);2163///2164/// fn example_system(mut commands: Commands) {2165/// // Create a new entity and store its EntityCommands.2166/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2167///2168/// // Create a clone of the entity with ComponentA but without ComponentB.2169/// let mut entity_clone = entity.clone_and_spawn_with_opt_out(|builder| {2170/// builder.deny::<ComponentB>();2171/// });2172/// }2173/// # bevy_ecs::system::assert_is_system(example_system);2174pub fn clone_and_spawn_with_opt_out(2175&mut self,2176config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,2177) -> EntityCommands<'_> {2178let entity_clone = self.commands().spawn_empty().id();2179self.clone_with_opt_out(entity_clone, config);2180EntityCommands {2181commands: self.commands_mut().reborrow(),2182entity: entity_clone,2183}2184}21852186/// Spawns a clone of this entity and allows configuring cloning behavior2187/// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.2188///2189/// The clone will receive only the components of the original that implement2190/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are2191/// [allowed](EntityClonerBuilder::allow) in the `config`.2192///2193/// See the methods on [`EntityClonerBuilder<OptIn>`] for more options.2194///2195/// # Note2196///2197/// If the original entity does not exist when this command is applied,2198/// the returned entity will have no components.2199///2200/// # Example2201///2202/// ```2203/// # use bevy_ecs::prelude::*;2204/// #[derive(Component, Clone)]2205/// struct ComponentA(u32);2206/// #[derive(Component, Clone)]2207/// struct ComponentB(u32);2208///2209/// fn example_system(mut commands: Commands) {2210/// // Create a new entity and store its EntityCommands.2211/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2212///2213/// // Create a clone of the entity with ComponentA but without ComponentB.2214/// let mut entity_clone = entity.clone_and_spawn_with_opt_in(|builder| {2215/// builder.allow::<ComponentA>();2216/// });2217/// }2218/// # bevy_ecs::system::assert_is_system(example_system);2219pub fn clone_and_spawn_with_opt_in(2220&mut self,2221config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,2222) -> EntityCommands<'_> {2223let entity_clone = self.commands().spawn_empty().id();2224self.clone_with_opt_in(entity_clone, config);2225EntityCommands {2226commands: self.commands_mut().reborrow(),2227entity: entity_clone,2228}2229}22302231/// Clones the specified components of this entity and inserts them into another entity.2232///2233/// Components can only be cloned if they implement2234/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).2235///2236/// # Panics2237///2238/// The command will panic when applied if the target entity does not exist.2239pub fn clone_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {2240self.queue(entity_command::clone_components::<B>(target))2241}22422243/// Moves the specified components of this entity into another entity.2244///2245/// Components with [`Ignore`] clone behavior will not be moved, while components that2246/// have a [`Custom`] clone behavior will be cloned using it and then removed from the source entity.2247/// All other components will be moved without any other special handling.2248///2249/// Note that this will trigger `on_remove` hooks/observers on this entity and `on_insert`/`on_add` hooks/observers on the target entity.2250///2251/// # Panics2252///2253/// The command will panic when applied if the target entity does not exist.2254///2255/// [`Ignore`]: crate::component::ComponentCloneBehavior::Ignore2256/// [`Custom`]: crate::component::ComponentCloneBehavior::Custom2257pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {2258self.queue(entity_command::move_components::<B>(target))2259}22602261/// Deprecated. Use [`Commands::trigger`] instead.2262#[track_caller]2263#[deprecated(2264since = "0.17.0",2265note = "Use Commands::trigger with an EntityEvent instead."2266)]2267pub fn trigger<'t, E: EntityEvent>(2268&mut self,2269event: impl EntityEvent<Trigger<'t>: Default>,2270) -> &mut Self {2271log::warn!("EntityCommands::trigger is deprecated and no longer triggers the event for the current EntityCommands entity. Use Commands::trigger instead with an EntityEvent.");2272self.commands.trigger(event);2273self2274}2275}22762277/// A wrapper around [`EntityCommands`] with convenience methods for working with a specified component type.2278pub struct EntityEntryCommands<'a, T> {2279entity_commands: EntityCommands<'a>,2280marker: PhantomData<T>,2281}22822283impl<'a, T: Component<Mutability = Mutable>> EntityEntryCommands<'a, T> {2284/// Modify the component `T` if it exists, using the function `modify`.2285pub fn and_modify(&mut self, modify: impl FnOnce(Mut<T>) + Send + Sync + 'static) -> &mut Self {2286self.entity_commands2287.queue(move |mut entity: EntityWorldMut| {2288if let Some(value) = entity.get_mut() {2289modify(value);2290}2291});2292self2293}2294}22952296impl<'a, T: Component> EntityEntryCommands<'a, T> {2297/// [Insert](EntityCommands::insert) `default` into this entity,2298/// if `T` is not already present.2299#[track_caller]2300pub fn or_insert(&mut self, default: T) -> &mut Self {2301self.entity_commands.insert_if_new(default);2302self2303}23042305/// [Insert](EntityCommands::insert) `default` into this entity,2306/// if `T` is not already present.2307///2308/// # Note2309///2310/// If the entity does not exist when this command is executed,2311/// the resulting error will be ignored.2312#[track_caller]2313pub fn or_try_insert(&mut self, default: T) -> &mut Self {2314self.entity_commands.try_insert_if_new(default);2315self2316}23172318/// [Insert](EntityCommands::insert) the value returned from `default` into this entity,2319/// if `T` is not already present.2320///2321/// `default` will only be invoked if the component will actually be inserted.2322#[track_caller]2323pub fn or_insert_with<F>(&mut self, default: F) -> &mut Self2324where2325F: FnOnce() -> T + Send + 'static,2326{2327self.entity_commands2328.queue(entity_command::insert_with(default, InsertMode::Keep));2329self2330}23312332/// [Insert](EntityCommands::insert) the value returned from `default` into this entity,2333/// if `T` is not already present.2334///2335/// `default` will only be invoked if the component will actually be inserted.2336///2337/// # Note2338///2339/// If the entity does not exist when this command is executed,2340/// the resulting error will be ignored.2341#[track_caller]2342pub fn or_try_insert_with<F>(&mut self, default: F) -> &mut Self2343where2344F: FnOnce() -> T + Send + 'static,2345{2346self.entity_commands2347.queue_silenced(entity_command::insert_with(default, InsertMode::Keep));2348self2349}23502351/// [Insert](EntityCommands::insert) `T::default` into this entity,2352/// if `T` is not already present.2353///2354/// `T::default` will only be invoked if the component will actually be inserted.2355#[track_caller]2356pub fn or_default(&mut self) -> &mut Self2357where2358T: Default,2359{2360self.or_insert_with(T::default)2361}23622363/// [Insert](EntityCommands::insert) `T::from_world` into this entity,2364/// if `T` is not already present.2365///2366/// `T::from_world` will only be invoked if the component will actually be inserted.2367#[track_caller]2368pub fn or_from_world(&mut self) -> &mut Self2369where2370T: FromWorld,2371{2372self.entity_commands2373.queue(entity_command::insert_from_world::<T>(InsertMode::Keep));2374self2375}23762377/// Get the [`EntityCommands`] from which the [`EntityEntryCommands`] was initiated.2378///2379/// This allows you to continue chaining method calls after calling [`EntityCommands::entry`].2380///2381/// # Example2382///2383/// ```2384/// # use bevy_ecs::prelude::*;2385/// # #[derive(Resource)]2386/// # struct PlayerEntity { entity: Entity }2387/// #[derive(Component)]2388/// struct Level(u32);2389///2390/// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {2391/// commands2392/// .entity(player.entity)2393/// .entry::<Level>()2394/// // Modify the component if it exists.2395/// .and_modify(|mut lvl| lvl.0 += 1)2396/// // Otherwise, insert a default value.2397/// .or_insert(Level(0))2398/// // Return the EntityCommands for the entity.2399/// .entity()2400/// // Continue chaining method calls.2401/// .insert(Name::new("Player"));2402/// }2403/// # bevy_ecs::system::assert_is_system(level_up_system);2404/// ```2405pub fn entity(&mut self) -> EntityCommands<'_> {2406self.entity_commands.reborrow()2407}2408}24092410#[cfg(test)]2411mod tests {2412use crate::{2413component::Component,2414resource::Resource,2415system::Commands,2416world::{CommandQueue, FromWorld, World},2417};2418use alloc::{string::String, sync::Arc, vec, vec::Vec};2419use core::{2420any::TypeId,2421sync::atomic::{AtomicUsize, Ordering},2422};24232424#[expect(2425dead_code,2426reason = "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."2427)]2428#[derive(Component)]2429#[component(storage = "SparseSet")]2430struct SparseDropCk(DropCk);24312432#[derive(Component)]2433struct DropCk(Arc<AtomicUsize>);2434impl DropCk {2435fn new_pair() -> (Self, Arc<AtomicUsize>) {2436let atomic = Arc::new(AtomicUsize::new(0));2437(DropCk(atomic.clone()), atomic)2438}2439}24402441impl Drop for DropCk {2442fn drop(&mut self) {2443self.0.as_ref().fetch_add(1, Ordering::Relaxed);2444}2445}24462447#[derive(Component, Resource)]2448struct W<T>(T);24492450fn simple_command(world: &mut World) {2451world.spawn((W(0u32), W(42u64)));2452}24532454impl FromWorld for W<String> {2455fn from_world(world: &mut World) -> Self {2456let v = world.resource::<W<usize>>();2457Self("*".repeat(v.0))2458}2459}24602461impl Default for W<u8> {2462fn default() -> Self {2463unreachable!()2464}2465}24662467#[test]2468fn entity_commands_entry() {2469let mut world = World::default();2470let mut queue = CommandQueue::default();2471let mut commands = Commands::new(&mut queue, &world);2472let entity = commands.spawn_empty().id();2473commands2474.entity(entity)2475.entry::<W<u32>>()2476.and_modify(|_| unreachable!());2477queue.apply(&mut world);2478assert!(!world.entity(entity).contains::<W<u32>>());2479let mut commands = Commands::new(&mut queue, &world);2480commands2481.entity(entity)2482.entry::<W<u32>>()2483.or_insert(W(0))2484.and_modify(|mut val| {2485val.0 = 21;2486});2487queue.apply(&mut world);2488assert_eq!(21, world.get::<W<u32>>(entity).unwrap().0);2489let mut commands = Commands::new(&mut queue, &world);2490commands2491.entity(entity)2492.entry::<W<u64>>()2493.and_modify(|_| unreachable!())2494.or_insert(W(42));2495queue.apply(&mut world);2496assert_eq!(42, world.get::<W<u64>>(entity).unwrap().0);2497world.insert_resource(W(5_usize));2498let mut commands = Commands::new(&mut queue, &world);2499commands.entity(entity).entry::<W<String>>().or_from_world();2500queue.apply(&mut world);2501assert_eq!("*****", &world.get::<W<String>>(entity).unwrap().0);2502let mut commands = Commands::new(&mut queue, &world);2503let id = commands.entity(entity).entry::<W<u64>>().entity().id();2504queue.apply(&mut world);2505assert_eq!(id, entity);2506let mut commands = Commands::new(&mut queue, &world);2507commands2508.entity(entity)2509.entry::<W<u8>>()2510.or_insert_with(|| W(5))2511.or_insert_with(|| unreachable!())2512.or_try_insert_with(|| unreachable!())2513.or_default()2514.or_from_world();2515queue.apply(&mut world);2516assert_eq!(5, world.get::<W<u8>>(entity).unwrap().0);2517}25182519#[test]2520fn commands() {2521let mut world = World::default();2522let mut command_queue = CommandQueue::default();2523let entity = Commands::new(&mut command_queue, &world)2524.spawn((W(1u32), W(2u64)))2525.id();2526command_queue.apply(&mut world);2527assert_eq!(world.query::<&W<u32>>().query(&world).count(), 1);2528let results = world2529.query::<(&W<u32>, &W<u64>)>()2530.iter(&world)2531.map(|(a, b)| (a.0, b.0))2532.collect::<Vec<_>>();2533assert_eq!(results, vec![(1u32, 2u64)]);2534// test entity despawn2535{2536let mut commands = Commands::new(&mut command_queue, &world);2537commands.entity(entity).despawn();2538commands.entity(entity).despawn(); // double despawn shouldn't panic2539}2540command_queue.apply(&mut world);2541let results2 = world2542.query::<(&W<u32>, &W<u64>)>()2543.iter(&world)2544.map(|(a, b)| (a.0, b.0))2545.collect::<Vec<_>>();2546assert_eq!(results2, vec![]);25472548// test adding simple (FnOnce) commands2549{2550let mut commands = Commands::new(&mut command_queue, &world);25512552// set up a simple command using a closure that adds one additional entity2553commands.queue(|world: &mut World| {2554world.spawn((W(42u32), W(0u64)));2555});25562557// set up a simple command using a function that adds one additional entity2558commands.queue(simple_command);2559}2560command_queue.apply(&mut world);2561let results3 = world2562.query::<(&W<u32>, &W<u64>)>()2563.iter(&world)2564.map(|(a, b)| (a.0, b.0))2565.collect::<Vec<_>>();25662567assert_eq!(results3, vec![(42u32, 0u64), (0u32, 42u64)]);2568}25692570#[test]2571fn insert_components() {2572let mut world = World::default();2573let mut command_queue1 = CommandQueue::default();25742575// insert components2576let entity = Commands::new(&mut command_queue1, &world)2577.spawn(())2578.insert_if(W(1u8), || true)2579.insert_if(W(2u8), || false)2580.insert_if_new(W(1u16))2581.insert_if_new(W(2u16))2582.insert_if_new_and(W(1u32), || false)2583.insert_if_new_and(W(2u32), || true)2584.insert_if_new_and(W(3u32), || true)2585.id();2586command_queue1.apply(&mut world);25872588let results = world2589.query::<(&W<u8>, &W<u16>, &W<u32>)>()2590.iter(&world)2591.map(|(a, b, c)| (a.0, b.0, c.0))2592.collect::<Vec<_>>();2593assert_eq!(results, vec![(1u8, 1u16, 2u32)]);25942595// try to insert components after despawning entity2596// in another command queue2597Commands::new(&mut command_queue1, &world)2598.entity(entity)2599.try_insert_if_new_and(W(1u64), || true);26002601let mut command_queue2 = CommandQueue::default();2602Commands::new(&mut command_queue2, &world)2603.entity(entity)2604.despawn();2605command_queue2.apply(&mut world);2606command_queue1.apply(&mut world);2607}26082609#[test]2610fn remove_components() {2611let mut world = World::default();26122613let mut command_queue = CommandQueue::default();2614let (dense_dropck, dense_is_dropped) = DropCk::new_pair();2615let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();2616let sparse_dropck = SparseDropCk(sparse_dropck);26172618let entity = Commands::new(&mut command_queue, &world)2619.spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))2620.id();2621command_queue.apply(&mut world);2622let results_before = world2623.query::<(&W<u32>, &W<u64>)>()2624.iter(&world)2625.map(|(a, b)| (a.0, b.0))2626.collect::<Vec<_>>();2627assert_eq!(results_before, vec![(1u32, 2u64)]);26282629// test component removal2630Commands::new(&mut command_queue, &world)2631.entity(entity)2632.remove::<W<u32>>()2633.remove::<(W<u32>, W<u64>, SparseDropCk, DropCk)>();26342635assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);2636assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);2637command_queue.apply(&mut world);2638assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);2639assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);26402641let results_after = world2642.query::<(&W<u32>, &W<u64>)>()2643.iter(&world)2644.map(|(a, b)| (a.0, b.0))2645.collect::<Vec<_>>();2646assert_eq!(results_after, vec![]);2647let results_after_u64 = world2648.query::<&W<u64>>()2649.iter(&world)2650.map(|v| v.0)2651.collect::<Vec<_>>();2652assert_eq!(results_after_u64, vec![]);2653}26542655#[test]2656fn remove_components_by_id() {2657let mut world = World::default();26582659let mut command_queue = CommandQueue::default();2660let (dense_dropck, dense_is_dropped) = DropCk::new_pair();2661let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();2662let sparse_dropck = SparseDropCk(sparse_dropck);26632664let entity = Commands::new(&mut command_queue, &world)2665.spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))2666.id();2667command_queue.apply(&mut world);2668let results_before = world2669.query::<(&W<u32>, &W<u64>)>()2670.iter(&world)2671.map(|(a, b)| (a.0, b.0))2672.collect::<Vec<_>>();2673assert_eq!(results_before, vec![(1u32, 2u64)]);26742675// test component removal2676Commands::new(&mut command_queue, &world)2677.entity(entity)2678.remove_by_id(world.components().get_id(TypeId::of::<W<u32>>()).unwrap())2679.remove_by_id(world.components().get_id(TypeId::of::<W<u64>>()).unwrap())2680.remove_by_id(world.components().get_id(TypeId::of::<DropCk>()).unwrap())2681.remove_by_id(2682world2683.components()2684.get_id(TypeId::of::<SparseDropCk>())2685.unwrap(),2686);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_resources() {2710let mut world = World::default();2711let mut queue = CommandQueue::default();2712{2713let mut commands = Commands::new(&mut queue, &world);2714commands.insert_resource(W(123i32));2715commands.insert_resource(W(456.0f64));2716}27172718queue.apply(&mut world);2719assert!(world.contains_resource::<W<i32>>());2720assert!(world.contains_resource::<W<f64>>());27212722{2723let mut commands = Commands::new(&mut queue, &world);2724// test resource removal2725commands.remove_resource::<W<i32>>();2726}2727queue.apply(&mut world);2728assert!(!world.contains_resource::<W<i32>>());2729assert!(world.contains_resource::<W<f64>>());2730}27312732#[test]2733fn remove_component_with_required_components() {2734#[derive(Component)]2735#[require(Y)]2736struct X;27372738#[derive(Component, Default)]2739struct Y;27402741#[derive(Component)]2742struct Z;27432744let mut world = World::default();2745let mut queue = CommandQueue::default();2746let e = {2747let mut commands = Commands::new(&mut queue, &world);2748commands.spawn((X, Z)).id()2749};2750queue.apply(&mut world);27512752assert!(world.get::<Y>(e).is_some());2753assert!(world.get::<X>(e).is_some());2754assert!(world.get::<Z>(e).is_some());27552756{2757let mut commands = Commands::new(&mut queue, &world);2758commands.entity(e).remove_with_requires::<X>();2759}2760queue.apply(&mut world);27612762assert!(world.get::<Y>(e).is_none());2763assert!(world.get::<X>(e).is_none());27642765assert!(world.get::<Z>(e).is_some());2766}27672768#[test]2769fn unregister_system_cached_commands() {2770let mut world = World::default();2771let mut queue = CommandQueue::default();27722773fn nothing() {}27742775let resources = world.iter_resources().count();2776let id = world.register_system_cached(nothing);2777assert_eq!(world.iter_resources().count(), resources + 1);2778assert!(world.get_entity(id.entity).is_ok());27792780let mut commands = Commands::new(&mut queue, &world);2781commands.unregister_system_cached(nothing);2782queue.apply(&mut world);2783assert_eq!(world.iter_resources().count(), resources);2784assert!(world.get_entity(id.entity).is_err());2785}27862787fn is_send<T: Send>() {}2788fn is_sync<T: Sync>() {}27892790#[test]2791fn test_commands_are_send_and_sync() {2792is_send::<Commands>();2793is_sync::<Commands>();2794}27952796#[test]2797fn append() {2798let mut world = World::default();2799let mut queue_1 = CommandQueue::default();2800{2801let mut commands = Commands::new(&mut queue_1, &world);2802commands.insert_resource(W(123i32));2803}2804let mut queue_2 = CommandQueue::default();2805{2806let mut commands = Commands::new(&mut queue_2, &world);2807commands.insert_resource(W(456.0f64));2808}2809queue_1.append(&mut queue_2);2810queue_1.apply(&mut world);2811assert!(world.contains_resource::<W<i32>>());2812assert!(world.contains_resource::<W<f64>>());2813}28142815#[test]2816fn track_spawn_ticks() {2817let mut world = World::default();2818world.increment_change_tick();2819let expected = world.change_tick();2820let id = world.commands().spawn_empty().id();2821world.flush();2822assert_eq!(2823Some(expected),2824world.entities().entity_get_spawn_or_despawn_tick(id)2825);2826}2827}282828292830