Path: blob/main/crates/bevy_ecs/src/system/commands/mod.rs
6609 views
pub mod command;1pub mod entity_command;23#[cfg(feature = "std")]4mod parallel_scope;56pub use command::Command;7pub use entity_command::EntityCommand;89#[cfg(feature = "std")]10pub use parallel_scope::*;1112use alloc::boxed::Box;13use core::marker::PhantomData;1415use crate::{16self as bevy_ecs,17bundle::{Bundle, InsertMode, NoBundleEffect},18change_detection::{MaybeLocation, Mut},19component::{Component, ComponentId, Mutable},20entity::{Entities, Entity, EntityClonerBuilder, EntityDoesNotExistError, OptIn, OptOut},21error::{warn, BevyError, CommandWithEntity, ErrorContext, HandleError},22event::{BufferedEvent, EntityEvent, Event},23observer::Observer,24resource::Resource,25schedule::ScheduleLabel,26system::{27Deferred, IntoObserverSystem, IntoSystem, RegisteredSystem, SystemId, SystemInput,28SystemParamValidationError,29},30world::{31command_queue::RawCommandQueue, unsafe_world_cell::UnsafeWorldCell, CommandQueue,32EntityWorldMut, FromWorld, World,33},34};3536/// A [`Command`] queue to perform structural changes to the [`World`].37///38/// Since each command requires exclusive access to the `World`,39/// all queued commands are automatically applied in sequence40/// when the `ApplyDeferred` system runs (see [`ApplyDeferred`] documentation for more details).41///42/// Each command can be used to modify the [`World`] in arbitrary ways:43/// * spawning or despawning entities44/// * inserting components on new or existing entities45/// * inserting resources46/// * etc.47///48/// For a version of [`Commands`] that works in parallel contexts (such as49/// within [`Query::par_iter`](crate::system::Query::par_iter)) see50/// [`ParallelCommands`]51///52/// # Usage53///54/// Add `mut commands: Commands` as a function argument to your system to get a55/// copy of this struct that will be applied the next time a copy of [`ApplyDeferred`] runs.56/// Commands are almost always used as a [`SystemParam`](crate::system::SystemParam).57///58/// ```59/// # use bevy_ecs::prelude::*;60/// fn my_system(mut commands: Commands) {61/// // ...62/// }63/// # bevy_ecs::system::assert_is_system(my_system);64/// ```65///66/// # Implementing67///68/// Each built-in command is implemented as a separate method, e.g. [`Commands::spawn`].69/// In addition to the pre-defined command methods, you can add commands with any arbitrary70/// behavior using [`Commands::queue`], which accepts any type implementing [`Command`].71///72/// Since closures and other functions implement this trait automatically, this allows one-shot,73/// anonymous custom commands.74///75/// ```76/// # use bevy_ecs::prelude::*;77/// # fn foo(mut commands: Commands) {78/// // NOTE: type inference fails here, so annotations are required on the closure.79/// commands.queue(|w: &mut World| {80/// // Mutate the world however you want...81/// });82/// # }83/// ```84///85/// # Error handling86///87/// A [`Command`] can return a [`Result`](crate::error::Result),88/// which will be passed to an [error handler](crate::error) if the `Result` is an error.89///90/// The default error handler panics. It can be configured via91/// the [`DefaultErrorHandler`](crate::error::DefaultErrorHandler) resource.92///93/// Alternatively, you can customize the error handler for a specific command94/// by calling [`Commands::queue_handled`].95///96/// The [`error`](crate::error) module provides some simple error handlers for convenience.97///98/// [`ApplyDeferred`]: crate::schedule::ApplyDeferred99pub struct Commands<'w, 's> {100queue: InternalQueue<'s>,101entities: &'w Entities,102}103104// SAFETY: All commands [`Command`] implement [`Send`]105unsafe impl Send for Commands<'_, '_> {}106107// SAFETY: `Commands` never gives access to the inner commands.108unsafe impl Sync for Commands<'_, '_> {}109110const _: () = {111type __StructFieldsAlias<'w, 's> = (Deferred<'s, CommandQueue>, &'w Entities);112#[doc(hidden)]113pub struct FetchState {114state: <__StructFieldsAlias<'static, 'static> as bevy_ecs::system::SystemParam>::State,115}116// SAFETY: Only reads Entities117unsafe impl bevy_ecs::system::SystemParam for Commands<'_, '_> {118type State = FetchState;119120type Item<'w, 's> = Commands<'w, 's>;121122fn init_state(world: &mut World) -> Self::State {123FetchState {124state: <__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::init_state(125world,126),127}128}129130fn init_access(131state: &Self::State,132system_meta: &mut bevy_ecs::system::SystemMeta,133component_access_set: &mut bevy_ecs::query::FilteredAccessSet,134world: &mut World,135) {136<__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::init_access(137&state.state,138system_meta,139component_access_set,140world,141);142}143144fn apply(145state: &mut Self::State,146system_meta: &bevy_ecs::system::SystemMeta,147world: &mut World,148) {149<__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::apply(150&mut state.state,151system_meta,152world,153);154}155156fn queue(157state: &mut Self::State,158system_meta: &bevy_ecs::system::SystemMeta,159world: bevy_ecs::world::DeferredWorld,160) {161<__StructFieldsAlias<'_, '_> as bevy_ecs::system::SystemParam>::queue(162&mut state.state,163system_meta,164world,165);166}167168#[inline]169unsafe fn validate_param(170state: &mut Self::State,171system_meta: &bevy_ecs::system::SystemMeta,172world: UnsafeWorldCell,173) -> Result<(), SystemParamValidationError> {174<(Deferred<CommandQueue>, &Entities) as bevy_ecs::system::SystemParam>::validate_param(175&mut state.state,176system_meta,177world,178)179}180181#[inline]182unsafe fn get_param<'w, 's>(183state: &'s mut Self::State,184system_meta: &bevy_ecs::system::SystemMeta,185world: UnsafeWorldCell<'w>,186change_tick: bevy_ecs::component::Tick,187) -> Self::Item<'w, 's> {188let(f0, f1) = <(Deferred<'s, CommandQueue>, &'w Entities) as bevy_ecs::system::SystemParam>::get_param(&mut state.state, system_meta, world, change_tick);189Commands {190queue: InternalQueue::CommandQueue(f0),191entities: f1,192}193}194}195// SAFETY: Only reads Entities196unsafe impl<'w, 's> bevy_ecs::system::ReadOnlySystemParam for Commands<'w, 's>197where198Deferred<'s, CommandQueue>: bevy_ecs::system::ReadOnlySystemParam,199&'w Entities: bevy_ecs::system::ReadOnlySystemParam,200{201}202};203204enum InternalQueue<'s> {205CommandQueue(Deferred<'s, CommandQueue>),206RawCommandQueue(RawCommandQueue),207}208209impl<'w, 's> Commands<'w, 's> {210/// Returns a new `Commands` instance from a [`CommandQueue`] and a [`World`].211pub fn new(queue: &'s mut CommandQueue, world: &'w World) -> Self {212Self::new_from_entities(queue, &world.entities)213}214215/// Returns a new `Commands` instance from a [`CommandQueue`] and an [`Entities`] reference.216pub fn new_from_entities(queue: &'s mut CommandQueue, entities: &'w Entities) -> Self {217Self {218queue: InternalQueue::CommandQueue(Deferred(queue)),219entities,220}221}222223/// Returns a new `Commands` instance from a [`RawCommandQueue`] and an [`Entities`] reference.224///225/// This is used when constructing [`Commands`] from a [`DeferredWorld`](crate::world::DeferredWorld).226///227/// # Safety228///229/// * Caller ensures that `queue` must outlive `'w`230pub(crate) unsafe fn new_raw_from_entities(231queue: RawCommandQueue,232entities: &'w Entities,233) -> Self {234Self {235queue: InternalQueue::RawCommandQueue(queue),236entities,237}238}239240/// Returns a [`Commands`] with a smaller lifetime.241///242/// This is useful if you have `&mut Commands` but need `Commands`.243///244/// # Example245///246/// ```247/// # use bevy_ecs::prelude::*;248/// fn my_system(mut commands: Commands) {249/// // We do our initialization in a separate function,250/// // which expects an owned `Commands`.251/// do_initialization(commands.reborrow());252///253/// // Since we only reborrowed the commands instead of moving them, we can still use them.254/// commands.spawn_empty();255/// }256/// #257/// # fn do_initialization(_: Commands) {}258/// ```259pub fn reborrow(&mut self) -> Commands<'w, '_> {260Commands {261queue: match &mut self.queue {262InternalQueue::CommandQueue(queue) => InternalQueue::CommandQueue(queue.reborrow()),263InternalQueue::RawCommandQueue(queue) => {264InternalQueue::RawCommandQueue(queue.clone())265}266},267entities: self.entities,268}269}270271/// Take all commands from `other` and append them to `self`, leaving `other` empty.272pub fn append(&mut self, other: &mut CommandQueue) {273match &mut self.queue {274InternalQueue::CommandQueue(queue) => queue.bytes.append(&mut other.bytes),275InternalQueue::RawCommandQueue(queue) => {276// SAFETY: Pointers in `RawCommandQueue` are never null277unsafe { queue.bytes.as_mut() }.append(&mut other.bytes);278}279}280}281282/// Spawns a new empty [`Entity`] and returns its corresponding [`EntityCommands`].283///284/// # Example285///286/// ```287/// # use bevy_ecs::prelude::*;288/// #[derive(Component)]289/// struct Label(&'static str);290/// #[derive(Component)]291/// struct Strength(u32);292/// #[derive(Component)]293/// struct Agility(u32);294///295/// fn example_system(mut commands: Commands) {296/// // Create a new empty entity.297/// commands.spawn_empty();298///299/// // Create another empty entity.300/// commands.spawn_empty()301/// // Add a new component bundle to the entity.302/// .insert((Strength(1), Agility(2)))303/// // Add a single component to the entity.304/// .insert(Label("hello world"));305/// }306/// # bevy_ecs::system::assert_is_system(example_system);307/// ```308///309/// # See also310///311/// - [`spawn`](Self::spawn) to spawn an entity with components.312/// - [`spawn_batch`](Self::spawn_batch) to spawn many entities313/// with the same combination of components.314#[track_caller]315pub fn spawn_empty(&mut self) -> EntityCommands<'_> {316let entity = self.entities.reserve_entity();317let mut entity_commands = EntityCommands {318entity,319commands: self.reborrow(),320};321let caller = MaybeLocation::caller();322entity_commands.queue(move |entity: EntityWorldMut| {323let index = entity.id().index();324let world = entity.into_world_mut();325let tick = world.change_tick();326// SAFETY: Entity has been flushed327unsafe {328world.entities_mut().mark_spawn_despawn(index, caller, tick);329}330});331entity_commands332}333334/// Spawns a new [`Entity`] with the given components335/// and returns the entity's corresponding [`EntityCommands`].336///337/// To spawn many entities with the same combination of components,338/// [`spawn_batch`](Self::spawn_batch) can be used for better performance.339///340/// # Example341///342/// ```343/// # use bevy_ecs::prelude::*;344/// #[derive(Component)]345/// struct ComponentA(u32);346/// #[derive(Component)]347/// struct ComponentB(u32);348///349/// #[derive(Bundle)]350/// struct ExampleBundle {351/// a: ComponentA,352/// b: ComponentB,353/// }354///355/// fn example_system(mut commands: Commands) {356/// // Create a new entity with a single component.357/// commands.spawn(ComponentA(1));358///359/// // Create a new entity with two components using a "tuple bundle".360/// commands.spawn((ComponentA(2), ComponentB(1)));361///362/// // Create a new entity with a component bundle.363/// commands.spawn(ExampleBundle {364/// a: ComponentA(3),365/// b: ComponentB(2),366/// });367/// }368/// # bevy_ecs::system::assert_is_system(example_system);369/// ```370///371/// # See also372///373/// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without any components.374/// - [`spawn_batch`](Self::spawn_batch) to spawn many entities375/// with the same combination of components.376#[track_caller]377pub fn spawn<T: Bundle>(&mut self, bundle: T) -> EntityCommands<'_> {378let entity = self.entities.reserve_entity();379let mut entity_commands = EntityCommands {380entity,381commands: self.reborrow(),382};383let caller = MaybeLocation::caller();384385entity_commands.queue(move |mut entity: EntityWorldMut| {386// Store metadata about the spawn operation.387// This is the same as in `spawn_empty`, but merged into388// the same command for better performance.389let index = entity.id().index();390entity.world_scope(|world| {391let tick = world.change_tick();392// SAFETY: Entity has been flushed393unsafe {394world.entities_mut().mark_spawn_despawn(index, caller, tick);395}396});397398entity.insert_with_caller(399bundle,400InsertMode::Replace,401caller,402crate::relationship::RelationshipHookMode::Run,403);404});405// entity_command::insert(bundle, InsertMode::Replace)406entity_commands407}408409/// Returns the [`EntityCommands`] for the given [`Entity`].410///411/// This method does not guarantee that commands queued by the returned `EntityCommands`412/// will be successful, since the entity could be despawned before they are executed.413///414/// # Example415///416/// ```417/// # use bevy_ecs::prelude::*;418/// #[derive(Resource)]419/// struct PlayerEntity {420/// entity: Entity421/// }422///423/// #[derive(Component)]424/// struct Label(&'static str);425///426/// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) {427/// // Get the entity and add a component.428/// commands.entity(player.entity).insert(Label("hello world"));429/// }430/// # bevy_ecs::system::assert_is_system(example_system);431/// ```432///433/// # See also434///435/// - [`get_entity`](Self::get_entity) for the fallible version.436#[inline]437#[track_caller]438pub fn entity(&mut self, entity: Entity) -> EntityCommands<'_> {439EntityCommands {440entity,441commands: self.reborrow(),442}443}444445/// Returns the [`EntityCommands`] for the requested [`Entity`] if it exists.446///447/// This method does not guarantee that commands queued by the returned `EntityCommands`448/// will be successful, since the entity could be despawned before they are executed.449///450/// # Errors451///452/// Returns [`EntityDoesNotExistError`] if the requested entity does not exist.453///454/// # Example455///456/// ```457/// # use bevy_ecs::prelude::*;458/// #[derive(Resource)]459/// struct PlayerEntity {460/// entity: Entity461/// }462///463/// #[derive(Component)]464/// struct Label(&'static str);465///466/// fn example_system(mut commands: Commands, player: Res<PlayerEntity>) -> Result {467/// // Get the entity if it still exists and store the `EntityCommands`.468/// // If it doesn't exist, the `?` operator will propagate the returned error469/// // to the system, and the system will pass it to an error handler.470/// let mut entity_commands = commands.get_entity(player.entity)?;471///472/// // Add a component to the entity.473/// entity_commands.insert(Label("hello world"));474///475/// // Return from the system successfully.476/// Ok(())477/// }478/// # bevy_ecs::system::assert_is_system::<(), (), _>(example_system);479/// ```480///481/// # See also482///483/// - [`entity`](Self::entity) for the infallible version.484#[inline]485#[track_caller]486pub fn get_entity(487&mut self,488entity: Entity,489) -> Result<EntityCommands<'_>, EntityDoesNotExistError> {490if self.entities.contains(entity) {491Ok(EntityCommands {492entity,493commands: self.reborrow(),494})495} else {496Err(EntityDoesNotExistError::new(entity, self.entities))497}498}499500/// Spawns multiple entities with the same combination of components,501/// based on a batch of [`Bundles`](Bundle).502///503/// A batch can be any type that implements [`IntoIterator`] and contains bundles,504/// such as a [`Vec<Bundle>`](alloc::vec::Vec) or an array `[Bundle; N]`.505///506/// This method is equivalent to iterating the batch507/// and calling [`spawn`](Self::spawn) for each bundle,508/// but is faster by pre-allocating memory and having exclusive [`World`] access.509///510/// # Example511///512/// ```513/// use bevy_ecs::prelude::*;514///515/// #[derive(Component)]516/// struct Score(u32);517///518/// fn example_system(mut commands: Commands) {519/// commands.spawn_batch([520/// (Name::new("Alice"), Score(0)),521/// (Name::new("Bob"), Score(0)),522/// ]);523/// }524/// # bevy_ecs::system::assert_is_system(example_system);525/// ```526///527/// # See also528///529/// - [`spawn`](Self::spawn) to spawn an entity with components.530/// - [`spawn_empty`](Self::spawn_empty) to spawn an entity without components.531#[track_caller]532pub fn spawn_batch<I>(&mut self, batch: I)533where534I: IntoIterator + Send + Sync + 'static,535I::Item: Bundle<Effect: NoBundleEffect>,536{537self.queue(command::spawn_batch(batch));538}539540/// Pushes a generic [`Command`] to the command queue.541///542/// If the [`Command`] returns a [`Result`],543/// it will be handled using the [default error handler](crate::error::DefaultErrorHandler).544///545/// To use a custom error handler, see [`Commands::queue_handled`].546///547/// The command can be:548/// - A custom struct that implements [`Command`].549/// - A closure or function that matches one of the following signatures:550/// - [`(&mut World)`](World)551/// - A built-in command from the [`command`] module.552///553/// # Example554///555/// ```556/// # use bevy_ecs::prelude::*;557/// #[derive(Resource, Default)]558/// struct Counter(u64);559///560/// struct AddToCounter(String);561///562/// impl Command<Result> for AddToCounter {563/// fn apply(self, world: &mut World) -> Result {564/// let mut counter = world.get_resource_or_insert_with(Counter::default);565/// let amount: u64 = self.0.parse()?;566/// counter.0 += amount;567/// Ok(())568/// }569/// }570///571/// fn add_three_to_counter_system(mut commands: Commands) {572/// commands.queue(AddToCounter("3".to_string()));573/// }574///575/// fn add_twenty_five_to_counter_system(mut commands: Commands) {576/// commands.queue(|world: &mut World| {577/// let mut counter = world.get_resource_or_insert_with(Counter::default);578/// counter.0 += 25;579/// });580/// }581/// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);582/// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);583/// ```584pub fn queue<C: Command<T> + HandleError<T>, T>(&mut self, command: C) {585self.queue_internal(command.handle_error());586}587588/// Pushes a generic [`Command`] to the command queue.589///590/// If the [`Command`] returns a [`Result`],591/// the given `error_handler` will be used to handle error cases.592///593/// To implicitly use the default error handler, see [`Commands::queue`].594///595/// The command can be:596/// - A custom struct that implements [`Command`].597/// - A closure or function that matches one of the following signatures:598/// - [`(&mut World)`](World)599/// - [`(&mut World)`](World) `->` [`Result`]600/// - A built-in command from the [`command`] module.601///602/// # Example603///604/// ```605/// # use bevy_ecs::prelude::*;606/// use bevy_ecs::error::warn;607///608/// #[derive(Resource, Default)]609/// struct Counter(u64);610///611/// struct AddToCounter(String);612///613/// impl Command<Result> for AddToCounter {614/// fn apply(self, world: &mut World) -> Result {615/// let mut counter = world.get_resource_or_insert_with(Counter::default);616/// let amount: u64 = self.0.parse()?;617/// counter.0 += amount;618/// Ok(())619/// }620/// }621///622/// fn add_three_to_counter_system(mut commands: Commands) {623/// commands.queue_handled(AddToCounter("3".to_string()), warn);624/// }625///626/// fn add_twenty_five_to_counter_system(mut commands: Commands) {627/// commands.queue(|world: &mut World| {628/// let mut counter = world.get_resource_or_insert_with(Counter::default);629/// counter.0 += 25;630/// });631/// }632/// # bevy_ecs::system::assert_is_system(add_three_to_counter_system);633/// # bevy_ecs::system::assert_is_system(add_twenty_five_to_counter_system);634/// ```635pub fn queue_handled<C: Command<T> + HandleError<T>, T>(636&mut self,637command: C,638error_handler: fn(BevyError, ErrorContext),639) {640self.queue_internal(command.handle_error_with(error_handler));641}642643/// Pushes a generic [`Command`] to the queue like [`Commands::queue_handled`], but instead silently ignores any errors.644pub fn queue_silenced<C: Command<T> + HandleError<T>, T>(&mut self, command: C) {645self.queue_internal(command.ignore_error());646}647648fn queue_internal(&mut self, command: impl Command) {649match &mut self.queue {650InternalQueue::CommandQueue(queue) => {651queue.push(command);652}653InternalQueue::RawCommandQueue(queue) => {654// SAFETY: `RawCommandQueue` is only every constructed in `Commands::new_raw_from_entities`655// where the caller of that has ensured that `queue` outlives `self`656unsafe {657queue.push(command);658}659}660}661}662663/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,664/// based on a batch of `(Entity, Bundle)` pairs.665///666/// A batch can be any type that implements [`IntoIterator`]667/// and contains `(Entity, Bundle)` tuples,668/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)669/// or an array `[(Entity, Bundle); N]`.670///671/// This will overwrite any pre-existing components shared by the [`Bundle`] type.672/// Use [`Commands::insert_batch_if_new`] to keep the pre-existing components instead.673///674/// This method is equivalent to iterating the batch675/// and calling [`insert`](EntityCommands::insert) for each pair,676/// but is faster by caching data that is shared between entities.677///678/// # Fallible679///680/// This command will fail if any of the given entities do not exist.681///682/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),683/// which will be handled by the [default error handler](crate::error::DefaultErrorHandler).684#[track_caller]685pub fn insert_batch<I, B>(&mut self, batch: I)686where687I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,688B: Bundle<Effect: NoBundleEffect>,689{690self.queue(command::insert_batch(batch, InsertMode::Replace));691}692693/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,694/// based on a batch of `(Entity, Bundle)` pairs.695///696/// A batch can be any type that implements [`IntoIterator`]697/// and contains `(Entity, Bundle)` tuples,698/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)699/// or an array `[(Entity, Bundle); N]`.700///701/// This will keep any pre-existing components shared by the [`Bundle`] type702/// and discard the new values.703/// Use [`Commands::insert_batch`] to overwrite the pre-existing components instead.704///705/// This method is equivalent to iterating the batch706/// and calling [`insert_if_new`](EntityCommands::insert_if_new) for each pair,707/// but is faster by caching data that is shared between entities.708///709/// # Fallible710///711/// This command will fail if any of the given entities do not exist.712///713/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),714/// which will be handled by the [default error handler](crate::error::DefaultErrorHandler).715#[track_caller]716pub fn insert_batch_if_new<I, B>(&mut self, batch: I)717where718I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,719B: Bundle<Effect: NoBundleEffect>,720{721self.queue(command::insert_batch(batch, InsertMode::Keep));722}723724/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,725/// based on a batch of `(Entity, Bundle)` pairs.726///727/// A batch can be any type that implements [`IntoIterator`]728/// and contains `(Entity, Bundle)` tuples,729/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)730/// or an array `[(Entity, Bundle); N]`.731///732/// This will overwrite any pre-existing components shared by the [`Bundle`] type.733/// Use [`Commands::try_insert_batch_if_new`] to keep the pre-existing components instead.734///735/// This method is equivalent to iterating the batch736/// and calling [`insert`](EntityCommands::insert) for each pair,737/// but is faster by caching data that is shared between entities.738///739/// # Fallible740///741/// This command will fail if any of the given entities do not exist.742///743/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),744/// which will be handled by [logging the error at the `warn` level](warn).745#[track_caller]746pub fn try_insert_batch<I, B>(&mut self, batch: I)747where748I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,749B: Bundle<Effect: NoBundleEffect>,750{751self.queue(command::insert_batch(batch, InsertMode::Replace).handle_error_with(warn));752}753754/// Adds a series of [`Bundles`](Bundle) to each [`Entity`] they are paired with,755/// based on a batch of `(Entity, Bundle)` pairs.756///757/// A batch can be any type that implements [`IntoIterator`]758/// and contains `(Entity, Bundle)` tuples,759/// such as a [`Vec<(Entity, Bundle)>`](alloc::vec::Vec)760/// or an array `[(Entity, Bundle); N]`.761///762/// This will keep any pre-existing components shared by the [`Bundle`] type763/// and discard the new values.764/// Use [`Commands::try_insert_batch`] to overwrite the pre-existing components instead.765///766/// This method is equivalent to iterating the batch767/// and calling [`insert_if_new`](EntityCommands::insert_if_new) for each pair,768/// but is faster by caching data that is shared between entities.769///770/// # Fallible771///772/// This command will fail if any of the given entities do not exist.773///774/// It will internally return a [`TryInsertBatchError`](crate::world::error::TryInsertBatchError),775/// which will be handled by [logging the error at the `warn` level](warn).776#[track_caller]777pub fn try_insert_batch_if_new<I, B>(&mut self, batch: I)778where779I: IntoIterator<Item = (Entity, B)> + Send + Sync + 'static,780B: Bundle<Effect: NoBundleEffect>,781{782self.queue(command::insert_batch(batch, InsertMode::Keep).handle_error_with(warn));783}784785/// Inserts a [`Resource`] into the [`World`] with an inferred value.786///787/// The inferred value is determined by the [`FromWorld`] trait of the resource.788/// Note that any resource with the [`Default`] trait automatically implements [`FromWorld`],789/// and those default values will be used.790///791/// If the resource already exists when the command is applied, nothing happens.792///793/// # Example794///795/// ```796/// # use bevy_ecs::prelude::*;797/// #[derive(Resource, Default)]798/// struct Scoreboard {799/// current_score: u32,800/// high_score: u32,801/// }802///803/// fn initialize_scoreboard(mut commands: Commands) {804/// commands.init_resource::<Scoreboard>();805/// }806/// # bevy_ecs::system::assert_is_system(initialize_scoreboard);807/// ```808#[track_caller]809pub fn init_resource<R: Resource + FromWorld>(&mut self) {810self.queue(command::init_resource::<R>());811}812813/// Inserts a [`Resource`] into the [`World`] with a specific value.814///815/// This will overwrite any previous value of the same resource type.816///817/// # Example818///819/// ```820/// # use bevy_ecs::prelude::*;821/// #[derive(Resource)]822/// struct Scoreboard {823/// current_score: u32,824/// high_score: u32,825/// }826///827/// fn system(mut commands: Commands) {828/// commands.insert_resource(Scoreboard {829/// current_score: 0,830/// high_score: 0,831/// });832/// }833/// # bevy_ecs::system::assert_is_system(system);834/// ```835#[track_caller]836pub fn insert_resource<R: Resource>(&mut self, resource: R) {837self.queue(command::insert_resource(resource));838}839840/// Removes a [`Resource`] from the [`World`].841///842/// # Example843///844/// ```845/// # use bevy_ecs::prelude::*;846/// #[derive(Resource)]847/// struct Scoreboard {848/// current_score: u32,849/// high_score: u32,850/// }851///852/// fn system(mut commands: Commands) {853/// commands.remove_resource::<Scoreboard>();854/// }855/// # bevy_ecs::system::assert_is_system(system);856/// ```857pub fn remove_resource<R: Resource>(&mut self) {858self.queue(command::remove_resource::<R>());859}860861/// Runs the system corresponding to the given [`SystemId`].862/// Before running a system, it must first be registered via863/// [`Commands::register_system`] or [`World::register_system`].864///865/// The system is run in an exclusive and single-threaded way.866/// Running slow systems can become a bottleneck.867///868/// There is no way to get the output of a system when run as a command, because the869/// execution of the system happens later. To get the output of a system, use870/// [`World::run_system`] or [`World::run_system_with`] instead of running the system as a command.871///872/// # Fallible873///874/// This command will fail if the given [`SystemId`]875/// does not correspond to a [`System`](crate::system::System).876///877/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),878/// which will be handled by [logging the error at the `warn` level](warn).879pub fn run_system(&mut self, id: SystemId) {880self.queue(command::run_system(id).handle_error_with(warn));881}882883/// Runs the system corresponding to the given [`SystemId`] with input.884/// Before running a system, it must first be registered via885/// [`Commands::register_system`] or [`World::register_system`].886///887/// The system is run in an exclusive and single-threaded way.888/// Running slow systems can become a bottleneck.889///890/// There is no way to get the output of a system when run as a command, because the891/// execution of the system happens later. To get the output of a system, use892/// [`World::run_system`] or [`World::run_system_with`] instead of running the system as a command.893///894/// # Fallible895///896/// This command will fail if the given [`SystemId`]897/// does not correspond to a [`System`](crate::system::System).898///899/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),900/// which will be handled by [logging the error at the `warn` level](warn).901pub fn run_system_with<I>(&mut self, id: SystemId<I>, input: I::Inner<'static>)902where903I: SystemInput<Inner<'static>: Send> + 'static,904{905self.queue(command::run_system_with(id, input).handle_error_with(warn));906}907908/// Registers a system and returns its [`SystemId`] so it can later be called by909/// [`Commands::run_system`] or [`World::run_system`].910///911/// This is different from adding systems to a [`Schedule`](crate::schedule::Schedule),912/// because the [`SystemId`] that is returned can be used anywhere in the [`World`] to run the associated system.913///914/// Using a [`Schedule`](crate::schedule::Schedule) is still preferred for most cases915/// due to its better performance and ability to run non-conflicting systems simultaneously.916///917/// # Note918///919/// If the same system is registered more than once,920/// each registration will be considered a different system,921/// and they will each be given their own [`SystemId`].922///923/// If you want to avoid registering the same system multiple times,924/// consider using [`Commands::run_system_cached`] or storing the [`SystemId`]925/// in a [`Local`](crate::system::Local).926///927/// # Example928///929/// ```930/// # use bevy_ecs::{prelude::*, world::CommandQueue, system::SystemId};931/// #[derive(Resource)]932/// struct Counter(i32);933///934/// fn register_system(935/// mut commands: Commands,936/// mut local_system: Local<Option<SystemId>>,937/// ) {938/// if let Some(system) = *local_system {939/// commands.run_system(system);940/// } else {941/// *local_system = Some(commands.register_system(increment_counter));942/// }943/// }944///945/// fn increment_counter(mut value: ResMut<Counter>) {946/// value.0 += 1;947/// }948///949/// # let mut world = World::default();950/// # world.insert_resource(Counter(0));951/// # let mut queue_1 = CommandQueue::default();952/// # let systemid = {953/// # let mut commands = Commands::new(&mut queue_1, &world);954/// # commands.register_system(increment_counter)955/// # };956/// # let mut queue_2 = CommandQueue::default();957/// # {958/// # let mut commands = Commands::new(&mut queue_2, &world);959/// # commands.run_system(systemid);960/// # }961/// # queue_1.append(&mut queue_2);962/// # queue_1.apply(&mut world);963/// # assert_eq!(1, world.resource::<Counter>().0);964/// # bevy_ecs::system::assert_is_system(register_system);965/// ```966pub fn register_system<I, O, M>(967&mut self,968system: impl IntoSystem<I, O, M> + 'static,969) -> SystemId<I, O>970where971I: SystemInput + Send + 'static,972O: Send + 'static,973{974let entity = self.spawn_empty().id();975let system = RegisteredSystem::<I, O>::new(Box::new(IntoSystem::into_system(system)));976self.entity(entity).insert(system);977SystemId::from_entity(entity)978}979980/// Removes a system previously registered with [`Commands::register_system`]981/// or [`World::register_system`].982///983/// After removing a system, the [`SystemId`] becomes invalid984/// and attempting to use it afterwards will result in an error.985/// Re-adding the removed system will register it with a new `SystemId`.986///987/// # Fallible988///989/// This command will fail if the given [`SystemId`]990/// does not correspond to a [`System`](crate::system::System).991///992/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),993/// which will be handled by [logging the error at the `warn` level](warn).994pub fn unregister_system<I, O>(&mut self, system_id: SystemId<I, O>)995where996I: SystemInput + Send + 'static,997O: Send + 'static,998{999self.queue(command::unregister_system(system_id).handle_error_with(warn));1000}10011002/// Removes a system previously registered with one of the following:1003/// - [`Commands::run_system_cached`]1004/// - [`World::run_system_cached`]1005/// - [`World::register_system_cached`]1006///1007/// # Fallible1008///1009/// This command will fail if the given system1010/// is not currently cached in a [`CachedSystemId`](crate::system::CachedSystemId) resource.1011///1012/// It will internally return a [`RegisteredSystemError`](crate::system::system_registry::RegisteredSystemError),1013/// which will be handled by [logging the error at the `warn` level](warn).1014pub fn unregister_system_cached<I, O, M, S>(&mut self, system: S)1015where1016I: SystemInput + Send + 'static,1017O: 'static,1018M: 'static,1019S: IntoSystem<I, O, M> + Send + 'static,1020{1021self.queue(command::unregister_system_cached(system).handle_error_with(warn));1022}10231024/// Runs a cached system, registering it if necessary.1025///1026/// Unlike [`Commands::run_system`], this method does not require manual registration.1027///1028/// The first time this method is called for a particular system,1029/// it will register the system and store its [`SystemId`] in a1030/// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.1031///1032/// If you would rather manage the [`SystemId`] yourself,1033/// or register multiple copies of the same system,1034/// use [`Commands::register_system`] instead.1035///1036/// # Limitations1037///1038/// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of1039/// the same type must be equal. This means that closures that capture the environment, and1040/// function pointers, are not accepted.1041///1042/// If you want to access values from the environment within a system,1043/// consider passing them in as inputs via [`Commands::run_system_cached_with`].1044///1045/// If that's not an option, consider [`Commands::register_system`] instead.1046pub fn run_system_cached<M, S>(&mut self, system: S)1047where1048M: 'static,1049S: IntoSystem<(), (), M> + Send + 'static,1050{1051self.queue(command::run_system_cached(system).handle_error_with(warn));1052}10531054/// Runs a cached system with an input, registering it if necessary.1055///1056/// Unlike [`Commands::run_system_with`], this method does not require manual registration.1057///1058/// The first time this method is called for a particular system,1059/// it will register the system and store its [`SystemId`] in a1060/// [`CachedSystemId`](crate::system::CachedSystemId) resource for later.1061///1062/// If you would rather manage the [`SystemId`] yourself,1063/// or register multiple copies of the same system,1064/// use [`Commands::register_system`] instead.1065///1066/// # Limitations1067///1068/// This method only accepts ZST (zero-sized) systems to guarantee that any two systems of1069/// the same type must be equal. This means that closures that capture the environment, and1070/// function pointers, are not accepted.1071///1072/// If you want to access values from the environment within a system,1073/// consider passing them in as inputs.1074///1075/// If that's not an option, consider [`Commands::register_system`] instead.1076pub fn run_system_cached_with<I, M, S>(&mut self, system: S, input: I::Inner<'static>)1077where1078I: SystemInput<Inner<'static>: Send> + Send + 'static,1079M: 'static,1080S: IntoSystem<I, (), M> + Send + 'static,1081{1082self.queue(command::run_system_cached_with(system, input).handle_error_with(warn));1083}10841085/// Triggers the given [`Event`], which will run any [`Observer`]s watching for it.1086///1087/// [`Observer`]: crate::observer::Observer1088#[track_caller]1089pub fn trigger<'a>(&mut self, event: impl Event<Trigger<'a>: Default>) {1090self.queue(command::trigger(event));1091}10921093/// A deprecated alias for [`trigger`](Self::trigger) to ease migration.1094///1095/// Instead of specifying the trigger target separately,1096/// information about the target of the event is embedded in the data held by1097/// the event type itself.1098#[deprecated(since = "0.17.0", note = "Use `Commands::trigger` instead.")]1099pub fn trigger_targets<'a>(&mut self, event: impl Event<Trigger<'a>: Default>) {1100self.trigger(event);1101}11021103/// Triggers the given [`Event`] using the given [`Trigger`], which will run any [`Observer`]s watching for it.1104///1105/// [`Trigger`]: crate::event::Trigger1106/// [`Observer`]: crate::observer::Observer1107#[track_caller]1108pub fn trigger_with<E: Event<Trigger<'static>: Send + Sync>>(1109&mut self,1110event: E,1111trigger: E::Trigger<'static>,1112) {1113self.queue(command::trigger_with(event, trigger));1114}11151116/// Spawns an [`Observer`] and returns the [`EntityCommands`] associated1117/// with the entity that stores the observer.1118///1119/// `observer` can be any system whose first parameter is [`On`].1120///1121/// **Calling [`observe`](EntityCommands::observe) on the returned1122/// [`EntityCommands`] will observe the observer itself, which you very1123/// likely do not want.**1124///1125/// # Panics1126///1127/// Panics if the given system is an exclusive system.1128///1129/// [`On`]: crate::observer::On1130pub fn add_observer<E: Event, B: Bundle, M>(1131&mut self,1132observer: impl IntoObserverSystem<E, B, M>,1133) -> EntityCommands<'_> {1134self.spawn(Observer::new(observer))1135}11361137/// Writes an arbitrary [`BufferedEvent`].1138///1139/// This is a convenience method for writing events1140/// without requiring an [`EventWriter`](crate::event::EventWriter).1141///1142/// # Performance1143///1144/// Since this is a command, exclusive world access is used, which means that it will not profit from1145/// system-level parallelism on supported platforms.1146///1147/// If these events are performance-critical or very frequently sent,1148/// consider using a typed [`EventWriter`](crate::event::EventWriter) instead.1149#[track_caller]1150pub fn write_event<E: BufferedEvent>(&mut self, event: E) -> &mut Self {1151self.queue(command::write_event(event));1152self1153}11541155/// Writes an arbitrary [`BufferedEvent`].1156///1157/// This is a convenience method for writing events1158/// without requiring an [`EventWriter`](crate::event::EventWriter).1159///1160/// # Performance1161///1162/// Since this is a command, exclusive world access is used, which means that it will not profit from1163/// system-level parallelism on supported platforms.1164///1165/// If these events are performance-critical or very frequently sent,1166/// consider using a typed [`EventWriter`](crate::event::EventWriter) instead.1167#[track_caller]1168#[deprecated(since = "0.17.0", note = "Use `Commands::write_event` instead.")]1169pub fn send_event<E: BufferedEvent>(&mut self, event: E) -> &mut Self {1170self.write_event(event)1171}11721173/// Runs the schedule corresponding to the given [`ScheduleLabel`].1174///1175/// Calls [`World::try_run_schedule`](World::try_run_schedule).1176///1177/// # Fallible1178///1179/// This command will fail if the given [`ScheduleLabel`]1180/// does not correspond to a [`Schedule`](crate::schedule::Schedule).1181///1182/// It will internally return a [`TryRunScheduleError`](crate::world::error::TryRunScheduleError),1183/// which will be handled by [logging the error at the `warn` level](warn).1184///1185/// # Example1186///1187/// ```1188/// # use bevy_ecs::prelude::*;1189/// # use bevy_ecs::schedule::ScheduleLabel;1190/// # #[derive(Default, Resource)]1191/// # struct Counter(u32);1192/// #[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone, Copy)]1193/// struct FooSchedule;1194///1195/// # fn foo_system(mut counter: ResMut<Counter>) {1196/// # counter.0 += 1;1197/// # }1198/// #1199/// # let mut schedule = Schedule::new(FooSchedule);1200/// # schedule.add_systems(foo_system);1201/// #1202/// # let mut world = World::default();1203/// #1204/// # world.init_resource::<Counter>();1205/// # world.add_schedule(schedule);1206/// #1207/// # assert_eq!(world.resource::<Counter>().0, 0);1208/// #1209/// # let mut commands = world.commands();1210/// commands.run_schedule(FooSchedule);1211/// #1212/// # world.flush();1213/// #1214/// # assert_eq!(world.resource::<Counter>().0, 1);1215/// ```1216pub fn run_schedule(&mut self, label: impl ScheduleLabel) {1217self.queue(command::run_schedule(label).handle_error_with(warn));1218}1219}12201221/// A list of commands that will be run to modify an [`Entity`].1222///1223/// # Note1224///1225/// Most [`Commands`] (and thereby [`EntityCommands`]) are deferred:1226/// when you call the command, if it requires mutable access to the [`World`]1227/// (that is, if it removes, adds, or changes something), it's not executed immediately.1228///1229/// Instead, the command is added to a "command queue."1230/// The command queue is applied later1231/// when the [`ApplyDeferred`](crate::schedule::ApplyDeferred) system runs.1232/// Commands are executed one-by-one so that1233/// each command can have exclusive access to the `World`.1234///1235/// # Fallible1236///1237/// Due to their deferred nature, an entity you're trying to change with an [`EntityCommand`]1238/// can be despawned by the time the command is executed.1239///1240/// All deferred entity commands will check whether the entity exists at the time of execution1241/// and will return an error if it doesn't.1242///1243/// # Error handling1244///1245/// An [`EntityCommand`] can return a [`Result`](crate::error::Result),1246/// which will be passed to an [error handler](crate::error) if the `Result` is an error.1247///1248/// The default error handler panics. It can be configured via1249/// the [`DefaultErrorHandler`](crate::error::DefaultErrorHandler) resource.1250///1251/// Alternatively, you can customize the error handler for a specific command1252/// by calling [`EntityCommands::queue_handled`].1253///1254/// The [`error`](crate::error) module provides some simple error handlers for convenience.1255pub struct EntityCommands<'a> {1256pub(crate) entity: Entity,1257pub(crate) commands: Commands<'a, 'a>,1258}12591260impl<'a> EntityCommands<'a> {1261/// Returns the [`Entity`] id of the entity.1262///1263/// # Example1264///1265/// ```1266/// # use bevy_ecs::prelude::*;1267/// #1268/// fn my_system(mut commands: Commands) {1269/// let entity_id = commands.spawn_empty().id();1270/// }1271/// # bevy_ecs::system::assert_is_system(my_system);1272/// ```1273#[inline]1274#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]1275pub fn id(&self) -> Entity {1276self.entity1277}12781279/// Returns an [`EntityCommands`] with a smaller lifetime.1280///1281/// This is useful if you have `&mut EntityCommands` but you need `EntityCommands`.1282pub fn reborrow(&mut self) -> EntityCommands<'_> {1283EntityCommands {1284entity: self.entity,1285commands: self.commands.reborrow(),1286}1287}12881289/// Get an [`EntityEntryCommands`] for the [`Component`] `T`,1290/// allowing you to modify it or insert it if it isn't already present.1291///1292/// See also [`insert_if_new`](Self::insert_if_new),1293/// which lets you insert a [`Bundle`] without overwriting it.1294///1295/// # Example1296///1297/// ```1298/// # use bevy_ecs::prelude::*;1299/// # #[derive(Resource)]1300/// # struct PlayerEntity { entity: Entity }1301/// #[derive(Component)]1302/// struct Level(u32);1303///1304///1305/// #[derive(Component, Default)]1306/// struct Mana {1307/// max: u32,1308/// current: u32,1309/// }1310///1311/// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {1312/// // If a component already exists then modify it, otherwise insert a default value1313/// commands1314/// .entity(player.entity)1315/// .entry::<Level>()1316/// .and_modify(|mut lvl| lvl.0 += 1)1317/// .or_insert(Level(0));1318///1319/// // Add a default value if none exists, and then modify the existing or new value1320/// commands1321/// .entity(player.entity)1322/// .entry::<Mana>()1323/// .or_default()1324/// .and_modify(|mut mana| {1325/// mana.max += 10;1326/// mana.current = mana.max;1327/// });1328/// }1329///1330/// # bevy_ecs::system::assert_is_system(level_up_system);1331/// ```1332pub fn entry<T: Component>(&mut self) -> EntityEntryCommands<'_, T> {1333EntityEntryCommands {1334entity_commands: self.reborrow(),1335marker: PhantomData,1336}1337}13381339/// Adds a [`Bundle`] of components to the entity.1340///1341/// This will overwrite any previous value(s) of the same component type.1342/// See [`EntityCommands::insert_if_new`] to keep the old value instead.1343///1344/// # Example1345///1346/// ```1347/// # use bevy_ecs::prelude::*;1348/// # #[derive(Resource)]1349/// # struct PlayerEntity { entity: Entity }1350/// #[derive(Component)]1351/// struct Health(u32);1352/// #[derive(Component)]1353/// struct Strength(u32);1354/// #[derive(Component)]1355/// struct Defense(u32);1356///1357/// #[derive(Bundle)]1358/// struct CombatBundle {1359/// health: Health,1360/// strength: Strength,1361/// }1362///1363/// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1364/// commands1365/// .entity(player.entity)1366/// // You can insert individual components:1367/// .insert(Defense(10))1368/// // You can also insert pre-defined bundles of components:1369/// .insert(CombatBundle {1370/// health: Health(100),1371/// strength: Strength(40),1372/// })1373/// // You can also insert tuples of components and bundles.1374/// // This is equivalent to the calls above:1375/// .insert((1376/// Defense(10),1377/// CombatBundle {1378/// health: Health(100),1379/// strength: Strength(40),1380/// },1381/// ));1382/// }1383/// # bevy_ecs::system::assert_is_system(add_combat_stats_system);1384/// ```1385#[track_caller]1386pub fn insert(&mut self, bundle: impl Bundle) -> &mut Self {1387self.queue(entity_command::insert(bundle, InsertMode::Replace))1388}13891390/// Adds a [`Bundle`] of components to the entity if the predicate returns true.1391///1392/// This is useful for chaining method calls.1393///1394/// # Example1395///1396/// ```1397/// # use bevy_ecs::prelude::*;1398/// # #[derive(Resource)]1399/// # struct PlayerEntity { entity: Entity }1400/// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }1401/// #[derive(Component)]1402/// struct StillLoadingStats;1403/// #[derive(Component)]1404/// struct Health(u32);1405///1406/// fn add_health_system(mut commands: Commands, player: Res<PlayerEntity>) {1407/// commands1408/// .entity(player.entity)1409/// .insert_if(Health(10), || !player.is_spectator())1410/// .remove::<StillLoadingStats>();1411/// }1412/// # bevy_ecs::system::assert_is_system(add_health_system);1413/// ```1414#[track_caller]1415pub fn insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1416where1417F: FnOnce() -> bool,1418{1419if condition() {1420self.insert(bundle)1421} else {1422self1423}1424}14251426/// Adds a [`Bundle`] of components to the entity without overwriting.1427///1428/// This is the same as [`EntityCommands::insert`], but in case of duplicate1429/// components will leave the old values instead of replacing them with new ones.1430///1431/// See also [`entry`](Self::entry), which lets you modify a [`Component`] if it's present,1432/// as well as initialize it with a default value.1433#[track_caller]1434pub fn insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {1435self.queue(entity_command::insert(bundle, InsertMode::Keep))1436}14371438/// Adds a [`Bundle`] of components to the entity without overwriting if the1439/// predicate returns true.1440///1441/// This is the same as [`EntityCommands::insert_if`], but in case of duplicate1442/// components will leave the old values instead of replacing them with new ones.1443#[track_caller]1444pub fn insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1445where1446F: FnOnce() -> bool,1447{1448if condition() {1449self.insert_if_new(bundle)1450} else {1451self1452}1453}14541455/// Adds a dynamic [`Component`] to the entity.1456///1457/// This will overwrite any previous value(s) of the same component type.1458///1459/// You should prefer to use the typed API [`EntityCommands::insert`] where possible.1460///1461/// # Safety1462///1463/// - [`ComponentId`] must be from the same world as `self`.1464/// - `T` must have the same layout as the one passed during `component_id` creation.1465#[track_caller]1466pub unsafe fn insert_by_id<T: Send + 'static>(1467&mut self,1468component_id: ComponentId,1469value: T,1470) -> &mut Self {1471self.queue(1472// SAFETY:1473// - `ComponentId` safety is ensured by the caller.1474// - `T` safety is ensured by the caller.1475unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },1476)1477}14781479/// Adds a dynamic [`Component`] to the entity.1480///1481/// This will overwrite any previous value(s) of the same component type.1482///1483/// You should prefer to use the typed API [`EntityCommands::try_insert`] where possible.1484///1485/// # Note1486///1487/// If the entity does not exist when this command is executed,1488/// the resulting error will be ignored.1489///1490/// # Safety1491///1492/// - [`ComponentId`] must be from the same world as `self`.1493/// - `T` must have the same layout as the one passed during `component_id` creation.1494#[track_caller]1495pub unsafe fn try_insert_by_id<T: Send + 'static>(1496&mut self,1497component_id: ComponentId,1498value: T,1499) -> &mut Self {1500self.queue_silenced(1501// SAFETY:1502// - `ComponentId` safety is ensured by the caller.1503// - `T` safety is ensured by the caller.1504unsafe { entity_command::insert_by_id(component_id, value, InsertMode::Replace) },1505)1506}15071508/// Adds a [`Bundle`] of components to the entity.1509///1510/// This will overwrite any previous value(s) of the same component type.1511///1512/// # Note1513///1514/// If the entity does not exist when this command is executed,1515/// the resulting error will be ignored.1516///1517/// # Example1518///1519/// ```1520/// # use bevy_ecs::prelude::*;1521/// # #[derive(Resource)]1522/// # struct PlayerEntity { entity: Entity }1523/// #[derive(Component)]1524/// struct Health(u32);1525/// #[derive(Component)]1526/// struct Strength(u32);1527/// #[derive(Component)]1528/// struct Defense(u32);1529///1530/// #[derive(Bundle)]1531/// struct CombatBundle {1532/// health: Health,1533/// strength: Strength,1534/// }1535///1536/// fn add_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1537/// commands.entity(player.entity)1538/// // You can insert individual components:1539/// .try_insert(Defense(10))1540/// // You can also insert tuples of components:1541/// .try_insert(CombatBundle {1542/// health: Health(100),1543/// strength: Strength(40),1544/// });1545///1546/// // Suppose this occurs in a parallel adjacent system or process.1547/// commands.entity(player.entity).despawn();1548///1549/// // This will not panic nor will it add the component.1550/// commands.entity(player.entity).try_insert(Defense(5));1551/// }1552/// # bevy_ecs::system::assert_is_system(add_combat_stats_system);1553/// ```1554#[track_caller]1555pub fn try_insert(&mut self, bundle: impl Bundle) -> &mut Self {1556self.queue_silenced(entity_command::insert(bundle, InsertMode::Replace))1557}15581559/// Adds a [`Bundle`] of components to the entity if the predicate returns true.1560///1561/// This is useful for chaining method calls.1562///1563/// # Note1564///1565/// If the entity does not exist when this command is executed,1566/// the resulting error will be ignored.1567#[track_caller]1568pub fn try_insert_if<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1569where1570F: FnOnce() -> bool,1571{1572if condition() {1573self.try_insert(bundle)1574} else {1575self1576}1577}15781579/// Adds a [`Bundle`] of components to the entity without overwriting if the1580/// predicate returns true.1581///1582/// This is the same as [`EntityCommands::try_insert_if`], but in case of duplicate1583/// components will leave the old values instead of replacing them with new ones.1584///1585/// # Note1586///1587/// If the entity does not exist when this command is executed,1588/// the resulting error will be ignored.1589#[track_caller]1590pub fn try_insert_if_new_and<F>(&mut self, bundle: impl Bundle, condition: F) -> &mut Self1591where1592F: FnOnce() -> bool,1593{1594if condition() {1595self.try_insert_if_new(bundle)1596} else {1597self1598}1599}16001601/// Adds a [`Bundle`] of components to the entity without overwriting.1602///1603/// This is the same as [`EntityCommands::try_insert`], but in case of duplicate1604/// components will leave the old values instead of replacing them with new ones.1605///1606/// # Note1607///1608/// If the entity does not exist when this command is executed,1609/// the resulting error will be ignored.1610#[track_caller]1611pub fn try_insert_if_new(&mut self, bundle: impl Bundle) -> &mut Self {1612self.queue_silenced(entity_command::insert(bundle, InsertMode::Keep))1613}16141615/// Removes a [`Bundle`] of components from the entity.1616///1617/// This will remove all components that intersect with the provided bundle;1618/// the entity does not need to have all the components in the bundle.1619///1620/// This will emit a warning if the entity does not exist.1621///1622/// # Example1623///1624/// ```1625/// # use bevy_ecs::prelude::*;1626/// # #[derive(Resource)]1627/// # struct PlayerEntity { entity: Entity }1628/// #[derive(Component)]1629/// struct Health(u32);1630/// #[derive(Component)]1631/// struct Strength(u32);1632/// #[derive(Component)]1633/// struct Defense(u32);1634///1635/// #[derive(Bundle)]1636/// struct CombatBundle {1637/// health: Health,1638/// strength: Strength,1639/// }1640///1641/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1642/// commands1643/// .entity(player.entity)1644/// // You can remove individual components:1645/// .remove::<Defense>()1646/// // You can also remove pre-defined bundles of components:1647/// .remove::<CombatBundle>()1648/// // You can also remove tuples of components and bundles.1649/// // This is equivalent to the calls above:1650/// .remove::<(Defense, CombatBundle)>();1651/// }1652/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1653/// ```1654#[track_caller]1655pub fn remove<B: Bundle>(&mut self) -> &mut Self {1656self.queue_handled(entity_command::remove::<B>(), warn)1657}16581659/// Removes a [`Bundle`] of components from the entity if the predicate returns true.1660///1661/// This is useful for chaining method calls.1662///1663/// # Example1664///1665/// ```1666/// # use bevy_ecs::prelude::*;1667/// # #[derive(Resource)]1668/// # struct PlayerEntity { entity: Entity }1669/// # impl PlayerEntity { fn is_spectator(&self) -> bool { true } }1670/// #[derive(Component)]1671/// struct Health(u32);1672/// #[derive(Component)]1673/// struct Strength(u32);1674/// #[derive(Component)]1675/// struct Defense(u32);1676///1677/// #[derive(Bundle)]1678/// struct CombatBundle {1679/// health: Health,1680/// strength: Strength,1681/// }1682///1683/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1684/// commands1685/// .entity(player.entity)1686/// .remove_if::<(Defense, CombatBundle)>(|| !player.is_spectator());1687/// }1688/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1689/// ```1690#[track_caller]1691pub fn remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {1692if condition() {1693self.remove::<B>()1694} else {1695self1696}1697}16981699/// Removes a [`Bundle`] of components from the entity if the predicate returns true.1700///1701/// This is useful for chaining method calls.1702///1703/// # Note1704///1705/// If the entity does not exist when this command is executed,1706/// the resulting error will be ignored.1707#[track_caller]1708pub fn try_remove_if<B: Bundle>(&mut self, condition: impl FnOnce() -> bool) -> &mut Self {1709if condition() {1710self.try_remove::<B>()1711} else {1712self1713}1714}17151716/// Removes a [`Bundle`] of components from the entity.1717///1718/// This will remove all components that intersect with the provided bundle;1719/// the entity does not need to have all the components in the bundle.1720///1721/// Unlike [`Self::remove`],1722/// this will not emit a warning if the entity does not exist.1723///1724/// # Example1725///1726/// ```1727/// # use bevy_ecs::prelude::*;1728/// # #[derive(Resource)]1729/// # struct PlayerEntity { entity: Entity }1730/// #[derive(Component)]1731/// struct Health(u32);1732/// #[derive(Component)]1733/// struct Strength(u32);1734/// #[derive(Component)]1735/// struct Defense(u32);1736///1737/// #[derive(Bundle)]1738/// struct CombatBundle {1739/// health: Health,1740/// strength: Strength,1741/// }1742///1743/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1744/// commands1745/// .entity(player.entity)1746/// // You can remove individual components:1747/// .try_remove::<Defense>()1748/// // You can also remove pre-defined bundles of components:1749/// .try_remove::<CombatBundle>()1750/// // You can also remove tuples of components and bundles.1751/// // This is equivalent to the calls above:1752/// .try_remove::<(Defense, CombatBundle)>();1753/// }1754/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1755/// ```1756pub fn try_remove<B: Bundle>(&mut self) -> &mut Self {1757self.queue_silenced(entity_command::remove::<B>())1758}17591760/// Removes a [`Bundle`] of components from the entity,1761/// and also removes any components required by the components in the bundle.1762///1763/// This will remove all components that intersect with the provided bundle;1764/// the entity does not need to have all the components in the bundle.1765///1766/// # Example1767///1768/// ```1769/// # use bevy_ecs::prelude::*;1770/// # #[derive(Resource)]1771/// # struct PlayerEntity { entity: Entity }1772/// #1773/// #[derive(Component)]1774/// #[require(B)]1775/// struct A;1776/// #[derive(Component, Default)]1777/// struct B;1778///1779/// fn remove_with_requires_system(mut commands: Commands, player: Res<PlayerEntity>) {1780/// commands1781/// .entity(player.entity)1782/// // Removes both A and B from the entity, because B is required by A.1783/// .remove_with_requires::<A>();1784/// }1785/// # bevy_ecs::system::assert_is_system(remove_with_requires_system);1786/// ```1787#[track_caller]1788pub fn remove_with_requires<B: Bundle>(&mut self) -> &mut Self {1789self.queue(entity_command::remove_with_requires::<B>())1790}17911792/// Removes a dynamic [`Component`] from the entity if it exists.1793///1794/// # Panics1795///1796/// Panics if the provided [`ComponentId`] does not exist in the [`World`].1797#[track_caller]1798pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {1799self.queue(entity_command::remove_by_id(component_id))1800}18011802/// Removes all components associated with the entity.1803#[track_caller]1804pub fn clear(&mut self) -> &mut Self {1805self.queue(entity_command::clear())1806}18071808/// Despawns the entity.1809///1810/// This will emit a warning if the entity does not exist.1811///1812/// # Note1813///1814/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)1815/// that is configured to despawn descendants.1816///1817/// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1818///1819/// # Example1820///1821/// ```1822/// # use bevy_ecs::prelude::*;1823/// # #[derive(Resource)]1824/// # struct CharacterToRemove { entity: Entity }1825/// #1826/// fn remove_character_system(1827/// mut commands: Commands,1828/// character_to_remove: Res<CharacterToRemove>1829/// ) {1830/// commands.entity(character_to_remove.entity).despawn();1831/// }1832/// # bevy_ecs::system::assert_is_system(remove_character_system);1833/// ```1834#[track_caller]1835pub fn despawn(&mut self) {1836self.queue_handled(entity_command::despawn(), warn);1837}18381839/// Despawns the entity.1840///1841/// Unlike [`Self::despawn`],1842/// this will not emit a warning if the entity does not exist.1843///1844/// # Note1845///1846/// This will also despawn the entities in any [`RelationshipTarget`](crate::relationship::RelationshipTarget)1847/// that is configured to despawn descendants.1848///1849/// For example, this will recursively despawn [`Children`](crate::hierarchy::Children).1850pub fn try_despawn(&mut self) {1851self.queue_silenced(entity_command::despawn());1852}18531854/// Pushes an [`EntityCommand`] to the queue,1855/// which will get executed for the current [`Entity`].1856///1857/// The [default error handler](crate::error::DefaultErrorHandler)1858/// will be used to handle error cases.1859/// Every [`EntityCommand`] checks whether the entity exists at the time of execution1860/// and returns an error if it does not.1861///1862/// To use a custom error handler, see [`EntityCommands::queue_handled`].1863///1864/// The command can be:1865/// - A custom struct that implements [`EntityCommand`].1866/// - A closure or function that matches the following signature:1867/// - [`(EntityWorldMut)`](EntityWorldMut)1868/// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]1869/// - A built-in command from the [`entity_command`] module.1870///1871/// # Example1872///1873/// ```1874/// # use bevy_ecs::prelude::*;1875/// # fn my_system(mut commands: Commands) {1876/// commands1877/// .spawn_empty()1878/// // Closures with this signature implement `EntityCommand`.1879/// .queue(|entity: EntityWorldMut| {1880/// println!("Executed an EntityCommand for {}", entity.id());1881/// });1882/// # }1883/// # bevy_ecs::system::assert_is_system(my_system);1884/// ```1885pub fn queue<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(1886&mut self,1887command: C,1888) -> &mut Self {1889self.commands.queue(command.with_entity(self.entity));1890self1891}18921893/// Pushes an [`EntityCommand`] to the queue,1894/// which will get executed for the current [`Entity`].1895///1896/// The given `error_handler` will be used to handle error cases.1897/// Every [`EntityCommand`] checks whether the entity exists at the time of execution1898/// and returns an error if it does not.1899///1900/// To implicitly use the default error handler, see [`EntityCommands::queue`].1901///1902/// The command can be:1903/// - A custom struct that implements [`EntityCommand`].1904/// - A closure or function that matches the following signature:1905/// - [`(EntityWorldMut)`](EntityWorldMut)1906/// - [`(EntityWorldMut)`](EntityWorldMut) `->` [`Result`]1907/// - A built-in command from the [`entity_command`] module.1908///1909/// # Example1910///1911/// ```1912/// # use bevy_ecs::prelude::*;1913/// # fn my_system(mut commands: Commands) {1914/// use bevy_ecs::error::warn;1915///1916/// commands1917/// .spawn_empty()1918/// // Closures with this signature implement `EntityCommand`.1919/// .queue_handled(1920/// |entity: EntityWorldMut| -> Result {1921/// let value: usize = "100".parse()?;1922/// println!("Successfully parsed the value {} for entity {}", value, entity.id());1923/// Ok(())1924/// },1925/// warn1926/// );1927/// # }1928/// # bevy_ecs::system::assert_is_system(my_system);1929/// ```1930pub fn queue_handled<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(1931&mut self,1932command: C,1933error_handler: fn(BevyError, ErrorContext),1934) -> &mut Self {1935self.commands1936.queue_handled(command.with_entity(self.entity), error_handler);1937self1938}19391940/// Pushes an [`EntityCommand`] to the queue, which will get executed for the current [`Entity`].1941///1942/// Unlike [`EntityCommands::queue_handled`], this will completely ignore any errors that occur.1943pub fn queue_silenced<C: EntityCommand<T> + CommandWithEntity<M>, T, M>(1944&mut self,1945command: C,1946) -> &mut Self {1947self.commands1948.queue_silenced(command.with_entity(self.entity));1949self1950}19511952/// Removes all components except the given [`Bundle`] from the entity.1953///1954/// # Example1955///1956/// ```1957/// # use bevy_ecs::prelude::*;1958/// # #[derive(Resource)]1959/// # struct PlayerEntity { entity: Entity }1960/// #[derive(Component)]1961/// struct Health(u32);1962/// #[derive(Component)]1963/// struct Strength(u32);1964/// #[derive(Component)]1965/// struct Defense(u32);1966///1967/// #[derive(Bundle)]1968/// struct CombatBundle {1969/// health: Health,1970/// strength: Strength,1971/// }1972///1973/// fn remove_combat_stats_system(mut commands: Commands, player: Res<PlayerEntity>) {1974/// commands1975/// .entity(player.entity)1976/// // You can retain a pre-defined Bundle of components,1977/// // with this removing only the Defense component.1978/// .retain::<CombatBundle>()1979/// // You can also retain only a single component.1980/// .retain::<Health>();1981/// }1982/// # bevy_ecs::system::assert_is_system(remove_combat_stats_system);1983/// ```1984#[track_caller]1985pub fn retain<B: Bundle>(&mut self) -> &mut Self {1986self.queue(entity_command::retain::<B>())1987}19881989/// Logs the components of the entity at the [`info`](log::info) level.1990pub fn log_components(&mut self) -> &mut Self {1991self.queue(entity_command::log_components())1992}19931994/// Returns the underlying [`Commands`].1995pub fn commands(&mut self) -> Commands<'_, '_> {1996self.commands.reborrow()1997}19981999/// Returns a mutable reference to the underlying [`Commands`].2000pub fn commands_mut(&mut self) -> &mut Commands<'a, 'a> {2001&mut self.commands2002}20032004/// Creates an [`Observer`] watching for an [`EntityEvent`] of type `E` whose [`EntityEvent::event_target`]2005/// targets this entity.2006pub fn observe<E: EntityEvent, B: Bundle, M>(2007&mut self,2008observer: impl IntoObserverSystem<E, B, M>,2009) -> &mut Self {2010self.queue(entity_command::observe(observer))2011}20122013/// Clones parts of an entity (components, observers, etc.) onto another entity,2014/// configured through [`EntityClonerBuilder`].2015///2016/// The other entity will receive all the components of the original that implement2017/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are2018/// [denied](EntityClonerBuilder::deny) in the `config`.2019///2020/// # Panics2021///2022/// The command will panic when applied if the target entity does not exist.2023///2024/// # Example2025///2026/// Configure through [`EntityClonerBuilder<OptOut>`] as follows:2027/// ```2028/// # use bevy_ecs::prelude::*;2029/// #[derive(Component, Clone)]2030/// struct ComponentA(u32);2031/// #[derive(Component, Clone)]2032/// struct ComponentB(u32);2033///2034/// fn example_system(mut commands: Commands) {2035/// // Create an empty entity.2036/// let target = commands.spawn_empty().id();2037///2038/// // Create a new entity and keep its EntityCommands.2039/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2040///2041/// // Clone ComponentA but not ComponentB onto the target.2042/// entity.clone_with_opt_out(target, |builder| {2043/// builder.deny::<ComponentB>();2044/// });2045/// }2046/// # bevy_ecs::system::assert_is_system(example_system);2047/// ```2048///2049/// See [`EntityClonerBuilder`] for more options.2050pub fn clone_with_opt_out(2051&mut self,2052target: Entity,2053config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,2054) -> &mut Self {2055self.queue(entity_command::clone_with_opt_out(target, config))2056}20572058/// Clones parts of an entity (components, observers, etc.) onto another entity,2059/// configured through [`EntityClonerBuilder`].2060///2061/// The other entity will receive only the components of the original that implement2062/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are2063/// [allowed](EntityClonerBuilder::allow) in the `config`.2064///2065/// # Panics2066///2067/// The command will panic when applied if the target entity does not exist.2068///2069/// # Example2070///2071/// Configure through [`EntityClonerBuilder<OptIn>`] as follows:2072/// ```2073/// # use bevy_ecs::prelude::*;2074/// #[derive(Component, Clone)]2075/// struct ComponentA(u32);2076/// #[derive(Component, Clone)]2077/// struct ComponentB(u32);2078///2079/// fn example_system(mut commands: Commands) {2080/// // Create an empty entity.2081/// let target = commands.spawn_empty().id();2082///2083/// // Create a new entity and keep its EntityCommands.2084/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2085///2086/// // Clone ComponentA but not ComponentB onto the target.2087/// entity.clone_with_opt_in(target, |builder| {2088/// builder.allow::<ComponentA>();2089/// });2090/// }2091/// # bevy_ecs::system::assert_is_system(example_system);2092/// ```2093///2094/// See [`EntityClonerBuilder`] for more options.2095pub fn clone_with_opt_in(2096&mut self,2097target: Entity,2098config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,2099) -> &mut Self {2100self.queue(entity_command::clone_with_opt_in(target, config))2101}21022103/// Spawns a clone of this entity and returns the [`EntityCommands`] of the clone.2104///2105/// The clone will receive all the components of the original that implement2106/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).2107///2108/// To configure cloning behavior (such as only cloning certain components),2109/// use [`EntityCommands::clone_and_spawn_with_opt_out`]/2110/// [`opt_out`](EntityCommands::clone_and_spawn_with_opt_out).2111///2112/// # Note2113///2114/// If the original entity does not exist when this command is applied,2115/// the returned entity will have no components.2116///2117/// # Example2118///2119/// ```2120/// # use bevy_ecs::prelude::*;2121/// #[derive(Component, Clone)]2122/// struct ComponentA(u32);2123/// #[derive(Component, Clone)]2124/// struct ComponentB(u32);2125///2126/// fn example_system(mut commands: Commands) {2127/// // Create a new entity and store its EntityCommands.2128/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2129///2130/// // Create a clone of the entity.2131/// let mut entity_clone = entity.clone_and_spawn();2132/// }2133/// # bevy_ecs::system::assert_is_system(example_system);2134pub fn clone_and_spawn(&mut self) -> EntityCommands<'_> {2135self.clone_and_spawn_with_opt_out(|_| {})2136}21372138/// Spawns a clone of this entity and allows configuring cloning behavior2139/// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.2140///2141/// The clone will receive all the components of the original that implement2142/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are2143/// [denied](EntityClonerBuilder::deny) in the `config`.2144///2145/// See the methods on [`EntityClonerBuilder<OptOut>`] for more options.2146///2147/// # Note2148///2149/// If the original entity does not exist when this command is applied,2150/// the returned entity will have no components.2151///2152/// # Example2153///2154/// ```2155/// # use bevy_ecs::prelude::*;2156/// #[derive(Component, Clone)]2157/// struct ComponentA(u32);2158/// #[derive(Component, Clone)]2159/// struct ComponentB(u32);2160///2161/// fn example_system(mut commands: Commands) {2162/// // Create a new entity and store its EntityCommands.2163/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2164///2165/// // Create a clone of the entity with ComponentA but without ComponentB.2166/// let mut entity_clone = entity.clone_and_spawn_with_opt_out(|builder| {2167/// builder.deny::<ComponentB>();2168/// });2169/// }2170/// # bevy_ecs::system::assert_is_system(example_system);2171pub fn clone_and_spawn_with_opt_out(2172&mut self,2173config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,2174) -> EntityCommands<'_> {2175let entity_clone = self.commands().spawn_empty().id();2176self.clone_with_opt_out(entity_clone, config);2177EntityCommands {2178commands: self.commands_mut().reborrow(),2179entity: entity_clone,2180}2181}21822183/// Spawns a clone of this entity and allows configuring cloning behavior2184/// using [`EntityClonerBuilder`], returning the [`EntityCommands`] of the clone.2185///2186/// The clone will receive only the components of the original that implement2187/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are2188/// [allowed](EntityClonerBuilder::allow) in the `config`.2189///2190/// See the methods on [`EntityClonerBuilder<OptIn>`] for more options.2191///2192/// # Note2193///2194/// If the original entity does not exist when this command is applied,2195/// the returned entity will have no components.2196///2197/// # Example2198///2199/// ```2200/// # use bevy_ecs::prelude::*;2201/// #[derive(Component, Clone)]2202/// struct ComponentA(u32);2203/// #[derive(Component, Clone)]2204/// struct ComponentB(u32);2205///2206/// fn example_system(mut commands: Commands) {2207/// // Create a new entity and store its EntityCommands.2208/// let mut entity = commands.spawn((ComponentA(10), ComponentB(20)));2209///2210/// // Create a clone of the entity with ComponentA but without ComponentB.2211/// let mut entity_clone = entity.clone_and_spawn_with_opt_in(|builder| {2212/// builder.allow::<ComponentA>();2213/// });2214/// }2215/// # bevy_ecs::system::assert_is_system(example_system);2216pub fn clone_and_spawn_with_opt_in(2217&mut self,2218config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,2219) -> EntityCommands<'_> {2220let entity_clone = self.commands().spawn_empty().id();2221self.clone_with_opt_in(entity_clone, config);2222EntityCommands {2223commands: self.commands_mut().reborrow(),2224entity: entity_clone,2225}2226}22272228/// Clones the specified components of this entity and inserts them into another entity.2229///2230/// Components can only be cloned if they implement2231/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).2232///2233/// # Panics2234///2235/// The command will panic when applied if the target entity does not exist.2236pub fn clone_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {2237self.queue(entity_command::clone_components::<B>(target))2238}22392240/// Moves the specified components of this entity into another entity.2241///2242/// Components with [`Ignore`] clone behavior will not be moved, while components that2243/// have a [`Custom`] clone behavior will be cloned using it and then removed from the source entity.2244/// All other components will be moved without any other special handling.2245///2246/// Note that this will trigger `on_remove` hooks/observers on this entity and `on_insert`/`on_add` hooks/observers on the target entity.2247///2248/// # Panics2249///2250/// The command will panic when applied if the target entity does not exist.2251///2252/// [`Ignore`]: crate::component::ComponentCloneBehavior::Ignore2253/// [`Custom`]: crate::component::ComponentCloneBehavior::Custom2254pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {2255self.queue(entity_command::move_components::<B>(target))2256}2257}22582259/// A wrapper around [`EntityCommands`] with convenience methods for working with a specified component type.2260pub struct EntityEntryCommands<'a, T> {2261entity_commands: EntityCommands<'a>,2262marker: PhantomData<T>,2263}22642265impl<'a, T: Component<Mutability = Mutable>> EntityEntryCommands<'a, T> {2266/// Modify the component `T` if it exists, using the function `modify`.2267pub fn and_modify(&mut self, modify: impl FnOnce(Mut<T>) + Send + Sync + 'static) -> &mut Self {2268self.entity_commands2269.queue(move |mut entity: EntityWorldMut| {2270if let Some(value) = entity.get_mut() {2271modify(value);2272}2273});2274self2275}2276}22772278impl<'a, T: Component> EntityEntryCommands<'a, T> {2279/// [Insert](EntityCommands::insert) `default` into this entity,2280/// if `T` is not already present.2281#[track_caller]2282pub fn or_insert(&mut self, default: T) -> &mut Self {2283self.entity_commands.insert_if_new(default);2284self2285}22862287/// [Insert](EntityCommands::insert) `default` into this entity,2288/// if `T` is not already present.2289///2290/// # Note2291///2292/// If the entity does not exist when this command is executed,2293/// the resulting error will be ignored.2294#[track_caller]2295pub fn or_try_insert(&mut self, default: T) -> &mut Self {2296self.entity_commands.try_insert_if_new(default);2297self2298}22992300/// [Insert](EntityCommands::insert) the value returned from `default` into this entity,2301/// if `T` is not already present.2302///2303/// `default` will only be invoked if the component will actually be inserted.2304#[track_caller]2305pub fn or_insert_with<F>(&mut self, default: F) -> &mut Self2306where2307F: FnOnce() -> T + Send + 'static,2308{2309self.entity_commands2310.queue(entity_command::insert_with(default, InsertMode::Keep));2311self2312}23132314/// [Insert](EntityCommands::insert) the value returned from `default` into this entity,2315/// if `T` is not already present.2316///2317/// `default` will only be invoked if the component will actually be inserted.2318///2319/// # Note2320///2321/// If the entity does not exist when this command is executed,2322/// the resulting error will be ignored.2323#[track_caller]2324pub fn or_try_insert_with<F>(&mut self, default: F) -> &mut Self2325where2326F: FnOnce() -> T + Send + 'static,2327{2328self.entity_commands2329.queue_silenced(entity_command::insert_with(default, InsertMode::Keep));2330self2331}23322333/// [Insert](EntityCommands::insert) `T::default` into this entity,2334/// if `T` is not already present.2335///2336/// `T::default` will only be invoked if the component will actually be inserted.2337#[track_caller]2338pub fn or_default(&mut self) -> &mut Self2339where2340T: Default,2341{2342self.or_insert_with(T::default)2343}23442345/// [Insert](EntityCommands::insert) `T::from_world` into this entity,2346/// if `T` is not already present.2347///2348/// `T::from_world` will only be invoked if the component will actually be inserted.2349#[track_caller]2350pub fn or_from_world(&mut self) -> &mut Self2351where2352T: FromWorld,2353{2354self.entity_commands2355.queue(entity_command::insert_from_world::<T>(InsertMode::Keep));2356self2357}23582359/// Get the [`EntityCommands`] from which the [`EntityEntryCommands`] was initiated.2360///2361/// This allows you to continue chaining method calls after calling [`EntityCommands::entry`].2362///2363/// # Example2364///2365/// ```2366/// # use bevy_ecs::prelude::*;2367/// # #[derive(Resource)]2368/// # struct PlayerEntity { entity: Entity }2369/// #[derive(Component)]2370/// struct Level(u32);2371///2372/// fn level_up_system(mut commands: Commands, player: Res<PlayerEntity>) {2373/// commands2374/// .entity(player.entity)2375/// .entry::<Level>()2376/// // Modify the component if it exists.2377/// .and_modify(|mut lvl| lvl.0 += 1)2378/// // Otherwise, insert a default value.2379/// .or_insert(Level(0))2380/// // Return the EntityCommands for the entity.2381/// .entity()2382/// // Continue chaining method calls.2383/// .insert(Name::new("Player"));2384/// }2385/// # bevy_ecs::system::assert_is_system(level_up_system);2386/// ```2387pub fn entity(&mut self) -> EntityCommands<'_> {2388self.entity_commands.reborrow()2389}2390}23912392#[cfg(test)]2393mod tests {2394use crate::{2395component::Component,2396resource::Resource,2397system::Commands,2398world::{CommandQueue, FromWorld, World},2399};2400use alloc::{string::String, sync::Arc, vec, vec::Vec};2401use core::{2402any::TypeId,2403sync::atomic::{AtomicUsize, Ordering},2404};24052406#[expect(2407dead_code,2408reason = "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."2409)]2410#[derive(Component)]2411#[component(storage = "SparseSet")]2412struct SparseDropCk(DropCk);24132414#[derive(Component)]2415struct DropCk(Arc<AtomicUsize>);2416impl DropCk {2417fn new_pair() -> (Self, Arc<AtomicUsize>) {2418let atomic = Arc::new(AtomicUsize::new(0));2419(DropCk(atomic.clone()), atomic)2420}2421}24222423impl Drop for DropCk {2424fn drop(&mut self) {2425self.0.as_ref().fetch_add(1, Ordering::Relaxed);2426}2427}24282429#[derive(Component, Resource)]2430struct W<T>(T);24312432fn simple_command(world: &mut World) {2433world.spawn((W(0u32), W(42u64)));2434}24352436impl FromWorld for W<String> {2437fn from_world(world: &mut World) -> Self {2438let v = world.resource::<W<usize>>();2439Self("*".repeat(v.0))2440}2441}24422443impl Default for W<u8> {2444fn default() -> Self {2445unreachable!()2446}2447}24482449#[test]2450fn entity_commands_entry() {2451let mut world = World::default();2452let mut queue = CommandQueue::default();2453let mut commands = Commands::new(&mut queue, &world);2454let entity = commands.spawn_empty().id();2455commands2456.entity(entity)2457.entry::<W<u32>>()2458.and_modify(|_| unreachable!());2459queue.apply(&mut world);2460assert!(!world.entity(entity).contains::<W<u32>>());2461let mut commands = Commands::new(&mut queue, &world);2462commands2463.entity(entity)2464.entry::<W<u32>>()2465.or_insert(W(0))2466.and_modify(|mut val| {2467val.0 = 21;2468});2469queue.apply(&mut world);2470assert_eq!(21, world.get::<W<u32>>(entity).unwrap().0);2471let mut commands = Commands::new(&mut queue, &world);2472commands2473.entity(entity)2474.entry::<W<u64>>()2475.and_modify(|_| unreachable!())2476.or_insert(W(42));2477queue.apply(&mut world);2478assert_eq!(42, world.get::<W<u64>>(entity).unwrap().0);2479world.insert_resource(W(5_usize));2480let mut commands = Commands::new(&mut queue, &world);2481commands.entity(entity).entry::<W<String>>().or_from_world();2482queue.apply(&mut world);2483assert_eq!("*****", &world.get::<W<String>>(entity).unwrap().0);2484let mut commands = Commands::new(&mut queue, &world);2485let id = commands.entity(entity).entry::<W<u64>>().entity().id();2486queue.apply(&mut world);2487assert_eq!(id, entity);2488let mut commands = Commands::new(&mut queue, &world);2489commands2490.entity(entity)2491.entry::<W<u8>>()2492.or_insert_with(|| W(5))2493.or_insert_with(|| unreachable!())2494.or_try_insert_with(|| unreachable!())2495.or_default()2496.or_from_world();2497queue.apply(&mut world);2498assert_eq!(5, world.get::<W<u8>>(entity).unwrap().0);2499}25002501#[test]2502fn commands() {2503let mut world = World::default();2504let mut command_queue = CommandQueue::default();2505let entity = Commands::new(&mut command_queue, &world)2506.spawn((W(1u32), W(2u64)))2507.id();2508command_queue.apply(&mut world);2509assert_eq!(world.query::<&W<u32>>().query(&world).count(), 1);2510let results = world2511.query::<(&W<u32>, &W<u64>)>()2512.iter(&world)2513.map(|(a, b)| (a.0, b.0))2514.collect::<Vec<_>>();2515assert_eq!(results, vec![(1u32, 2u64)]);2516// test entity despawn2517{2518let mut commands = Commands::new(&mut command_queue, &world);2519commands.entity(entity).despawn();2520commands.entity(entity).despawn(); // double despawn shouldn't panic2521}2522command_queue.apply(&mut world);2523let results2 = world2524.query::<(&W<u32>, &W<u64>)>()2525.iter(&world)2526.map(|(a, b)| (a.0, b.0))2527.collect::<Vec<_>>();2528assert_eq!(results2, vec![]);25292530// test adding simple (FnOnce) commands2531{2532let mut commands = Commands::new(&mut command_queue, &world);25332534// set up a simple command using a closure that adds one additional entity2535commands.queue(|world: &mut World| {2536world.spawn((W(42u32), W(0u64)));2537});25382539// set up a simple command using a function that adds one additional entity2540commands.queue(simple_command);2541}2542command_queue.apply(&mut world);2543let results3 = world2544.query::<(&W<u32>, &W<u64>)>()2545.iter(&world)2546.map(|(a, b)| (a.0, b.0))2547.collect::<Vec<_>>();25482549assert_eq!(results3, vec![(42u32, 0u64), (0u32, 42u64)]);2550}25512552#[test]2553fn insert_components() {2554let mut world = World::default();2555let mut command_queue1 = CommandQueue::default();25562557// insert components2558let entity = Commands::new(&mut command_queue1, &world)2559.spawn(())2560.insert_if(W(1u8), || true)2561.insert_if(W(2u8), || false)2562.insert_if_new(W(1u16))2563.insert_if_new(W(2u16))2564.insert_if_new_and(W(1u32), || false)2565.insert_if_new_and(W(2u32), || true)2566.insert_if_new_and(W(3u32), || true)2567.id();2568command_queue1.apply(&mut world);25692570let results = world2571.query::<(&W<u8>, &W<u16>, &W<u32>)>()2572.iter(&world)2573.map(|(a, b, c)| (a.0, b.0, c.0))2574.collect::<Vec<_>>();2575assert_eq!(results, vec![(1u8, 1u16, 2u32)]);25762577// try to insert components after despawning entity2578// in another command queue2579Commands::new(&mut command_queue1, &world)2580.entity(entity)2581.try_insert_if_new_and(W(1u64), || true);25822583let mut command_queue2 = CommandQueue::default();2584Commands::new(&mut command_queue2, &world)2585.entity(entity)2586.despawn();2587command_queue2.apply(&mut world);2588command_queue1.apply(&mut world);2589}25902591#[test]2592fn remove_components() {2593let mut world = World::default();25942595let mut command_queue = CommandQueue::default();2596let (dense_dropck, dense_is_dropped) = DropCk::new_pair();2597let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();2598let sparse_dropck = SparseDropCk(sparse_dropck);25992600let entity = Commands::new(&mut command_queue, &world)2601.spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))2602.id();2603command_queue.apply(&mut world);2604let results_before = world2605.query::<(&W<u32>, &W<u64>)>()2606.iter(&world)2607.map(|(a, b)| (a.0, b.0))2608.collect::<Vec<_>>();2609assert_eq!(results_before, vec![(1u32, 2u64)]);26102611// test component removal2612Commands::new(&mut command_queue, &world)2613.entity(entity)2614.remove::<W<u32>>()2615.remove::<(W<u32>, W<u64>, SparseDropCk, DropCk)>();26162617assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);2618assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);2619command_queue.apply(&mut world);2620assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);2621assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);26222623let results_after = world2624.query::<(&W<u32>, &W<u64>)>()2625.iter(&world)2626.map(|(a, b)| (a.0, b.0))2627.collect::<Vec<_>>();2628assert_eq!(results_after, vec![]);2629let results_after_u64 = world2630.query::<&W<u64>>()2631.iter(&world)2632.map(|v| v.0)2633.collect::<Vec<_>>();2634assert_eq!(results_after_u64, vec![]);2635}26362637#[test]2638fn remove_components_by_id() {2639let mut world = World::default();26402641let mut command_queue = CommandQueue::default();2642let (dense_dropck, dense_is_dropped) = DropCk::new_pair();2643let (sparse_dropck, sparse_is_dropped) = DropCk::new_pair();2644let sparse_dropck = SparseDropCk(sparse_dropck);26452646let entity = Commands::new(&mut command_queue, &world)2647.spawn((W(1u32), W(2u64), dense_dropck, sparse_dropck))2648.id();2649command_queue.apply(&mut world);2650let results_before = world2651.query::<(&W<u32>, &W<u64>)>()2652.iter(&world)2653.map(|(a, b)| (a.0, b.0))2654.collect::<Vec<_>>();2655assert_eq!(results_before, vec![(1u32, 2u64)]);26562657// test component removal2658Commands::new(&mut command_queue, &world)2659.entity(entity)2660.remove_by_id(world.components().get_id(TypeId::of::<W<u32>>()).unwrap())2661.remove_by_id(world.components().get_id(TypeId::of::<W<u64>>()).unwrap())2662.remove_by_id(world.components().get_id(TypeId::of::<DropCk>()).unwrap())2663.remove_by_id(2664world2665.components()2666.get_id(TypeId::of::<SparseDropCk>())2667.unwrap(),2668);26692670assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 0);2671assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 0);2672command_queue.apply(&mut world);2673assert_eq!(dense_is_dropped.load(Ordering::Relaxed), 1);2674assert_eq!(sparse_is_dropped.load(Ordering::Relaxed), 1);26752676let results_after = world2677.query::<(&W<u32>, &W<u64>)>()2678.iter(&world)2679.map(|(a, b)| (a.0, b.0))2680.collect::<Vec<_>>();2681assert_eq!(results_after, vec![]);2682let results_after_u64 = world2683.query::<&W<u64>>()2684.iter(&world)2685.map(|v| v.0)2686.collect::<Vec<_>>();2687assert_eq!(results_after_u64, vec![]);2688}26892690#[test]2691fn remove_resources() {2692let mut world = World::default();2693let mut queue = CommandQueue::default();2694{2695let mut commands = Commands::new(&mut queue, &world);2696commands.insert_resource(W(123i32));2697commands.insert_resource(W(456.0f64));2698}26992700queue.apply(&mut world);2701assert!(world.contains_resource::<W<i32>>());2702assert!(world.contains_resource::<W<f64>>());27032704{2705let mut commands = Commands::new(&mut queue, &world);2706// test resource removal2707commands.remove_resource::<W<i32>>();2708}2709queue.apply(&mut world);2710assert!(!world.contains_resource::<W<i32>>());2711assert!(world.contains_resource::<W<f64>>());2712}27132714#[test]2715fn remove_component_with_required_components() {2716#[derive(Component)]2717#[require(Y)]2718struct X;27192720#[derive(Component, Default)]2721struct Y;27222723#[derive(Component)]2724struct Z;27252726let mut world = World::default();2727let mut queue = CommandQueue::default();2728let e = {2729let mut commands = Commands::new(&mut queue, &world);2730commands.spawn((X, Z)).id()2731};2732queue.apply(&mut world);27332734assert!(world.get::<Y>(e).is_some());2735assert!(world.get::<X>(e).is_some());2736assert!(world.get::<Z>(e).is_some());27372738{2739let mut commands = Commands::new(&mut queue, &world);2740commands.entity(e).remove_with_requires::<X>();2741}2742queue.apply(&mut world);27432744assert!(world.get::<Y>(e).is_none());2745assert!(world.get::<X>(e).is_none());27462747assert!(world.get::<Z>(e).is_some());2748}27492750#[test]2751fn unregister_system_cached_commands() {2752let mut world = World::default();2753let mut queue = CommandQueue::default();27542755fn nothing() {}27562757let resources = world.iter_resources().count();2758let id = world.register_system_cached(nothing);2759assert_eq!(world.iter_resources().count(), resources + 1);2760assert!(world.get_entity(id.entity).is_ok());27612762let mut commands = Commands::new(&mut queue, &world);2763commands.unregister_system_cached(nothing);2764queue.apply(&mut world);2765assert_eq!(world.iter_resources().count(), resources);2766assert!(world.get_entity(id.entity).is_err());2767}27682769fn is_send<T: Send>() {}2770fn is_sync<T: Sync>() {}27712772#[test]2773fn test_commands_are_send_and_sync() {2774is_send::<Commands>();2775is_sync::<Commands>();2776}27772778#[test]2779fn append() {2780let mut world = World::default();2781let mut queue_1 = CommandQueue::default();2782{2783let mut commands = Commands::new(&mut queue_1, &world);2784commands.insert_resource(W(123i32));2785}2786let mut queue_2 = CommandQueue::default();2787{2788let mut commands = Commands::new(&mut queue_2, &world);2789commands.insert_resource(W(456.0f64));2790}2791queue_1.append(&mut queue_2);2792queue_1.apply(&mut world);2793assert!(world.contains_resource::<W<i32>>());2794assert!(world.contains_resource::<W<f64>>());2795}27962797#[test]2798fn track_spawn_ticks() {2799let mut world = World::default();2800world.increment_change_tick();2801let expected = world.change_tick();2802let id = world.commands().spawn_empty().id();2803world.flush();2804assert_eq!(2805Some(expected),2806world.entities().entity_get_spawned_or_despawned_at(id)2807);2808}2809}281028112812