Path: blob/main/crates/bevy_ecs/src/world/entity_ref.rs
6604 views
use crate::{1archetype::Archetype,2bundle::{3Bundle, BundleEffect, BundleFromComponents, BundleInserter, BundleRemover, DynamicBundle,4InsertMode,5},6change_detection::{MaybeLocation, MutUntyped},7component::{Component, ComponentId, ComponentTicks, Components, Mutable, StorageType, Tick},8entity::{9ContainsEntity, Entity, EntityCloner, EntityClonerBuilder, EntityEquivalent,10EntityIdLocation, EntityLocation, OptIn, OptOut,11},12event::{EntityComponentsTrigger, EntityEvent},13lifecycle::{Despawn, Remove, Replace, DESPAWN, REMOVE, REPLACE},14observer::Observer,15query::{Access, DebugCheckedUnwrap, ReadOnlyQueryData, ReleaseStateQueryData},16relationship::RelationshipHookMode,17resource::Resource,18storage::{SparseSets, Table},19system::IntoObserverSystem,20world::{error::EntityComponentError, unsafe_world_cell::UnsafeEntityCell, Mut, Ref, World},21};22use alloc::vec::Vec;23use bevy_platform::collections::{HashMap, HashSet};24use bevy_ptr::{OwningPtr, Ptr};25use core::{26any::TypeId,27cmp::Ordering,28hash::{Hash, Hasher},29marker::PhantomData,30mem::MaybeUninit,31};32use thiserror::Error;3334/// A read-only reference to a particular [`Entity`] and all of its components.35///36/// # Examples37///38/// Read-only access disjoint with mutable access.39///40/// ```41/// # use bevy_ecs::prelude::*;42/// # #[derive(Component)] pub struct A;43/// # #[derive(Component)] pub struct B;44/// fn disjoint_system(45/// query1: Query<&mut A>,46/// query2: Query<EntityRef, Without<A>>,47/// ) {48/// // ...49/// }50/// # bevy_ecs::system::assert_is_system(disjoint_system);51/// ```52#[derive(Copy, Clone)]53pub struct EntityRef<'w> {54cell: UnsafeEntityCell<'w>,55}5657impl<'w> EntityRef<'w> {58/// # Safety59/// - `cell` must have permission to read every component of the entity.60/// - No mutable accesses to any of the entity's components may exist61/// at the same time as the returned [`EntityRef`].62#[inline]63pub(crate) unsafe fn new(cell: UnsafeEntityCell<'w>) -> Self {64Self { cell }65}6667/// Returns the [ID](Entity) of the current entity.68#[inline]69#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]70pub fn id(&self) -> Entity {71self.cell.id()72}7374/// Gets metadata indicating the location where the current entity is stored.75#[inline]76pub fn location(&self) -> EntityLocation {77self.cell.location()78}7980/// Returns the archetype that the current entity belongs to.81#[inline]82pub fn archetype(&self) -> &Archetype {83self.cell.archetype()84}8586/// Returns `true` if the current entity has a component of type `T`.87/// Otherwise, this returns `false`.88///89/// ## Notes90///91/// If you do not know the concrete type of a component, consider using92/// [`Self::contains_id`] or [`Self::contains_type_id`].93#[inline]94pub fn contains<T: Component>(&self) -> bool {95self.contains_type_id(TypeId::of::<T>())96}9798/// Returns `true` if the current entity has a component identified by `component_id`.99/// Otherwise, this returns false.100///101/// ## Notes102///103/// - If you know the concrete type of the component, you should prefer [`Self::contains`].104/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using105/// [`Self::contains_type_id`].106#[inline]107pub fn contains_id(&self, component_id: ComponentId) -> bool {108self.cell.contains_id(component_id)109}110111/// Returns `true` if the current entity has a component with the type identified by `type_id`.112/// Otherwise, this returns false.113///114/// ## Notes115///116/// - If you know the concrete type of the component, you should prefer [`Self::contains`].117/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].118#[inline]119pub fn contains_type_id(&self, type_id: TypeId) -> bool {120self.cell.contains_type_id(type_id)121}122123/// Gets access to the component of type `T` for the current entity.124/// Returns `None` if the entity does not have a component of type `T`.125#[inline]126pub fn get<T: Component>(&self) -> Option<&'w T> {127// SAFETY: We have read-only access to all components of this entity.128unsafe { self.cell.get::<T>() }129}130131/// Gets access to the component of type `T` for the current entity,132/// including change detection information as a [`Ref`].133///134/// Returns `None` if the entity does not have a component of type `T`.135#[inline]136pub fn get_ref<T: Component>(&self) -> Option<Ref<'w, T>> {137// SAFETY: We have read-only access to all components of this entity.138unsafe { self.cell.get_ref::<T>() }139}140141/// Retrieves the change ticks for the given component. This can be useful for implementing change142/// detection in custom runtimes.143#[inline]144pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {145// SAFETY: We have read-only access to all components of this entity.146unsafe { self.cell.get_change_ticks::<T>() }147}148149/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change150/// detection in custom runtimes.151///152/// **You should prefer to use the typed API [`EntityRef::get_change_ticks`] where possible and only153/// use this in cases where the actual component types are not known at154/// compile time.**155#[inline]156pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {157// SAFETY: We have read-only access to all components of this entity.158unsafe { self.cell.get_change_ticks_by_id(component_id) }159}160161/// Returns [untyped read-only reference(s)](Ptr) to component(s) for the162/// current entity, based on the given [`ComponentId`]s.163///164/// **You should prefer to use the typed API [`EntityRef::get`] where165/// possible and only use this in cases where the actual component types166/// are not known at compile time.**167///168/// Unlike [`EntityRef::get`], this returns untyped reference(s) to169/// component(s), and it's the job of the caller to ensure the correct170/// type(s) are dereferenced (if necessary).171///172/// # Errors173///174/// Returns [`EntityComponentError::MissingComponent`] if the entity does175/// not have a component.176///177/// # Examples178///179/// ## Single [`ComponentId`]180///181/// ```182/// # use bevy_ecs::prelude::*;183/// #184/// # #[derive(Component, PartialEq, Debug)]185/// # pub struct Foo(i32);186/// # let mut world = World::new();187/// let entity = world.spawn(Foo(42)).id();188///189/// // Grab the component ID for `Foo` in whatever way you like.190/// let component_id = world.register_component::<Foo>();191///192/// // Then, get the component by ID.193/// let ptr = world.entity(entity).get_by_id(component_id);194/// # assert_eq!(unsafe { ptr.unwrap().deref::<Foo>() }, &Foo(42));195/// ```196///197/// ## Array of [`ComponentId`]s198///199/// ```200/// # use bevy_ecs::prelude::*;201/// #202/// # #[derive(Component, PartialEq, Debug)]203/// # pub struct X(i32);204/// # #[derive(Component, PartialEq, Debug)]205/// # pub struct Y(i32);206/// # let mut world = World::new();207/// let entity = world.spawn((X(42), Y(10))).id();208///209/// // Grab the component IDs for `X` and `Y` in whatever way you like.210/// let x_id = world.register_component::<X>();211/// let y_id = world.register_component::<Y>();212///213/// // Then, get the components by ID. You'll receive a same-sized array.214/// let Ok([x_ptr, y_ptr]) = world.entity(entity).get_by_id([x_id, y_id]) else {215/// // Up to you to handle if a component is missing from the entity.216/// # unreachable!();217/// };218/// # assert_eq!((unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() }), (&X(42), &Y(10)));219/// ```220///221/// ## Slice of [`ComponentId`]s222///223/// ```224/// # use bevy_ecs::{prelude::*, component::ComponentId};225/// #226/// # #[derive(Component, PartialEq, Debug)]227/// # pub struct X(i32);228/// # #[derive(Component, PartialEq, Debug)]229/// # pub struct Y(i32);230/// # let mut world = World::new();231/// let entity = world.spawn((X(42), Y(10))).id();232///233/// // Grab the component IDs for `X` and `Y` in whatever way you like.234/// let x_id = world.register_component::<X>();235/// let y_id = world.register_component::<Y>();236///237/// // Then, get the components by ID. You'll receive a vec of ptrs.238/// let ptrs = world.entity(entity).get_by_id(&[x_id, y_id] as &[ComponentId]);239/// # let ptrs = ptrs.unwrap();240/// # assert_eq!((unsafe { ptrs[0].deref::<X>() }, unsafe { ptrs[1].deref::<Y>() }), (&X(42), &Y(10)));241/// ```242///243/// ## [`HashSet`] of [`ComponentId`]s244///245/// ```246/// # use bevy_platform::collections::HashSet;247/// # use bevy_ecs::{prelude::*, component::ComponentId};248/// #249/// # #[derive(Component, PartialEq, Debug)]250/// # pub struct X(i32);251/// # #[derive(Component, PartialEq, Debug)]252/// # pub struct Y(i32);253/// # let mut world = World::new();254/// let entity = world.spawn((X(42), Y(10))).id();255///256/// // Grab the component IDs for `X` and `Y` in whatever way you like.257/// let x_id = world.register_component::<X>();258/// let y_id = world.register_component::<Y>();259///260/// // Then, get the components by ID. You'll receive a vec of ptrs.261/// let ptrs = world.entity(entity).get_by_id(&HashSet::from_iter([x_id, y_id]));262/// # let ptrs = ptrs.unwrap();263/// # assert_eq!((unsafe { ptrs[&x_id].deref::<X>() }, unsafe { ptrs[&y_id].deref::<Y>() }), (&X(42), &Y(10)));264/// ```265#[inline]266pub fn get_by_id<F: DynamicComponentFetch>(267&self,268component_ids: F,269) -> Result<F::Ref<'w>, EntityComponentError> {270// SAFETY: We have read-only access to all components of this entity.271unsafe { component_ids.fetch_ref(self.cell) }272}273274/// Returns read-only components for the current entity that match the query `Q`.275///276/// # Panics277///278/// If the entity does not have the components required by the query `Q`.279pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'w, 'static> {280self.get_components::<Q>()281.expect("Query does not match the current entity")282}283284/// Returns read-only components for the current entity that match the query `Q`,285/// or `None` if the entity does not have the components required by the query `Q`.286pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(287&self,288) -> Option<Q::Item<'w, 'static>> {289// SAFETY:290// - We have read-only access to all components of this entity.291// - The query is read-only, and read-only references cannot have conflicts.292unsafe { self.cell.get_components::<Q>() }293}294295/// Returns the source code location from which this entity has been spawned.296pub fn spawned_by(&self) -> MaybeLocation {297self.cell.spawned_by()298}299300/// Returns the [`Tick`] at which this entity has been spawned.301pub fn spawned_at(&self) -> Tick {302self.cell.spawned_at()303}304}305306impl<'w> From<EntityWorldMut<'w>> for EntityRef<'w> {307fn from(entity: EntityWorldMut<'w>) -> EntityRef<'w> {308// SAFETY:309// - `EntityWorldMut` guarantees exclusive access to the entire world.310unsafe { EntityRef::new(entity.into_unsafe_entity_cell()) }311}312}313314impl<'a> From<&'a EntityWorldMut<'_>> for EntityRef<'a> {315fn from(entity: &'a EntityWorldMut<'_>) -> Self {316// SAFETY:317// - `EntityWorldMut` guarantees exclusive access to the entire world.318// - `&entity` ensures no mutable accesses are active.319unsafe { EntityRef::new(entity.as_unsafe_entity_cell_readonly()) }320}321}322323impl<'w> From<EntityMut<'w>> for EntityRef<'w> {324fn from(entity: EntityMut<'w>) -> Self {325// SAFETY:326// - `EntityMut` guarantees exclusive access to all of the entity's components.327unsafe { EntityRef::new(entity.cell) }328}329}330331impl<'a> From<&'a EntityMut<'_>> for EntityRef<'a> {332fn from(entity: &'a EntityMut<'_>) -> Self {333// SAFETY:334// - `EntityMut` guarantees exclusive access to all of the entity's components.335// - `&entity` ensures there are no mutable accesses.336unsafe { EntityRef::new(entity.cell) }337}338}339340impl<'a> TryFrom<FilteredEntityRef<'a, '_>> for EntityRef<'a> {341type Error = TryFromFilteredError;342343fn try_from(entity: FilteredEntityRef<'a, '_>) -> Result<Self, Self::Error> {344if !entity.access.has_read_all() {345Err(TryFromFilteredError::MissingReadAllAccess)346} else {347// SAFETY: check above guarantees read-only access to all components of the entity.348Ok(unsafe { EntityRef::new(entity.entity) })349}350}351}352353impl<'a> TryFrom<&'a FilteredEntityRef<'_, '_>> for EntityRef<'a> {354type Error = TryFromFilteredError;355356fn try_from(entity: &'a FilteredEntityRef<'_, '_>) -> Result<Self, Self::Error> {357if !entity.access.has_read_all() {358Err(TryFromFilteredError::MissingReadAllAccess)359} else {360// SAFETY: check above guarantees read-only access to all components of the entity.361Ok(unsafe { EntityRef::new(entity.entity) })362}363}364}365366impl<'a> TryFrom<FilteredEntityMut<'a, '_>> for EntityRef<'a> {367type Error = TryFromFilteredError;368369fn try_from(entity: FilteredEntityMut<'a, '_>) -> Result<Self, Self::Error> {370if !entity.access.has_read_all() {371Err(TryFromFilteredError::MissingReadAllAccess)372} else {373// SAFETY: check above guarantees read-only access to all components of the entity.374Ok(unsafe { EntityRef::new(entity.entity) })375}376}377}378379impl<'a> TryFrom<&'a FilteredEntityMut<'_, '_>> for EntityRef<'a> {380type Error = TryFromFilteredError;381382fn try_from(entity: &'a FilteredEntityMut<'_, '_>) -> Result<Self, Self::Error> {383if !entity.access.has_read_all() {384Err(TryFromFilteredError::MissingReadAllAccess)385} else {386// SAFETY: check above guarantees read-only access to all components of the entity.387Ok(unsafe { EntityRef::new(entity.entity) })388}389}390}391392impl PartialEq for EntityRef<'_> {393fn eq(&self, other: &Self) -> bool {394self.entity() == other.entity()395}396}397398impl Eq for EntityRef<'_> {}399400impl PartialOrd for EntityRef<'_> {401/// [`EntityRef`]'s comparison trait implementations match the underlying [`Entity`],402/// and cannot discern between different worlds.403fn partial_cmp(&self, other: &Self) -> Option<Ordering> {404Some(self.cmp(other))405}406}407408impl Ord for EntityRef<'_> {409fn cmp(&self, other: &Self) -> Ordering {410self.entity().cmp(&other.entity())411}412}413414impl Hash for EntityRef<'_> {415fn hash<H: Hasher>(&self, state: &mut H) {416self.entity().hash(state);417}418}419420impl ContainsEntity for EntityRef<'_> {421fn entity(&self) -> Entity {422self.id()423}424}425426// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.427unsafe impl EntityEquivalent for EntityRef<'_> {}428429/// Provides mutable access to a single entity and all of its components.430///431/// Contrast with [`EntityWorldMut`], which allows adding and removing components,432/// despawning the entity, and provides mutable access to the entire world.433/// Because of this, `EntityWorldMut` cannot coexist with any other world accesses.434///435/// # Examples436///437/// Disjoint mutable access.438///439/// ```440/// # use bevy_ecs::prelude::*;441/// # #[derive(Component)] pub struct A;442/// fn disjoint_system(443/// query1: Query<EntityMut, With<A>>,444/// query2: Query<EntityMut, Without<A>>,445/// ) {446/// // ...447/// }448/// # bevy_ecs::system::assert_is_system(disjoint_system);449/// ```450pub struct EntityMut<'w> {451cell: UnsafeEntityCell<'w>,452}453454impl<'w> EntityMut<'w> {455/// # Safety456/// - `cell` must have permission to mutate every component of the entity.457/// - No accesses to any of the entity's components may exist458/// at the same time as the returned [`EntityMut`].459#[inline]460pub(crate) unsafe fn new(cell: UnsafeEntityCell<'w>) -> Self {461Self { cell }462}463464/// Returns a new instance with a shorter lifetime.465/// This is useful if you have `&mut EntityMut`, but you need `EntityMut`.466pub fn reborrow(&mut self) -> EntityMut<'_> {467// SAFETY: We have exclusive access to the entire entity and its components.468unsafe { Self::new(self.cell) }469}470471/// Consumes `self` and returns read-only access to all of the entity's472/// components, with the world `'w` lifetime.473pub fn into_readonly(self) -> EntityRef<'w> {474EntityRef::from(self)475}476477/// Gets read-only access to all of the entity's components.478pub fn as_readonly(&self) -> EntityRef<'_> {479EntityRef::from(self)480}481482/// Returns the [ID](Entity) of the current entity.483#[inline]484#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]485pub fn id(&self) -> Entity {486self.cell.id()487}488489/// Gets metadata indicating the location where the current entity is stored.490#[inline]491pub fn location(&self) -> EntityLocation {492self.cell.location()493}494495/// Returns the archetype that the current entity belongs to.496#[inline]497pub fn archetype(&self) -> &Archetype {498self.cell.archetype()499}500501/// Returns `true` if the current entity has a component of type `T`.502/// Otherwise, this returns `false`.503///504/// ## Notes505///506/// If you do not know the concrete type of a component, consider using507/// [`Self::contains_id`] or [`Self::contains_type_id`].508#[inline]509pub fn contains<T: Component>(&self) -> bool {510self.contains_type_id(TypeId::of::<T>())511}512513/// Returns `true` if the current entity has a component identified by `component_id`.514/// Otherwise, this returns false.515///516/// ## Notes517///518/// - If you know the concrete type of the component, you should prefer [`Self::contains`].519/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using520/// [`Self::contains_type_id`].521#[inline]522pub fn contains_id(&self, component_id: ComponentId) -> bool {523self.cell.contains_id(component_id)524}525526/// Returns `true` if the current entity has a component with the type identified by `type_id`.527/// Otherwise, this returns false.528///529/// ## Notes530///531/// - If you know the concrete type of the component, you should prefer [`Self::contains`].532/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].533#[inline]534pub fn contains_type_id(&self, type_id: TypeId) -> bool {535self.cell.contains_type_id(type_id)536}537538/// Gets access to the component of type `T` for the current entity.539/// Returns `None` if the entity does not have a component of type `T`.540#[inline]541pub fn get<T: Component>(&self) -> Option<&'_ T> {542self.as_readonly().get()543}544545/// Returns read-only components for the current entity that match the query `Q`.546///547/// # Panics548///549/// If the entity does not have the components required by the query `Q`.550pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'_, 'static> {551self.as_readonly().components::<Q>()552}553554/// Returns read-only components for the current entity that match the query `Q`,555/// or `None` if the entity does not have the components required by the query `Q`.556pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(557&self,558) -> Option<Q::Item<'_, 'static>> {559self.as_readonly().get_components::<Q>()560}561562/// Returns components for the current entity that match the query `Q`,563/// or `None` if the entity does not have the components required by the query `Q`.564///565/// # Example566///567/// ```568/// # use bevy_ecs::prelude::*;569/// #570/// #[derive(Component)]571/// struct X(usize);572/// #[derive(Component)]573/// struct Y(usize);574///575/// # let mut world = World::default();576/// let mut entity = world.spawn((X(0), Y(0))).into_mutable();577/// // Get mutable access to two components at once578/// // SAFETY: X and Y are different components579/// let (mut x, mut y) =580/// unsafe { entity.get_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();581/// *x = X(1);582/// *y = Y(1);583/// // This would trigger undefined behavior, as the `&mut X`s would alias:584/// // entity.get_components_mut_unchecked::<(&mut X, &mut X)>();585/// ```586///587/// # Safety588/// It is the caller's responsibility to ensure that589/// the `QueryData` does not provide aliasing mutable references to the same component.590pub unsafe fn get_components_mut_unchecked<Q: ReleaseStateQueryData>(591&mut self,592) -> Option<Q::Item<'_, 'static>> {593// SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component594unsafe { self.reborrow().into_components_mut_unchecked::<Q>() }595}596597/// Consumes self and returns components for the current entity that match the query `Q` for the world lifetime `'w`,598/// or `None` if the entity does not have the components required by the query `Q`.599///600/// # Example601///602/// ```603/// # use bevy_ecs::prelude::*;604/// #605/// #[derive(Component)]606/// struct X(usize);607/// #[derive(Component)]608/// struct Y(usize);609///610/// # let mut world = World::default();611/// let mut entity = world.spawn((X(0), Y(0))).into_mutable();612/// // Get mutable access to two components at once613/// // SAFETY: X and Y are different components614/// let (mut x, mut y) =615/// unsafe { entity.into_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();616/// *x = X(1);617/// *y = Y(1);618/// // This would trigger undefined behavior, as the `&mut X`s would alias:619/// // entity.into_components_mut_unchecked::<(&mut X, &mut X)>();620/// ```621///622/// # Safety623/// It is the caller's responsibility to ensure that624/// the `QueryData` does not provide aliasing mutable references to the same component.625pub unsafe fn into_components_mut_unchecked<Q: ReleaseStateQueryData>(626self,627) -> Option<Q::Item<'w, 'static>> {628// SAFETY:629// - We have mutable access to all components of this entity.630// - Caller asserts the `QueryData` does not provide aliasing mutable references to the same component631unsafe { self.cell.get_components::<Q>() }632}633634/// Consumes `self` and gets access to the component of type `T` with the635/// world `'w` lifetime for the current entity.636///637/// Returns `None` if the entity does not have a component of type `T`.638#[inline]639pub fn into_borrow<T: Component>(self) -> Option<&'w T> {640self.into_readonly().get()641}642643/// Gets access to the component of type `T` for the current entity,644/// including change detection information as a [`Ref`].645///646/// Returns `None` if the entity does not have a component of type `T`.647#[inline]648pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {649self.as_readonly().get_ref()650}651652/// Consumes `self` and gets access to the component of type `T` with world653/// `'w` lifetime for the current entity, including change detection information654/// as a [`Ref<'w>`].655///656/// Returns `None` if the entity does not have a component of type `T`.657#[inline]658pub fn into_ref<T: Component>(self) -> Option<Ref<'w, T>> {659self.into_readonly().get_ref()660}661662/// Gets mutable access to the component of type `T` for the current entity.663/// Returns `None` if the entity does not have a component of type `T`.664#[inline]665pub fn get_mut<T: Component<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {666// SAFETY: &mut self implies exclusive access for duration of returned value667unsafe { self.cell.get_mut() }668}669670/// Gets mutable access to the component of type `T` for the current entity.671/// Returns `None` if the entity does not have a component of type `T`.672///673/// # Safety674///675/// - `T` must be a mutable component676#[inline]677pub unsafe fn get_mut_assume_mutable<T: Component>(&mut self) -> Option<Mut<'_, T>> {678// SAFETY:679// - &mut self implies exclusive access for duration of returned value680// - Caller ensures `T` is a mutable component681unsafe { self.cell.get_mut_assume_mutable() }682}683684/// Consumes self and gets mutable access to the component of type `T`685/// with the world `'w` lifetime for the current entity.686/// Returns `None` if the entity does not have a component of type `T`.687#[inline]688pub fn into_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {689// SAFETY: consuming `self` implies exclusive access690unsafe { self.cell.get_mut() }691}692693/// Gets mutable access to the component of type `T` for the current entity.694/// Returns `None` if the entity does not have a component of type `T`.695///696/// # Safety697///698/// - `T` must be a mutable component699#[inline]700pub unsafe fn into_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {701// SAFETY:702// - Consuming `self` implies exclusive access703// - Caller ensures `T` is a mutable component704unsafe { self.cell.get_mut_assume_mutable() }705}706707/// Retrieves the change ticks for the given component. This can be useful for implementing change708/// detection in custom runtimes.709#[inline]710pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {711self.as_readonly().get_change_ticks::<T>()712}713714/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change715/// detection in custom runtimes.716///717/// **You should prefer to use the typed API [`EntityWorldMut::get_change_ticks`] where possible and only718/// use this in cases where the actual component types are not known at719/// compile time.**720#[inline]721pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {722self.as_readonly().get_change_ticks_by_id(component_id)723}724725/// Returns [untyped read-only reference(s)](Ptr) to component(s) for the726/// current entity, based on the given [`ComponentId`]s.727///728/// **You should prefer to use the typed API [`EntityMut::get`] where729/// possible and only use this in cases where the actual component types730/// are not known at compile time.**731///732/// Unlike [`EntityMut::get`], this returns untyped reference(s) to733/// component(s), and it's the job of the caller to ensure the correct734/// type(s) are dereferenced (if necessary).735///736/// # Errors737///738/// Returns [`EntityComponentError::MissingComponent`] if the entity does739/// not have a component.740///741/// # Examples742///743/// For examples on how to use this method, see [`EntityRef::get_by_id`].744#[inline]745pub fn get_by_id<F: DynamicComponentFetch>(746&self,747component_ids: F,748) -> Result<F::Ref<'_>, EntityComponentError> {749self.as_readonly().get_by_id(component_ids)750}751752/// Consumes `self` and returns [untyped read-only reference(s)](Ptr) to753/// component(s) with lifetime `'w` for the current entity, based on the754/// given [`ComponentId`]s.755///756/// **You should prefer to use the typed API [`EntityMut::into_borrow`]757/// where possible and only use this in cases where the actual component758/// types are not known at compile time.**759///760/// Unlike [`EntityMut::into_borrow`], this returns untyped reference(s) to761/// component(s), and it's the job of the caller to ensure the correct762/// type(s) are dereferenced (if necessary).763///764/// # Errors765///766/// Returns [`EntityComponentError::MissingComponent`] if the entity does767/// not have a component.768///769/// # Examples770///771/// For examples on how to use this method, see [`EntityRef::get_by_id`].772#[inline]773pub fn into_borrow_by_id<F: DynamicComponentFetch>(774self,775component_ids: F,776) -> Result<F::Ref<'w>, EntityComponentError> {777self.into_readonly().get_by_id(component_ids)778}779780/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for781/// the current entity, based on the given [`ComponentId`]s.782///783/// **You should prefer to use the typed API [`EntityMut::get_mut`] where784/// possible and only use this in cases where the actual component types785/// are not known at compile time.**786///787/// Unlike [`EntityMut::get_mut`], this returns untyped reference(s) to788/// component(s), and it's the job of the caller to ensure the correct789/// type(s) are dereferenced (if necessary).790///791/// # Errors792///793/// - Returns [`EntityComponentError::MissingComponent`] if the entity does794/// not have a component.795/// - Returns [`EntityComponentError::AliasedMutability`] if a component796/// is requested multiple times.797///798/// # Examples799///800/// ## Single [`ComponentId`]801///802/// ```803/// # use bevy_ecs::prelude::*;804/// #805/// # #[derive(Component, PartialEq, Debug)]806/// # pub struct Foo(i32);807/// # let mut world = World::new();808/// let entity = world.spawn(Foo(42)).id();809///810/// // Grab the component ID for `Foo` in whatever way you like.811/// let component_id = world.register_component::<Foo>();812///813/// // Then, get the component by ID.814/// let mut entity_mut = world.entity_mut(entity);815/// let mut ptr = entity_mut.get_mut_by_id(component_id)816/// # .unwrap();817/// # assert_eq!(unsafe { ptr.as_mut().deref_mut::<Foo>() }, &mut Foo(42));818/// ```819///820/// ## Array of [`ComponentId`]s821///822/// ```823/// # use bevy_ecs::prelude::*;824/// #825/// # #[derive(Component, PartialEq, Debug)]826/// # pub struct X(i32);827/// # #[derive(Component, PartialEq, Debug)]828/// # pub struct Y(i32);829/// # let mut world = World::new();830/// let entity = world.spawn((X(42), Y(10))).id();831///832/// // Grab the component IDs for `X` and `Y` in whatever way you like.833/// let x_id = world.register_component::<X>();834/// let y_id = world.register_component::<Y>();835///836/// // Then, get the components by ID. You'll receive a same-sized array.837/// let mut entity_mut = world.entity_mut(entity);838/// let Ok([mut x_ptr, mut y_ptr]) = entity_mut.get_mut_by_id([x_id, y_id]) else {839/// // Up to you to handle if a component is missing from the entity.840/// # unreachable!();841/// };842/// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));843/// ```844///845/// ## Slice of [`ComponentId`]s846///847/// ```848/// # use bevy_ecs::{prelude::*, component::ComponentId, change_detection::MutUntyped};849/// #850/// # #[derive(Component, PartialEq, Debug)]851/// # pub struct X(i32);852/// # #[derive(Component, PartialEq, Debug)]853/// # pub struct Y(i32);854/// # let mut world = World::new();855/// let entity = world.spawn((X(42), Y(10))).id();856///857/// // Grab the component IDs for `X` and `Y` in whatever way you like.858/// let x_id = world.register_component::<X>();859/// let y_id = world.register_component::<Y>();860///861/// // Then, get the components by ID. You'll receive a vec of ptrs.862/// let mut entity_mut = world.entity_mut(entity);863/// let ptrs = entity_mut.get_mut_by_id(&[x_id, y_id] as &[ComponentId])864/// # .unwrap();865/// # let [mut x_ptr, mut y_ptr]: [MutUntyped; 2] = ptrs.try_into().unwrap();866/// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));867/// ```868///869/// ## [`HashSet`] of [`ComponentId`]s870///871/// ```872/// # use bevy_platform::collections::HashSet;873/// # use bevy_ecs::{prelude::*, component::ComponentId};874/// #875/// # #[derive(Component, PartialEq, Debug)]876/// # pub struct X(i32);877/// # #[derive(Component, PartialEq, Debug)]878/// # pub struct Y(i32);879/// # let mut world = World::new();880/// let entity = world.spawn((X(42), Y(10))).id();881///882/// // Grab the component IDs for `X` and `Y` in whatever way you like.883/// let x_id = world.register_component::<X>();884/// let y_id = world.register_component::<Y>();885///886/// // Then, get the components by ID. You'll receive a `HashMap` of ptrs.887/// let mut entity_mut = world.entity_mut(entity);888/// let mut ptrs = entity_mut.get_mut_by_id(&HashSet::from_iter([x_id, y_id]))889/// # .unwrap();890/// # let [Some(mut x_ptr), Some(mut y_ptr)] = ptrs.get_many_mut([&x_id, &y_id]) else { unreachable!() };891/// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));892/// ```893#[inline]894pub fn get_mut_by_id<F: DynamicComponentFetch>(895&mut self,896component_ids: F,897) -> Result<F::Mut<'_>, EntityComponentError> {898// SAFETY:899// - `&mut self` ensures that no references exist to this entity's components.900// - We have exclusive access to all components of this entity.901unsafe { component_ids.fetch_mut(self.cell) }902}903904/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for905/// the current entity, based on the given [`ComponentId`]s.906/// Assumes the given [`ComponentId`]s refer to mutable components.907///908/// **You should prefer to use the typed API [`EntityMut::get_mut_assume_mutable`] where909/// possible and only use this in cases where the actual component types910/// are not known at compile time.**911///912/// Unlike [`EntityMut::get_mut_assume_mutable`], this returns untyped reference(s) to913/// component(s), and it's the job of the caller to ensure the correct914/// type(s) are dereferenced (if necessary).915///916/// # Errors917///918/// - Returns [`EntityComponentError::MissingComponent`] if the entity does919/// not have a component.920/// - Returns [`EntityComponentError::AliasedMutability`] if a component921/// is requested multiple times.922///923/// # Safety924/// It is the callers responsibility to ensure that925/// - the provided [`ComponentId`]s must refer to mutable components.926#[inline]927pub unsafe fn get_mut_assume_mutable_by_id<F: DynamicComponentFetch>(928&mut self,929component_ids: F,930) -> Result<F::Mut<'_>, EntityComponentError> {931// SAFETY:932// - `&mut self` ensures that no references exist to this entity's components.933// - We have exclusive access to all components of this entity.934unsafe { component_ids.fetch_mut_assume_mutable(self.cell) }935}936937/// Returns [untyped mutable reference](MutUntyped) to component for938/// the current entity, based on the given [`ComponentId`].939///940/// Unlike [`EntityMut::get_mut_by_id`], this method borrows &self instead of941/// &mut self, allowing the caller to access multiple components simultaneously.942///943/// # Errors944///945/// - Returns [`EntityComponentError::MissingComponent`] if the entity does946/// not have a component.947/// - Returns [`EntityComponentError::AliasedMutability`] if a component948/// is requested multiple times.949///950/// # Safety951/// It is the callers responsibility to ensure that952/// - the [`UnsafeEntityCell`] has permission to access the component mutably953/// - no other references to the component exist at the same time954#[inline]955pub unsafe fn get_mut_by_id_unchecked<F: DynamicComponentFetch>(956&self,957component_ids: F,958) -> Result<F::Mut<'_>, EntityComponentError> {959// SAFETY:960// - The caller must ensure simultaneous access is limited961// - to components that are mutually independent.962unsafe { component_ids.fetch_mut(self.cell) }963}964965/// Returns [untyped mutable reference](MutUntyped) to component for966/// the current entity, based on the given [`ComponentId`].967/// Assumes the given [`ComponentId`]s refer to mutable components.968///969/// Unlike [`EntityMut::get_mut_assume_mutable_by_id`], this method borrows &self instead of970/// &mut self, allowing the caller to access multiple components simultaneously.971///972/// # Errors973///974/// - Returns [`EntityComponentError::MissingComponent`] if the entity does975/// not have a component.976/// - Returns [`EntityComponentError::AliasedMutability`] if a component977/// is requested multiple times.978///979/// # Safety980/// It is the callers responsibility to ensure that981/// - the [`UnsafeEntityCell`] has permission to access the component mutably982/// - no other references to the component exist at the same time983/// - the provided [`ComponentId`]s must refer to mutable components.984#[inline]985pub unsafe fn get_mut_assume_mutable_by_id_unchecked<F: DynamicComponentFetch>(986&self,987component_ids: F,988) -> Result<F::Mut<'_>, EntityComponentError> {989// SAFETY:990// - The caller must ensure simultaneous access is limited991// - to components that are mutually independent.992unsafe { component_ids.fetch_mut_assume_mutable(self.cell) }993}994995/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)996/// to component(s) with lifetime `'w` for the current entity, based on the997/// given [`ComponentId`]s.998///999/// **You should prefer to use the typed API [`EntityMut::into_mut`] where1000/// possible and only use this in cases where the actual component types1001/// are not known at compile time.**1002///1003/// Unlike [`EntityMut::into_mut`], this returns untyped reference(s) to1004/// component(s), and it's the job of the caller to ensure the correct1005/// type(s) are dereferenced (if necessary).1006///1007/// # Errors1008///1009/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1010/// not have a component.1011/// - Returns [`EntityComponentError::AliasedMutability`] if a component1012/// is requested multiple times.1013///1014/// # Examples1015///1016/// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].1017#[inline]1018pub fn into_mut_by_id<F: DynamicComponentFetch>(1019self,1020component_ids: F,1021) -> Result<F::Mut<'w>, EntityComponentError> {1022// SAFETY:1023// - consuming `self` ensures that no references exist to this entity's components.1024// - We have exclusive access to all components of this entity.1025unsafe { component_ids.fetch_mut(self.cell) }1026}10271028/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)1029/// to component(s) with lifetime `'w` for the current entity, based on the1030/// given [`ComponentId`]s.1031/// Assumes the given [`ComponentId`]s refer to mutable components.1032///1033/// **You should prefer to use the typed API [`EntityMut::into_mut_assume_mutable`] where1034/// possible and only use this in cases where the actual component types1035/// are not known at compile time.**1036///1037/// Unlike [`EntityMut::into_mut_assume_mutable`], this returns untyped reference(s) to1038/// component(s), and it's the job of the caller to ensure the correct1039/// type(s) are dereferenced (if necessary).1040///1041/// # Errors1042///1043/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1044/// not have a component.1045/// - Returns [`EntityComponentError::AliasedMutability`] if a component1046/// is requested multiple times.1047///1048/// # Safety1049/// It is the callers responsibility to ensure that1050/// - the provided [`ComponentId`]s must refer to mutable components.1051#[inline]1052pub unsafe fn into_mut_assume_mutable_by_id<F: DynamicComponentFetch>(1053self,1054component_ids: F,1055) -> Result<F::Mut<'w>, EntityComponentError> {1056// SAFETY:1057// - consuming `self` ensures that no references exist to this entity's components.1058// - We have exclusive access to all components of this entity.1059unsafe { component_ids.fetch_mut_assume_mutable(self.cell) }1060}10611062/// Returns the source code location from which this entity has been spawned.1063pub fn spawned_by(&self) -> MaybeLocation {1064self.cell.spawned_by()1065}10661067/// Returns the [`Tick`] at which this entity has been spawned.1068pub fn spawned_at(&self) -> Tick {1069self.cell.spawned_at()1070}1071}10721073impl<'w> From<&'w mut EntityMut<'_>> for EntityMut<'w> {1074fn from(entity: &'w mut EntityMut<'_>) -> Self {1075entity.reborrow()1076}1077}10781079impl<'w> From<EntityWorldMut<'w>> for EntityMut<'w> {1080fn from(entity: EntityWorldMut<'w>) -> Self {1081// SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.1082unsafe { EntityMut::new(entity.into_unsafe_entity_cell()) }1083}1084}10851086impl<'a> From<&'a mut EntityWorldMut<'_>> for EntityMut<'a> {1087#[inline]1088fn from(entity: &'a mut EntityWorldMut<'_>) -> Self {1089// SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.1090unsafe { EntityMut::new(entity.as_unsafe_entity_cell()) }1091}1092}10931094impl<'a> TryFrom<FilteredEntityMut<'a, '_>> for EntityMut<'a> {1095type Error = TryFromFilteredError;10961097fn try_from(entity: FilteredEntityMut<'a, '_>) -> Result<Self, Self::Error> {1098if !entity.access.has_read_all() {1099Err(TryFromFilteredError::MissingReadAllAccess)1100} else if !entity.access.has_write_all() {1101Err(TryFromFilteredError::MissingWriteAllAccess)1102} else {1103// SAFETY: check above guarantees exclusive access to all components of the entity.1104Ok(unsafe { EntityMut::new(entity.entity) })1105}1106}1107}11081109impl<'a> TryFrom<&'a mut FilteredEntityMut<'_, '_>> for EntityMut<'a> {1110type Error = TryFromFilteredError;11111112fn try_from(entity: &'a mut FilteredEntityMut<'_, '_>) -> Result<Self, Self::Error> {1113if !entity.access.has_read_all() {1114Err(TryFromFilteredError::MissingReadAllAccess)1115} else if !entity.access.has_write_all() {1116Err(TryFromFilteredError::MissingWriteAllAccess)1117} else {1118// SAFETY: check above guarantees exclusive access to all components of the entity.1119Ok(unsafe { EntityMut::new(entity.entity) })1120}1121}1122}11231124impl PartialEq for EntityMut<'_> {1125fn eq(&self, other: &Self) -> bool {1126self.entity() == other.entity()1127}1128}11291130impl Eq for EntityMut<'_> {}11311132impl PartialOrd for EntityMut<'_> {1133/// [`EntityMut`]'s comparison trait implementations match the underlying [`Entity`],1134/// and cannot discern between different worlds.1135fn partial_cmp(&self, other: &Self) -> Option<Ordering> {1136Some(self.cmp(other))1137}1138}11391140impl Ord for EntityMut<'_> {1141fn cmp(&self, other: &Self) -> Ordering {1142self.entity().cmp(&other.entity())1143}1144}11451146impl Hash for EntityMut<'_> {1147fn hash<H: Hasher>(&self, state: &mut H) {1148self.entity().hash(state);1149}1150}11511152impl ContainsEntity for EntityMut<'_> {1153fn entity(&self) -> Entity {1154self.id()1155}1156}11571158// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.1159unsafe impl EntityEquivalent for EntityMut<'_> {}11601161/// A mutable reference to a particular [`Entity`], and the entire world.1162///1163/// This is essentially a performance-optimized `(Entity, &mut World)` tuple,1164/// which caches the [`EntityLocation`] to reduce duplicate lookups.1165///1166/// Since this type provides mutable access to the entire world, only one1167/// [`EntityWorldMut`] can exist at a time for a given world.1168///1169/// See also [`EntityMut`], which allows disjoint mutable access to multiple1170/// entities at once. Unlike `EntityMut`, this type allows adding and1171/// removing components, and despawning the entity.1172pub struct EntityWorldMut<'w> {1173world: &'w mut World,1174entity: Entity,1175location: EntityIdLocation,1176}11771178impl<'w> EntityWorldMut<'w> {1179#[track_caller]1180#[inline(never)]1181#[cold]1182fn panic_despawned(&self) -> ! {1183panic!(1184"Entity {} {}",1185self.entity,1186self.world1187.entities()1188.entity_does_not_exist_error_details(self.entity)1189);1190}11911192#[inline(always)]1193#[track_caller]1194pub(crate) fn assert_not_despawned(&self) {1195if self.location.is_none() {1196self.panic_despawned()1197}1198}11991200#[inline(always)]1201fn as_unsafe_entity_cell_readonly(&self) -> UnsafeEntityCell<'_> {1202let location = self.location();1203let last_change_tick = self.world.last_change_tick;1204let change_tick = self.world.read_change_tick();1205UnsafeEntityCell::new(1206self.world.as_unsafe_world_cell_readonly(),1207self.entity,1208location,1209last_change_tick,1210change_tick,1211)1212}12131214#[inline(always)]1215fn as_unsafe_entity_cell(&mut self) -> UnsafeEntityCell<'_> {1216let location = self.location();1217let last_change_tick = self.world.last_change_tick;1218let change_tick = self.world.change_tick();1219UnsafeEntityCell::new(1220self.world.as_unsafe_world_cell(),1221self.entity,1222location,1223last_change_tick,1224change_tick,1225)1226}12271228#[inline(always)]1229fn into_unsafe_entity_cell(self) -> UnsafeEntityCell<'w> {1230let location = self.location();1231let last_change_tick = self.world.last_change_tick;1232let change_tick = self.world.change_tick();1233UnsafeEntityCell::new(1234self.world.as_unsafe_world_cell(),1235self.entity,1236location,1237last_change_tick,1238change_tick,1239)1240}12411242/// # Safety1243///1244/// - `entity` must be valid for `world`: the generation should match that of the entity at the same index.1245/// - `location` must be sourced from `world`'s `Entities` and must exactly match the location for `entity`1246///1247/// The above is trivially satisfied if `location` was sourced from `world.entities().get(entity)`.1248#[inline]1249pub(crate) unsafe fn new(1250world: &'w mut World,1251entity: Entity,1252location: Option<EntityLocation>,1253) -> Self {1254debug_assert!(world.entities().contains(entity));1255debug_assert_eq!(world.entities().get(entity), location);12561257EntityWorldMut {1258world,1259entity,1260location,1261}1262}12631264/// Consumes `self` and returns read-only access to all of the entity's1265/// components, with the world `'w` lifetime.1266pub fn into_readonly(self) -> EntityRef<'w> {1267EntityRef::from(self)1268}12691270/// Gets read-only access to all of the entity's components.1271#[inline]1272pub fn as_readonly(&self) -> EntityRef<'_> {1273EntityRef::from(self)1274}12751276/// Consumes `self` and returns non-structural mutable access to all of the1277/// entity's components, with the world `'w` lifetime.1278pub fn into_mutable(self) -> EntityMut<'w> {1279EntityMut::from(self)1280}12811282/// Gets non-structural mutable access to all of the entity's components.1283#[inline]1284pub fn as_mutable(&mut self) -> EntityMut<'_> {1285EntityMut::from(self)1286}12871288/// Returns the [ID](Entity) of the current entity.1289#[inline]1290#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]1291pub fn id(&self) -> Entity {1292self.entity1293}12941295/// Gets metadata indicating the location where the current entity is stored.1296///1297/// # Panics1298///1299/// If the entity has been despawned while this `EntityWorldMut` is still alive.1300#[inline]1301pub fn location(&self) -> EntityLocation {1302match self.location {1303Some(loc) => loc,1304None => self.panic_despawned(),1305}1306}13071308/// Returns the archetype that the current entity belongs to.1309///1310/// # Panics1311///1312/// If the entity has been despawned while this `EntityWorldMut` is still alive.1313#[inline]1314pub fn archetype(&self) -> &Archetype {1315let location = self.location();1316&self.world.archetypes[location.archetype_id]1317}13181319/// Returns `true` if the current entity has a component of type `T`.1320/// Otherwise, this returns `false`.1321///1322/// ## Notes1323///1324/// If you do not know the concrete type of a component, consider using1325/// [`Self::contains_id`] or [`Self::contains_type_id`].1326///1327/// # Panics1328///1329/// If the entity has been despawned while this `EntityWorldMut` is still alive.1330#[inline]1331pub fn contains<T: Component>(&self) -> bool {1332self.contains_type_id(TypeId::of::<T>())1333}13341335/// Returns `true` if the current entity has a component identified by `component_id`.1336/// Otherwise, this returns false.1337///1338/// ## Notes1339///1340/// - If you know the concrete type of the component, you should prefer [`Self::contains`].1341/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using1342/// [`Self::contains_type_id`].1343///1344/// # Panics1345///1346/// If the entity has been despawned while this `EntityWorldMut` is still alive.1347#[inline]1348pub fn contains_id(&self, component_id: ComponentId) -> bool {1349self.as_unsafe_entity_cell_readonly()1350.contains_id(component_id)1351}13521353/// Returns `true` if the current entity has a component with the type identified by `type_id`.1354/// Otherwise, this returns false.1355///1356/// ## Notes1357///1358/// - If you know the concrete type of the component, you should prefer [`Self::contains`].1359/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].1360///1361/// # Panics1362///1363/// If the entity has been despawned while this `EntityWorldMut` is still alive.1364#[inline]1365pub fn contains_type_id(&self, type_id: TypeId) -> bool {1366self.as_unsafe_entity_cell_readonly()1367.contains_type_id(type_id)1368}13691370/// Gets access to the component of type `T` for the current entity.1371/// Returns `None` if the entity does not have a component of type `T`.1372///1373/// # Panics1374///1375/// If the entity has been despawned while this `EntityWorldMut` is still alive.1376#[inline]1377pub fn get<T: Component>(&self) -> Option<&'_ T> {1378self.as_readonly().get()1379}13801381/// Returns read-only components for the current entity that match the query `Q`.1382///1383/// # Panics1384///1385/// If the entity does not have the components required by the query `Q` or if the entity1386/// has been despawned while this `EntityWorldMut` is still alive.1387#[inline]1388pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'_, 'static> {1389self.as_readonly().components::<Q>()1390}13911392/// Returns read-only components for the current entity that match the query `Q`,1393/// or `None` if the entity does not have the components required by the query `Q`.1394///1395/// # Panics1396///1397/// If the entity has been despawned while this `EntityWorldMut` is still alive.1398#[inline]1399pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(1400&self,1401) -> Option<Q::Item<'_, 'static>> {1402self.as_readonly().get_components::<Q>()1403}14041405/// Returns components for the current entity that match the query `Q`,1406/// or `None` if the entity does not have the components required by the query `Q`.1407///1408/// # Example1409///1410/// ```1411/// # use bevy_ecs::prelude::*;1412/// #1413/// #[derive(Component)]1414/// struct X(usize);1415/// #[derive(Component)]1416/// struct Y(usize);1417///1418/// # let mut world = World::default();1419/// let mut entity = world.spawn((X(0), Y(0)));1420/// // Get mutable access to two components at once1421/// // SAFETY: X and Y are different components1422/// let (mut x, mut y) =1423/// unsafe { entity.get_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();1424/// *x = X(1);1425/// *y = Y(1);1426/// // This would trigger undefined behavior, as the `&mut X`s would alias:1427/// // entity.get_components_mut_unchecked::<(&mut X, &mut X)>();1428/// ```1429///1430/// # Safety1431/// It is the caller's responsibility to ensure that1432/// the `QueryData` does not provide aliasing mutable references to the same component.1433pub unsafe fn get_components_mut_unchecked<Q: ReleaseStateQueryData>(1434&mut self,1435) -> Option<Q::Item<'_, 'static>> {1436// SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component1437unsafe { self.as_mutable().into_components_mut_unchecked::<Q>() }1438}14391440/// Consumes self and returns components for the current entity that match the query `Q` for the world lifetime `'w`,1441/// or `None` if the entity does not have the components required by the query `Q`.1442///1443/// # Example1444///1445/// ```1446/// # use bevy_ecs::prelude::*;1447/// #1448/// #[derive(Component)]1449/// struct X(usize);1450/// #[derive(Component)]1451/// struct Y(usize);1452///1453/// # let mut world = World::default();1454/// let mut entity = world.spawn((X(0), Y(0)));1455/// // Get mutable access to two components at once1456/// // SAFETY: X and Y are different components1457/// let (mut x, mut y) =1458/// unsafe { entity.into_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();1459/// *x = X(1);1460/// *y = Y(1);1461/// // This would trigger undefined behavior, as the `&mut X`s would alias:1462/// // entity.into_components_mut_unchecked::<(&mut X, &mut X)>();1463/// ```1464///1465/// # Safety1466/// It is the caller's responsibility to ensure that1467/// the `QueryData` does not provide aliasing mutable references to the same component.1468pub unsafe fn into_components_mut_unchecked<Q: ReleaseStateQueryData>(1469self,1470) -> Option<Q::Item<'w, 'static>> {1471// SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component1472unsafe { self.into_mutable().into_components_mut_unchecked::<Q>() }1473}14741475/// Consumes `self` and gets access to the component of type `T` with1476/// the world `'w` lifetime for the current entity.1477/// Returns `None` if the entity does not have a component of type `T`.1478///1479/// # Panics1480///1481/// If the entity has been despawned while this `EntityWorldMut` is still alive.1482#[inline]1483pub fn into_borrow<T: Component>(self) -> Option<&'w T> {1484self.into_readonly().get()1485}14861487/// Gets access to the component of type `T` for the current entity,1488/// including change detection information as a [`Ref`].1489///1490/// Returns `None` if the entity does not have a component of type `T`.1491///1492/// # Panics1493///1494/// If the entity has been despawned while this `EntityWorldMut` is still alive.1495#[inline]1496pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {1497self.as_readonly().get_ref()1498}14991500/// Consumes `self` and gets access to the component of type `T`1501/// with the world `'w` lifetime for the current entity,1502/// including change detection information as a [`Ref`].1503///1504/// Returns `None` if the entity does not have a component of type `T`.1505///1506/// # Panics1507///1508/// If the entity has been despawned while this `EntityWorldMut` is still alive.1509#[inline]1510pub fn into_ref<T: Component>(self) -> Option<Ref<'w, T>> {1511self.into_readonly().get_ref()1512}15131514/// Gets mutable access to the component of type `T` for the current entity.1515/// Returns `None` if the entity does not have a component of type `T`.1516///1517/// # Panics1518///1519/// If the entity has been despawned while this `EntityWorldMut` is still alive.1520#[inline]1521pub fn get_mut<T: Component<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {1522self.as_mutable().into_mut()1523}15241525/// Temporarily removes a [`Component`] `T` from this [`Entity`] and runs the1526/// provided closure on it, returning the result if `T` was available.1527/// This will trigger the `Remove` and `Replace` component hooks without1528/// causing an archetype move.1529///1530/// This is most useful with immutable components, where removal and reinsertion1531/// is the only way to modify a value.1532///1533/// If you do not need to ensure the above hooks are triggered, and your component1534/// is mutable, prefer using [`get_mut`](EntityWorldMut::get_mut).1535///1536/// # Examples1537///1538/// ```rust1539/// # use bevy_ecs::prelude::*;1540/// #1541/// #[derive(Component, PartialEq, Eq, Debug)]1542/// #[component(immutable)]1543/// struct Foo(bool);1544///1545/// # let mut world = World::default();1546/// # world.register_component::<Foo>();1547/// #1548/// # let entity = world.spawn(Foo(false)).id();1549/// #1550/// # let mut entity = world.entity_mut(entity);1551/// #1552/// # assert_eq!(entity.get::<Foo>(), Some(&Foo(false)));1553/// #1554/// entity.modify_component(|foo: &mut Foo| {1555/// foo.0 = true;1556/// });1557/// #1558/// # assert_eq!(entity.get::<Foo>(), Some(&Foo(true)));1559/// ```1560///1561/// # Panics1562///1563/// If the entity has been despawned while this `EntityWorldMut` is still alive.1564#[inline]1565pub fn modify_component<T: Component, R>(&mut self, f: impl FnOnce(&mut T) -> R) -> Option<R> {1566self.assert_not_despawned();15671568let result = self1569.world1570.modify_component(self.entity, f)1571.expect("entity access must be valid")?;15721573self.update_location();15741575Some(result)1576}15771578/// Temporarily removes a [`Component`] `T` from this [`Entity`] and runs the1579/// provided closure on it, returning the result if `T` was available.1580/// This will trigger the `Remove` and `Replace` component hooks without1581/// causing an archetype move.1582///1583/// This is most useful with immutable components, where removal and reinsertion1584/// is the only way to modify a value.1585///1586/// If you do not need to ensure the above hooks are triggered, and your component1587/// is mutable, prefer using [`get_mut`](EntityWorldMut::get_mut).1588///1589/// # Panics1590///1591/// If the entity has been despawned while this `EntityWorldMut` is still alive.1592#[inline]1593pub fn modify_component_by_id<R>(1594&mut self,1595component_id: ComponentId,1596f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,1597) -> Option<R> {1598self.assert_not_despawned();15991600let result = self1601.world1602.modify_component_by_id(self.entity, component_id, f)1603.expect("entity access must be valid")?;16041605self.update_location();16061607Some(result)1608}16091610/// Gets mutable access to the component of type `T` for the current entity.1611/// Returns `None` if the entity does not have a component of type `T`.1612///1613/// # Safety1614///1615/// - `T` must be a mutable component1616#[inline]1617pub unsafe fn get_mut_assume_mutable<T: Component>(&mut self) -> Option<Mut<'_, T>> {1618self.as_mutable().into_mut_assume_mutable()1619}16201621/// Consumes `self` and gets mutable access to the component of type `T`1622/// with the world `'w` lifetime for the current entity.1623/// Returns `None` if the entity does not have a component of type `T`.1624///1625/// # Panics1626///1627/// If the entity has been despawned while this `EntityWorldMut` is still alive.1628#[inline]1629pub fn into_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {1630// SAFETY: consuming `self` implies exclusive access1631unsafe { self.into_unsafe_entity_cell().get_mut() }1632}16331634/// Consumes `self` and gets mutable access to the component of type `T`1635/// with the world `'w` lifetime for the current entity.1636/// Returns `None` if the entity does not have a component of type `T`.1637///1638/// # Panics1639///1640/// If the entity has been despawned while this `EntityWorldMut` is still alive.1641///1642/// # Safety1643///1644/// - `T` must be a mutable component1645#[inline]1646pub unsafe fn into_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {1647// SAFETY: consuming `self` implies exclusive access1648unsafe { self.into_unsafe_entity_cell().get_mut_assume_mutable() }1649}16501651/// Gets a reference to the resource of the given type1652///1653/// # Panics1654///1655/// Panics if the resource does not exist.1656/// Use [`get_resource`](EntityWorldMut::get_resource) instead if you want to handle this case.1657#[inline]1658#[track_caller]1659pub fn resource<R: Resource>(&self) -> &R {1660self.world.resource::<R>()1661}16621663/// Gets a mutable reference to the resource of the given type1664///1665/// # Panics1666///1667/// Panics if the resource does not exist.1668/// Use [`get_resource_mut`](World::get_resource_mut) instead if you want to handle this case.1669///1670/// If you want to instead insert a value if the resource does not exist,1671/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).1672#[inline]1673#[track_caller]1674pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {1675self.world.resource_mut::<R>()1676}16771678/// Gets a reference to the resource of the given type if it exists1679#[inline]1680pub fn get_resource<R: Resource>(&self) -> Option<&R> {1681self.world.get_resource()1682}16831684/// Gets a mutable reference to the resource of the given type if it exists1685#[inline]1686pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {1687self.world.get_resource_mut()1688}16891690/// Temporarily removes the requested resource from the [`World`], runs custom user code,1691/// then re-adds the resource before returning.1692///1693/// # Panics1694///1695/// Panics if the resource does not exist.1696/// Use [`try_resource_scope`](Self::try_resource_scope) instead if you want to handle this case.1697///1698/// See [`World::resource_scope`] for further details.1699#[track_caller]1700pub fn resource_scope<R: Resource, U>(1701&mut self,1702f: impl FnOnce(&mut EntityWorldMut, Mut<R>) -> U,1703) -> U {1704let id = self.id();1705self.world_scope(|world| {1706world.resource_scope(|world, res| {1707// Acquiring a new EntityWorldMut here and using that instead of `self` is fine because1708// the outer `world_scope` will handle updating our location if it gets changed by the user code1709let mut this = world.entity_mut(id);1710f(&mut this, res)1711})1712})1713}17141715/// Temporarily removes the requested resource from the [`World`] if it exists, runs custom user code,1716/// then re-adds the resource before returning. Returns `None` if the resource does not exist in the [`World`].1717///1718/// See [`World::try_resource_scope`] for further details.1719pub fn try_resource_scope<R: Resource, U>(1720&mut self,1721f: impl FnOnce(&mut EntityWorldMut, Mut<R>) -> U,1722) -> Option<U> {1723let id = self.id();1724self.world_scope(|world| {1725world.try_resource_scope(|world, res| {1726// Acquiring a new EntityWorldMut here and using that instead of `self` is fine because1727// the outer `world_scope` will handle updating our location if it gets changed by the user code1728let mut this = world.entity_mut(id);1729f(&mut this, res)1730})1731})1732}17331734/// Retrieves the change ticks for the given component. This can be useful for implementing change1735/// detection in custom runtimes.1736///1737/// # Panics1738///1739/// If the entity has been despawned while this `EntityWorldMut` is still alive.1740#[inline]1741pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {1742self.as_readonly().get_change_ticks::<T>()1743}17441745/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change1746/// detection in custom runtimes.1747///1748/// **You should prefer to use the typed API [`EntityWorldMut::get_change_ticks`] where possible and only1749/// use this in cases where the actual component types are not known at1750/// compile time.**1751///1752/// # Panics1753///1754/// If the entity has been despawned while this `EntityWorldMut` is still alive.1755#[inline]1756pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {1757self.as_readonly().get_change_ticks_by_id(component_id)1758}17591760/// Returns [untyped read-only reference(s)](Ptr) to component(s) for the1761/// current entity, based on the given [`ComponentId`]s.1762///1763/// **You should prefer to use the typed API [`EntityWorldMut::get`] where1764/// possible and only use this in cases where the actual component types1765/// are not known at compile time.**1766///1767/// Unlike [`EntityWorldMut::get`], this returns untyped reference(s) to1768/// component(s), and it's the job of the caller to ensure the correct1769/// type(s) are dereferenced (if necessary).1770///1771/// # Errors1772///1773/// Returns [`EntityComponentError::MissingComponent`] if the entity does1774/// not have a component.1775///1776/// # Examples1777///1778/// For examples on how to use this method, see [`EntityRef::get_by_id`].1779///1780/// # Panics1781///1782/// If the entity has been despawned while this `EntityWorldMut` is still alive.1783#[inline]1784pub fn get_by_id<F: DynamicComponentFetch>(1785&self,1786component_ids: F,1787) -> Result<F::Ref<'_>, EntityComponentError> {1788self.as_readonly().get_by_id(component_ids)1789}17901791/// Consumes `self` and returns [untyped read-only reference(s)](Ptr) to1792/// component(s) with lifetime `'w` for the current entity, based on the1793/// given [`ComponentId`]s.1794///1795/// **You should prefer to use the typed API [`EntityWorldMut::into_borrow`]1796/// where possible and only use this in cases where the actual component1797/// types are not known at compile time.**1798///1799/// Unlike [`EntityWorldMut::into_borrow`], this returns untyped reference(s) to1800/// component(s), and it's the job of the caller to ensure the correct1801/// type(s) are dereferenced (if necessary).1802///1803/// # Errors1804///1805/// Returns [`EntityComponentError::MissingComponent`] if the entity does1806/// not have a component.1807///1808/// # Examples1809///1810/// For examples on how to use this method, see [`EntityRef::get_by_id`].1811///1812/// # Panics1813///1814/// If the entity has been despawned while this `EntityWorldMut` is still alive.1815#[inline]1816pub fn into_borrow_by_id<F: DynamicComponentFetch>(1817self,1818component_ids: F,1819) -> Result<F::Ref<'w>, EntityComponentError> {1820self.into_readonly().get_by_id(component_ids)1821}18221823/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for1824/// the current entity, based on the given [`ComponentId`]s.1825///1826/// **You should prefer to use the typed API [`EntityWorldMut::get_mut`] where1827/// possible and only use this in cases where the actual component types1828/// are not known at compile time.**1829///1830/// Unlike [`EntityWorldMut::get_mut`], this returns untyped reference(s) to1831/// component(s), and it's the job of the caller to ensure the correct1832/// type(s) are dereferenced (if necessary).1833///1834/// # Errors1835///1836/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1837/// not have a component.1838/// - Returns [`EntityComponentError::AliasedMutability`] if a component1839/// is requested multiple times.1840///1841/// # Examples1842///1843/// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].1844///1845/// # Panics1846///1847/// If the entity has been despawned while this `EntityWorldMut` is still alive.1848#[inline]1849pub fn get_mut_by_id<F: DynamicComponentFetch>(1850&mut self,1851component_ids: F,1852) -> Result<F::Mut<'_>, EntityComponentError> {1853self.as_mutable().into_mut_by_id(component_ids)1854}18551856/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for1857/// the current entity, based on the given [`ComponentId`]s.1858/// Assumes the given [`ComponentId`]s refer to mutable components.1859///1860/// **You should prefer to use the typed API [`EntityWorldMut::get_mut_assume_mutable`] where1861/// possible and only use this in cases where the actual component types1862/// are not known at compile time.**1863///1864/// Unlike [`EntityWorldMut::get_mut_assume_mutable`], this returns untyped reference(s) to1865/// component(s), and it's the job of the caller to ensure the correct1866/// type(s) are dereferenced (if necessary).1867///1868/// # Errors1869///1870/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1871/// not have a component.1872/// - Returns [`EntityComponentError::AliasedMutability`] if a component1873/// is requested multiple times.1874///1875/// # Panics1876///1877/// If the entity has been despawned while this `EntityWorldMut` is still alive.1878///1879/// # Safety1880/// It is the callers responsibility to ensure that1881/// - the provided [`ComponentId`]s must refer to mutable components.1882#[inline]1883pub unsafe fn get_mut_assume_mutable_by_id<F: DynamicComponentFetch>(1884&mut self,1885component_ids: F,1886) -> Result<F::Mut<'_>, EntityComponentError> {1887self.as_mutable()1888.into_mut_assume_mutable_by_id(component_ids)1889}18901891/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)1892/// to component(s) with lifetime `'w` for the current entity, based on the1893/// given [`ComponentId`]s.1894///1895/// **You should prefer to use the typed API [`EntityWorldMut::into_mut`] where1896/// possible and only use this in cases where the actual component types1897/// are not known at compile time.**1898///1899/// Unlike [`EntityWorldMut::into_mut`], this returns untyped reference(s) to1900/// component(s), and it's the job of the caller to ensure the correct1901/// type(s) are dereferenced (if necessary).1902///1903/// # Errors1904///1905/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1906/// not have a component.1907/// - Returns [`EntityComponentError::AliasedMutability`] if a component1908/// is requested multiple times.1909///1910/// # Examples1911///1912/// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].1913///1914/// # Panics1915///1916/// If the entity has been despawned while this `EntityWorldMut` is still alive.1917#[inline]1918pub fn into_mut_by_id<F: DynamicComponentFetch>(1919self,1920component_ids: F,1921) -> Result<F::Mut<'w>, EntityComponentError> {1922self.into_mutable().into_mut_by_id(component_ids)1923}19241925/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)1926/// to component(s) with lifetime `'w` for the current entity, based on the1927/// given [`ComponentId`]s.1928/// Assumes the given [`ComponentId`]s refer to mutable components.1929///1930/// **You should prefer to use the typed API [`EntityWorldMut::into_mut_assume_mutable`] where1931/// possible and only use this in cases where the actual component types1932/// are not known at compile time.**1933///1934/// Unlike [`EntityWorldMut::into_mut_assume_mutable`], this returns untyped reference(s) to1935/// component(s), and it's the job of the caller to ensure the correct1936/// type(s) are dereferenced (if necessary).1937///1938/// # Errors1939///1940/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1941/// not have a component.1942/// - Returns [`EntityComponentError::AliasedMutability`] if a component1943/// is requested multiple times.1944///1945/// # Panics1946///1947/// If the entity has been despawned while this `EntityWorldMut` is still alive.1948///1949/// # Safety1950/// It is the callers responsibility to ensure that1951/// - the provided [`ComponentId`]s must refer to mutable components.1952#[inline]1953pub unsafe fn into_mut_assume_mutable_by_id<F: DynamicComponentFetch>(1954self,1955component_ids: F,1956) -> Result<F::Mut<'w>, EntityComponentError> {1957self.into_mutable()1958.into_mut_assume_mutable_by_id(component_ids)1959}19601961/// Adds a [`Bundle`] of components to the entity.1962///1963/// This will overwrite any previous value(s) of the same component type.1964///1965/// # Panics1966///1967/// If the entity has been despawned while this `EntityWorldMut` is still alive.1968#[track_caller]1969pub fn insert<T: Bundle>(&mut self, bundle: T) -> &mut Self {1970self.insert_with_caller(1971bundle,1972InsertMode::Replace,1973MaybeLocation::caller(),1974RelationshipHookMode::Run,1975)1976}19771978/// Adds a [`Bundle`] of components to the entity.1979/// [`Relationship`](crate::relationship::Relationship) components in the bundle will follow the configuration1980/// in `relationship_hook_mode`.1981///1982/// This will overwrite any previous value(s) of the same component type.1983///1984/// # Warning1985///1986/// This can easily break the integrity of relationships. This is intended to be used for cloning and spawning code internals,1987/// not most user-facing scenarios.1988///1989/// # Panics1990///1991/// If the entity has been despawned while this `EntityWorldMut` is still alive.1992#[track_caller]1993pub fn insert_with_relationship_hook_mode<T: Bundle>(1994&mut self,1995bundle: T,1996relationship_hook_mode: RelationshipHookMode,1997) -> &mut Self {1998self.insert_with_caller(1999bundle,2000InsertMode::Replace,2001MaybeLocation::caller(),2002relationship_hook_mode,2003)2004}20052006/// Adds a [`Bundle`] of components to the entity without overwriting.2007///2008/// This will leave any previous value(s) of the same component type2009/// unchanged.2010///2011/// # Panics2012///2013/// If the entity has been despawned while this `EntityWorldMut` is still alive.2014#[track_caller]2015pub fn insert_if_new<T: Bundle>(&mut self, bundle: T) -> &mut Self {2016self.insert_with_caller(2017bundle,2018InsertMode::Keep,2019MaybeLocation::caller(),2020RelationshipHookMode::Run,2021)2022}20232024/// Split into a new function so we can pass the calling location into the function when using2025/// as a command.2026#[inline]2027pub(crate) fn insert_with_caller<T: Bundle>(2028&mut self,2029bundle: T,2030mode: InsertMode,2031caller: MaybeLocation,2032relationship_hook_mode: RelationshipHookMode,2033) -> &mut Self {2034let location = self.location();2035let change_tick = self.world.change_tick();2036let mut bundle_inserter =2037BundleInserter::new::<T>(self.world, location.archetype_id, change_tick);2038// SAFETY: location matches current entity. `T` matches `bundle_info`2039let (location, after_effect) = unsafe {2040bundle_inserter.insert(2041self.entity,2042location,2043bundle,2044mode,2045caller,2046relationship_hook_mode,2047)2048};2049self.location = Some(location);2050self.world.flush();2051self.update_location();2052after_effect.apply(self);2053self2054}20552056/// Inserts a dynamic [`Component`] into the entity.2057///2058/// This will overwrite any previous value(s) of the same component type.2059///2060/// You should prefer to use the typed API [`EntityWorldMut::insert`] where possible.2061///2062/// # Safety2063///2064/// - [`ComponentId`] must be from the same world as [`EntityWorldMut`]2065/// - [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]2066///2067/// # Panics2068///2069/// If the entity has been despawned while this `EntityWorldMut` is still alive.2070#[track_caller]2071pub unsafe fn insert_by_id(2072&mut self,2073component_id: ComponentId,2074component: OwningPtr<'_>,2075) -> &mut Self {2076self.insert_by_id_with_caller(2077component_id,2078component,2079InsertMode::Replace,2080MaybeLocation::caller(),2081RelationshipHookMode::Run,2082)2083}20842085/// # Safety2086///2087/// - [`ComponentId`] must be from the same world as [`EntityWorldMut`]2088/// - [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]2089#[inline]2090pub(crate) unsafe fn insert_by_id_with_caller(2091&mut self,2092component_id: ComponentId,2093component: OwningPtr<'_>,2094mode: InsertMode,2095caller: MaybeLocation,2096relationship_hook_insert_mode: RelationshipHookMode,2097) -> &mut Self {2098let location = self.location();2099let change_tick = self.world.change_tick();2100let bundle_id = self.world.bundles.init_component_info(2101&mut self.world.storages,2102&self.world.components,2103component_id,2104);2105let storage_type = self.world.bundles.get_storage_unchecked(bundle_id);21062107let bundle_inserter =2108BundleInserter::new_with_id(self.world, location.archetype_id, bundle_id, change_tick);21092110self.location = Some(insert_dynamic_bundle(2111bundle_inserter,2112self.entity,2113location,2114Some(component).into_iter(),2115Some(storage_type).iter().cloned(),2116mode,2117caller,2118relationship_hook_insert_mode,2119));2120self.world.flush();2121self.update_location();2122self2123}21242125/// Inserts a dynamic [`Bundle`] into the entity.2126///2127/// This will overwrite any previous value(s) of the same component type.2128///2129/// You should prefer to use the typed API [`EntityWorldMut::insert`] where possible.2130/// If your [`Bundle`] only has one component, use the cached API [`EntityWorldMut::insert_by_id`].2131///2132/// If possible, pass a sorted slice of `ComponentId` to maximize caching potential.2133///2134/// # Safety2135/// - Each [`ComponentId`] must be from the same world as [`EntityWorldMut`]2136/// - Each [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]2137///2138/// # Panics2139///2140/// If the entity has been despawned while this `EntityWorldMut` is still alive.2141#[track_caller]2142pub unsafe fn insert_by_ids<'a, I: Iterator<Item = OwningPtr<'a>>>(2143&mut self,2144component_ids: &[ComponentId],2145iter_components: I,2146) -> &mut Self {2147self.insert_by_ids_internal(component_ids, iter_components, RelationshipHookMode::Run)2148}21492150#[track_caller]2151pub(crate) unsafe fn insert_by_ids_internal<'a, I: Iterator<Item = OwningPtr<'a>>>(2152&mut self,2153component_ids: &[ComponentId],2154iter_components: I,2155relationship_hook_insert_mode: RelationshipHookMode,2156) -> &mut Self {2157let location = self.location();2158let change_tick = self.world.change_tick();2159let bundle_id = self.world.bundles.init_dynamic_info(2160&mut self.world.storages,2161&self.world.components,2162component_ids,2163);2164let mut storage_types =2165core::mem::take(self.world.bundles.get_storages_unchecked(bundle_id));2166let bundle_inserter =2167BundleInserter::new_with_id(self.world, location.archetype_id, bundle_id, change_tick);21682169self.location = Some(insert_dynamic_bundle(2170bundle_inserter,2171self.entity,2172location,2173iter_components,2174(*storage_types).iter().cloned(),2175InsertMode::Replace,2176MaybeLocation::caller(),2177relationship_hook_insert_mode,2178));2179*self.world.bundles.get_storages_unchecked(bundle_id) = core::mem::take(&mut storage_types);2180self.world.flush();2181self.update_location();2182self2183}21842185/// Removes all components in the [`Bundle`] from the entity and returns their previous values.2186///2187/// **Note:** If the entity does not have every component in the bundle, this method will not2188/// remove any of them.2189///2190/// # Panics2191///2192/// If the entity has been despawned while this `EntityWorldMut` is still alive.2193#[must_use]2194#[track_caller]2195pub fn take<T: Bundle + BundleFromComponents>(&mut self) -> Option<T> {2196let location = self.location();2197let entity = self.entity;21982199let mut remover =2200// SAFETY: The archetype id must be valid since this entity is in it.2201unsafe { BundleRemover::new::<T>(self.world, location.archetype_id, true) }?;2202// SAFETY: The passed location has the sane archetype as the remover, since they came from the same location.2203let (new_location, result) = unsafe {2204remover.remove(2205entity,2206location,2207MaybeLocation::caller(),2208|sets, table, components, bundle_components| {2209let mut bundle_components = bundle_components.iter().copied();2210(2211false,2212T::from_components(&mut (sets, table), &mut |(sets, table)| {2213let component_id = bundle_components.next().unwrap();2214// SAFETY: the component existed to be removed, so its id must be valid.2215let component_info = components.get_info_unchecked(component_id);2216match component_info.storage_type() {2217StorageType::Table => {2218table2219.as_mut()2220// SAFETY: The table must be valid if the component is in it.2221.debug_checked_unwrap()2222// SAFETY: The remover is cleaning this up.2223.take_component(component_id, location.table_row)2224}2225StorageType::SparseSet => sets2226.get_mut(component_id)2227.unwrap()2228.remove_and_forget(entity)2229.unwrap(),2230}2231}),2232)2233},2234)2235};2236self.location = Some(new_location);22372238self.world.flush();2239self.update_location();2240Some(result)2241}22422243/// Removes any components in the [`Bundle`] from the entity.2244///2245/// See [`EntityCommands::remove`](crate::system::EntityCommands::remove) for more details.2246///2247/// # Panics2248///2249/// If the entity has been despawned while this `EntityWorldMut` is still alive.2250#[track_caller]2251pub fn remove<T: Bundle>(&mut self) -> &mut Self {2252self.remove_with_caller::<T>(MaybeLocation::caller())2253}22542255#[inline]2256pub(crate) fn remove_with_caller<T: Bundle>(&mut self, caller: MaybeLocation) -> &mut Self {2257let location = self.location();22582259let Some(mut remover) =2260// SAFETY: The archetype id must be valid since this entity is in it.2261(unsafe { BundleRemover::new::<T>(self.world, location.archetype_id, false) })2262else {2263return self;2264};2265// SAFETY: The remover archetype came from the passed location and the removal can not fail.2266let new_location = unsafe {2267remover.remove(2268self.entity,2269location,2270caller,2271BundleRemover::empty_pre_remove,2272)2273}2274.0;22752276self.location = Some(new_location);2277self.world.flush();2278self.update_location();2279self2280}22812282/// Removes all components in the [`Bundle`] and remove all required components for each component in the bundle2283///2284/// # Panics2285///2286/// If the entity has been despawned while this `EntityWorldMut` is still alive.2287#[track_caller]2288pub fn remove_with_requires<T: Bundle>(&mut self) -> &mut Self {2289self.remove_with_requires_with_caller::<T>(MaybeLocation::caller())2290}22912292pub(crate) fn remove_with_requires_with_caller<T: Bundle>(2293&mut self,2294caller: MaybeLocation,2295) -> &mut Self {2296let location = self.location();2297let bundle_id = self.world.register_contributed_bundle_info::<T>();22982299// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.2300let Some(mut remover) = (unsafe {2301BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)2302}) else {2303return self;2304};2305// SAFETY: The remover archetype came from the passed location and the removal can not fail.2306let new_location = unsafe {2307remover.remove(2308self.entity,2309location,2310caller,2311BundleRemover::empty_pre_remove,2312)2313}2314.0;23152316self.location = Some(new_location);2317self.world.flush();2318self.update_location();2319self2320}23212322/// Removes any components except those in the [`Bundle`] (and its Required Components) from the entity.2323///2324/// See [`EntityCommands::retain`](crate::system::EntityCommands::retain) for more details.2325///2326/// # Panics2327///2328/// If the entity has been despawned while this `EntityWorldMut` is still alive.2329#[track_caller]2330pub fn retain<T: Bundle>(&mut self) -> &mut Self {2331self.retain_with_caller::<T>(MaybeLocation::caller())2332}23332334#[inline]2335pub(crate) fn retain_with_caller<T: Bundle>(&mut self, caller: MaybeLocation) -> &mut Self {2336let old_location = self.location();2337let retained_bundle = self.world.register_bundle_info::<T>();2338let archetypes = &mut self.world.archetypes;23392340// SAFETY: `retained_bundle` exists as we just registered it.2341let retained_bundle_info = unsafe { self.world.bundles.get_unchecked(retained_bundle) };2342let old_archetype = &mut archetypes[old_location.archetype_id];23432344// PERF: this could be stored in an Archetype Edge2345let to_remove = &old_archetype2346.iter_components()2347.filter(|c| !retained_bundle_info.contributed_components().contains(c))2348.collect::<Vec<_>>();2349let remove_bundle = self.world.bundles.init_dynamic_info(2350&mut self.world.storages,2351&self.world.components,2352to_remove,2353);23542355// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.2356let Some(mut remover) = (unsafe {2357BundleRemover::new_with_id(self.world, old_location.archetype_id, remove_bundle, false)2358}) else {2359return self;2360};2361// SAFETY: The remover archetype came from the passed location and the removal can not fail.2362let new_location = unsafe {2363remover.remove(2364self.entity,2365old_location,2366caller,2367BundleRemover::empty_pre_remove,2368)2369}2370.0;23712372self.location = Some(new_location);2373self.world.flush();2374self.update_location();2375self2376}23772378/// Removes a dynamic [`Component`] from the entity if it exists.2379///2380/// You should prefer to use the typed API [`EntityWorldMut::remove`] where possible.2381///2382/// # Panics2383///2384/// Panics if the provided [`ComponentId`] does not exist in the [`World`] or if the2385/// entity has been despawned while this `EntityWorldMut` is still alive.2386#[track_caller]2387pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {2388self.remove_by_id_with_caller(component_id, MaybeLocation::caller())2389}23902391#[inline]2392pub(crate) fn remove_by_id_with_caller(2393&mut self,2394component_id: ComponentId,2395caller: MaybeLocation,2396) -> &mut Self {2397let location = self.location();2398let components = &mut self.world.components;23992400let bundle_id = self.world.bundles.init_component_info(2401&mut self.world.storages,2402components,2403component_id,2404);24052406// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.2407let Some(mut remover) = (unsafe {2408BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)2409}) else {2410return self;2411};2412// SAFETY: The remover archetype came from the passed location and the removal can not fail.2413let new_location = unsafe {2414remover.remove(2415self.entity,2416location,2417caller,2418BundleRemover::empty_pre_remove,2419)2420}2421.0;24222423self.location = Some(new_location);2424self.world.flush();2425self.update_location();2426self2427}24282429/// Removes a dynamic bundle from the entity if it exists.2430///2431/// You should prefer to use the typed API [`EntityWorldMut::remove`] where possible.2432///2433/// # Panics2434///2435/// Panics if any of the provided [`ComponentId`]s do not exist in the [`World`] or if the2436/// entity has been despawned while this `EntityWorldMut` is still alive.2437#[track_caller]2438pub fn remove_by_ids(&mut self, component_ids: &[ComponentId]) -> &mut Self {2439self.remove_by_ids_with_caller(2440component_ids,2441MaybeLocation::caller(),2442RelationshipHookMode::Run,2443BundleRemover::empty_pre_remove,2444)2445}24462447#[inline]2448pub(crate) fn remove_by_ids_with_caller<T: 'static>(2449&mut self,2450component_ids: &[ComponentId],2451caller: MaybeLocation,2452relationship_hook_mode: RelationshipHookMode,2453pre_remove: impl FnOnce(2454&mut SparseSets,2455Option<&mut Table>,2456&Components,2457&[ComponentId],2458) -> (bool, T),2459) -> &mut Self {2460let location = self.location();2461let components = &mut self.world.components;24622463let bundle_id = self.world.bundles.init_dynamic_info(2464&mut self.world.storages,2465components,2466component_ids,2467);24682469// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.2470let Some(mut remover) = (unsafe {2471BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)2472}) else {2473return self;2474};2475remover.relationship_hook_mode = relationship_hook_mode;2476// SAFETY: The remover archetype came from the passed location and the removal can not fail.2477let new_location = unsafe { remover.remove(self.entity, location, caller, pre_remove) }.0;24782479self.location = Some(new_location);2480self.world.flush();2481self.update_location();2482self2483}24842485/// Removes all components associated with the entity.2486///2487/// # Panics2488///2489/// If the entity has been despawned while this `EntityWorldMut` is still alive.2490#[track_caller]2491pub fn clear(&mut self) -> &mut Self {2492self.clear_with_caller(MaybeLocation::caller())2493}24942495#[inline]2496pub(crate) fn clear_with_caller(&mut self, caller: MaybeLocation) -> &mut Self {2497let location = self.location();2498// PERF: this should not be necessary2499let component_ids: Vec<ComponentId> = self.archetype().components().to_vec();2500let components = &mut self.world.components;25012502let bundle_id = self.world.bundles.init_dynamic_info(2503&mut self.world.storages,2504components,2505component_ids.as_slice(),2506);25072508// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.2509let Some(mut remover) = (unsafe {2510BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)2511}) else {2512return self;2513};2514// SAFETY: The remover archetype came from the passed location and the removal can not fail.2515let new_location = unsafe {2516remover.remove(2517self.entity,2518location,2519caller,2520BundleRemover::empty_pre_remove,2521)2522}2523.0;25242525self.location = Some(new_location);2526self.world.flush();2527self.update_location();2528self2529}25302531/// Despawns the current entity.2532///2533/// See [`World::despawn`] for more details.2534///2535/// # Note2536///2537/// This will also despawn any [`Children`](crate::hierarchy::Children) entities, and any other [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured2538/// to despawn descendants. This results in "recursive despawn" behavior.2539///2540/// # Panics2541///2542/// If the entity has been despawned while this `EntityWorldMut` is still alive.2543#[track_caller]2544pub fn despawn(self) {2545self.despawn_with_caller(MaybeLocation::caller());2546}25472548pub(crate) fn despawn_with_caller(self, caller: MaybeLocation) {2549let location = self.location();2550let world = self.world;2551let archetype = &world.archetypes[location.archetype_id];25522553// SAFETY: Archetype cannot be mutably aliased by DeferredWorld2554let (archetype, mut deferred_world) = unsafe {2555let archetype: *const Archetype = archetype;2556let world = world.as_unsafe_world_cell();2557(&*archetype, world.into_deferred())2558};25592560// SAFETY: All components in the archetype exist in world2561unsafe {2562if archetype.has_despawn_observer() {2563// SAFETY: the DESPAWN event_key corresponds to the Despawn event's type2564deferred_world.trigger_raw(2565DESPAWN,2566&mut Despawn {2567entity: self.entity,2568},2569&mut EntityComponentsTrigger {2570components: archetype.components(),2571},2572caller,2573);2574}2575deferred_world.trigger_on_despawn(2576archetype,2577self.entity,2578archetype.iter_components(),2579caller,2580);2581if archetype.has_replace_observer() {2582// SAFETY: the REPLACE event_key corresponds to the Replace event's type2583deferred_world.trigger_raw(2584REPLACE,2585&mut Replace {2586entity: self.entity,2587},2588&mut EntityComponentsTrigger {2589components: archetype.components(),2590},2591caller,2592);2593}2594deferred_world.trigger_on_replace(2595archetype,2596self.entity,2597archetype.iter_components(),2598caller,2599RelationshipHookMode::Run,2600);2601if archetype.has_remove_observer() {2602// SAFETY: the REMOVE event_key corresponds to the Remove event's type2603deferred_world.trigger_raw(2604REMOVE,2605&mut Remove {2606entity: self.entity,2607},2608&mut EntityComponentsTrigger {2609components: archetype.components(),2610},2611caller,2612);2613}2614deferred_world.trigger_on_remove(2615archetype,2616self.entity,2617archetype.iter_components(),2618caller,2619);2620}26212622for component_id in archetype.iter_components() {2623world.removed_components.write(component_id, self.entity);2624}26252626// Observers and on_remove hooks may reserve new entities, which2627// requires a flush before Entities::free may be called.2628world.flush_entities();26292630let location = world2631.entities2632.free(self.entity)2633.flatten()2634.expect("entity should exist at this point.");2635let table_row;2636let moved_entity;2637let change_tick = world.change_tick();26382639{2640let archetype = &mut world.archetypes[location.archetype_id];2641let remove_result = archetype.swap_remove(location.archetype_row);2642if let Some(swapped_entity) = remove_result.swapped_entity {2643let swapped_location = world.entities.get(swapped_entity).unwrap();2644// SAFETY: swapped_entity is valid and the swapped entity's components are2645// moved to the new location immediately after.2646unsafe {2647world.entities.set(2648swapped_entity.index(),2649Some(EntityLocation {2650archetype_id: swapped_location.archetype_id,2651archetype_row: location.archetype_row,2652table_id: swapped_location.table_id,2653table_row: swapped_location.table_row,2654}),2655);2656world2657.entities2658.mark_spawn_despawn(swapped_entity.index(), caller, change_tick);2659}2660}2661table_row = remove_result.table_row;26622663for component_id in archetype.sparse_set_components() {2664// set must have existed for the component to be added.2665let sparse_set = world.storages.sparse_sets.get_mut(component_id).unwrap();2666sparse_set.remove(self.entity);2667}2668// SAFETY: table rows stored in archetypes always exist2669moved_entity = unsafe {2670world.storages.tables[archetype.table_id()].swap_remove_unchecked(table_row)2671};2672};26732674if let Some(moved_entity) = moved_entity {2675let moved_location = world.entities.get(moved_entity).unwrap();2676// SAFETY: `moved_entity` is valid and the provided `EntityLocation` accurately reflects2677// the current location of the entity and its component data.2678unsafe {2679world.entities.set(2680moved_entity.index(),2681Some(EntityLocation {2682archetype_id: moved_location.archetype_id,2683archetype_row: moved_location.archetype_row,2684table_id: moved_location.table_id,2685table_row,2686}),2687);2688world2689.entities2690.mark_spawn_despawn(moved_entity.index(), caller, change_tick);2691}2692world.archetypes[moved_location.archetype_id]2693.set_entity_table_row(moved_location.archetype_row, table_row);2694}2695world.flush();2696}26972698/// Ensures any commands triggered by the actions of Self are applied, equivalent to [`World::flush`]2699pub fn flush(self) -> Entity {2700self.world.flush();2701self.entity2702}27032704/// Gets read-only access to the world that the current entity belongs to.2705#[inline]2706pub fn world(&self) -> &World {2707self.world2708}27092710/// Returns this entity's world.2711///2712/// See [`EntityWorldMut::world_scope`] or [`EntityWorldMut::into_world_mut`] for a safe alternative.2713///2714/// # Safety2715/// Caller must not modify the world in a way that changes the current entity's location2716/// If the caller _does_ do something that could change the location, `self.update_location()`2717/// must be called before using any other methods on this [`EntityWorldMut`].2718#[inline]2719pub unsafe fn world_mut(&mut self) -> &mut World {2720self.world2721}27222723/// Returns this entity's [`World`], consuming itself.2724#[inline]2725pub fn into_world_mut(self) -> &'w mut World {2726self.world2727}27282729/// Gives mutable access to this entity's [`World`] in a temporary scope.2730/// This is a safe alternative to using [`EntityWorldMut::world_mut`].2731///2732/// # Examples2733///2734/// ```2735/// # use bevy_ecs::prelude::*;2736/// #[derive(Resource, Default, Clone, Copy)]2737/// struct R(u32);2738///2739/// # let mut world = World::new();2740/// # world.init_resource::<R>();2741/// # let mut entity = world.spawn_empty();2742/// // This closure gives us temporary access to the world.2743/// let new_r = entity.world_scope(|world: &mut World| {2744/// // Mutate the world while we have access to it.2745/// let mut r = world.resource_mut::<R>();2746/// r.0 += 1;2747///2748/// // Return a value from the world before giving it back to the `EntityWorldMut`.2749/// *r2750/// });2751/// # assert_eq!(new_r.0, 1);2752/// ```2753pub fn world_scope<U>(&mut self, f: impl FnOnce(&mut World) -> U) -> U {2754struct Guard<'w, 'a> {2755entity_mut: &'a mut EntityWorldMut<'w>,2756}27572758impl Drop for Guard<'_, '_> {2759#[inline]2760fn drop(&mut self) {2761self.entity_mut.update_location();2762}2763}27642765// When `guard` is dropped at the end of this scope,2766// it will update the cached `EntityLocation` for this instance.2767// This will run even in case the closure `f` unwinds.2768let guard = Guard { entity_mut: self };2769f(guard.entity_mut.world)2770}27712772/// Updates the internal entity location to match the current location in the internal2773/// [`World`].2774///2775/// This is *only* required when using the unsafe function [`EntityWorldMut::world_mut`],2776/// which enables the location to change.2777pub fn update_location(&mut self) {2778self.location = self.world.entities().get(self.entity);2779}27802781/// Returns if the entity has been despawned.2782///2783/// Normally it shouldn't be needed to explicitly check if the entity has been despawned2784/// between commands as this shouldn't happen. However, for some special cases where it2785/// is known that a hook or an observer might despawn the entity while a [`EntityWorldMut`]2786/// reference is still held, this method can be used to check if the entity is still alive2787/// to avoid panicking when calling further methods.2788#[inline]2789pub fn is_despawned(&self) -> bool {2790self.location.is_none()2791}27922793/// Gets an Entry into the world for this entity and component for in-place manipulation.2794///2795/// The type parameter specifies which component to get.2796///2797/// # Examples2798///2799/// ```2800/// # use bevy_ecs::prelude::*;2801/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]2802/// struct Comp(u32);2803///2804/// # let mut world = World::new();2805/// let mut entity = world.spawn_empty();2806/// entity.entry().or_insert_with(|| Comp(4));2807/// # let entity_id = entity.id();2808/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 4);2809///2810/// # let mut entity = world.get_entity_mut(entity_id).unwrap();2811/// entity.entry::<Comp>().and_modify(|mut c| c.0 += 1);2812/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 5);2813/// ```2814///2815/// # Panics2816///2817/// If the entity has been despawned while this `EntityWorldMut` is still alive.2818pub fn entry<'a, T: Component>(&'a mut self) -> ComponentEntry<'w, 'a, T> {2819if self.contains::<T>() {2820ComponentEntry::Occupied(OccupiedComponentEntry {2821entity_world: self,2822_marker: PhantomData,2823})2824} else {2825ComponentEntry::Vacant(VacantComponentEntry {2826entity_world: self,2827_marker: PhantomData,2828})2829}2830}28312832/// Creates an [`Observer`] watching for an [`EntityEvent`] of type `E` whose [`EntityEvent::event_target`]2833/// targets this entity.2834///2835/// # Panics2836///2837/// If the entity has been despawned while this `EntityWorldMut` is still alive.2838///2839/// Panics if the given system is an exclusive system.2840#[track_caller]2841pub fn observe<E: EntityEvent, B: Bundle, M>(2842&mut self,2843observer: impl IntoObserverSystem<E, B, M>,2844) -> &mut Self {2845self.observe_with_caller(observer, MaybeLocation::caller())2846}28472848pub(crate) fn observe_with_caller<E: EntityEvent, B: Bundle, M>(2849&mut self,2850observer: impl IntoObserverSystem<E, B, M>,2851caller: MaybeLocation,2852) -> &mut Self {2853self.assert_not_despawned();2854self.world2855.spawn_with_caller(Observer::new(observer).with_entity(self.entity), caller);2856self.world.flush();2857self.update_location();2858self2859}28602861/// Clones parts of an entity (components, observers, etc.) onto another entity,2862/// configured through [`EntityClonerBuilder`].2863///2864/// The other entity will receive all the components of the original that implement2865/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are2866/// [denied](EntityClonerBuilder::deny) in the `config`.2867///2868/// # Example2869///2870/// ```2871/// # use bevy_ecs::prelude::*;2872/// # #[derive(Component, Clone, PartialEq, Debug)]2873/// # struct ComponentA;2874/// # #[derive(Component, Clone, PartialEq, Debug)]2875/// # struct ComponentB;2876/// # let mut world = World::new();2877/// # let entity = world.spawn((ComponentA, ComponentB)).id();2878/// # let target = world.spawn_empty().id();2879/// // Clone all components except ComponentA onto the target.2880/// world.entity_mut(entity).clone_with_opt_out(target, |builder| {2881/// builder.deny::<ComponentA>();2882/// });2883/// # assert_eq!(world.get::<ComponentA>(target), None);2884/// # assert_eq!(world.get::<ComponentB>(target), Some(&ComponentB));2885/// ```2886///2887/// See [`EntityClonerBuilder<OptOut>`] for more options.2888///2889/// # Panics2890///2891/// - If this entity has been despawned while this `EntityWorldMut` is still alive.2892/// - If the target entity does not exist.2893pub fn clone_with_opt_out(2894&mut self,2895target: Entity,2896config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,2897) -> &mut Self {2898self.assert_not_despawned();28992900let mut builder = EntityCloner::build_opt_out(self.world);2901config(&mut builder);2902builder.clone_entity(self.entity, target);29032904self.world.flush();2905self.update_location();2906self2907}29082909/// Clones parts of an entity (components, observers, etc.) onto another entity,2910/// configured through [`EntityClonerBuilder`].2911///2912/// The other entity will receive only the components of the original that implement2913/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are2914/// [allowed](EntityClonerBuilder::allow) in the `config`.2915///2916/// # Example2917///2918/// ```2919/// # use bevy_ecs::prelude::*;2920/// # #[derive(Component, Clone, PartialEq, Debug)]2921/// # struct ComponentA;2922/// # #[derive(Component, Clone, PartialEq, Debug)]2923/// # struct ComponentB;2924/// # let mut world = World::new();2925/// # let entity = world.spawn((ComponentA, ComponentB)).id();2926/// # let target = world.spawn_empty().id();2927/// // Clone only ComponentA onto the target.2928/// world.entity_mut(entity).clone_with_opt_in(target, |builder| {2929/// builder.allow::<ComponentA>();2930/// });2931/// # assert_eq!(world.get::<ComponentA>(target), Some(&ComponentA));2932/// # assert_eq!(world.get::<ComponentB>(target), None);2933/// ```2934///2935/// See [`EntityClonerBuilder<OptIn>`] for more options.2936///2937/// # Panics2938///2939/// - If this entity has been despawned while this `EntityWorldMut` is still alive.2940/// - If the target entity does not exist.2941pub fn clone_with_opt_in(2942&mut self,2943target: Entity,2944config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,2945) -> &mut Self {2946self.assert_not_despawned();29472948let mut builder = EntityCloner::build_opt_in(self.world);2949config(&mut builder);2950builder.clone_entity(self.entity, target);29512952self.world.flush();2953self.update_location();2954self2955}29562957/// Spawns a clone of this entity and returns the [`Entity`] of the clone.2958///2959/// The clone will receive all the components of the original that implement2960/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).2961///2962/// To configure cloning behavior (such as only cloning certain components),2963/// use [`EntityWorldMut::clone_and_spawn_with_opt_out`]/2964/// [`opt_in`](`EntityWorldMut::clone_and_spawn_with_opt_in`).2965///2966/// # Panics2967///2968/// If this entity has been despawned while this `EntityWorldMut` is still alive.2969pub fn clone_and_spawn(&mut self) -> Entity {2970self.clone_and_spawn_with_opt_out(|_| {})2971}29722973/// Spawns a clone of this entity and allows configuring cloning behavior2974/// using [`EntityClonerBuilder`], returning the [`Entity`] of the clone.2975///2976/// The clone will receive all the components of the original that implement2977/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are2978/// [denied](EntityClonerBuilder::deny) in the `config`.2979///2980/// # Example2981///2982/// ```2983/// # use bevy_ecs::prelude::*;2984/// # let mut world = World::new();2985/// # let entity = world.spawn((ComponentA, ComponentB)).id();2986/// # #[derive(Component, Clone, PartialEq, Debug)]2987/// # struct ComponentA;2988/// # #[derive(Component, Clone, PartialEq, Debug)]2989/// # struct ComponentB;2990/// // Create a clone of an entity but without ComponentA.2991/// let entity_clone = world.entity_mut(entity).clone_and_spawn_with_opt_out(|builder| {2992/// builder.deny::<ComponentA>();2993/// });2994/// # assert_eq!(world.get::<ComponentA>(entity_clone), None);2995/// # assert_eq!(world.get::<ComponentB>(entity_clone), Some(&ComponentB));2996/// ```2997///2998/// See [`EntityClonerBuilder<OptOut>`] for more options.2999///3000/// # Panics3001///3002/// If this entity has been despawned while this `EntityWorldMut` is still alive.3003pub fn clone_and_spawn_with_opt_out(3004&mut self,3005config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,3006) -> Entity {3007self.assert_not_despawned();30083009let entity_clone = self.world.entities.reserve_entity();3010self.world.flush();30113012let mut builder = EntityCloner::build_opt_out(self.world);3013config(&mut builder);3014builder.clone_entity(self.entity, entity_clone);30153016self.world.flush();3017self.update_location();3018entity_clone3019}30203021/// Spawns a clone of this entity and allows configuring cloning behavior3022/// using [`EntityClonerBuilder`], returning the [`Entity`] of the clone.3023///3024/// The clone will receive only the components of the original that implement3025/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are3026/// [allowed](EntityClonerBuilder::allow) in the `config`.3027///3028/// # Example3029///3030/// ```3031/// # use bevy_ecs::prelude::*;3032/// # let mut world = World::new();3033/// # let entity = world.spawn((ComponentA, ComponentB)).id();3034/// # #[derive(Component, Clone, PartialEq, Debug)]3035/// # struct ComponentA;3036/// # #[derive(Component, Clone, PartialEq, Debug)]3037/// # struct ComponentB;3038/// // Create a clone of an entity but only with ComponentA.3039/// let entity_clone = world.entity_mut(entity).clone_and_spawn_with_opt_in(|builder| {3040/// builder.allow::<ComponentA>();3041/// });3042/// # assert_eq!(world.get::<ComponentA>(entity_clone), Some(&ComponentA));3043/// # assert_eq!(world.get::<ComponentB>(entity_clone), None);3044/// ```3045///3046/// See [`EntityClonerBuilder<OptIn>`] for more options.3047///3048/// # Panics3049///3050/// If this entity has been despawned while this `EntityWorldMut` is still alive.3051pub fn clone_and_spawn_with_opt_in(3052&mut self,3053config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,3054) -> Entity {3055self.assert_not_despawned();30563057let entity_clone = self.world.entities.reserve_entity();3058self.world.flush();30593060let mut builder = EntityCloner::build_opt_in(self.world);3061config(&mut builder);3062builder.clone_entity(self.entity, entity_clone);30633064self.world.flush();3065self.update_location();3066entity_clone3067}30683069/// Clones the specified components of this entity and inserts them into another entity.3070///3071/// Components can only be cloned if they implement3072/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).3073///3074/// # Panics3075///3076/// - If this entity has been despawned while this `EntityWorldMut` is still alive.3077/// - If the target entity does not exist.3078pub fn clone_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {3079self.assert_not_despawned();30803081EntityCloner::build_opt_in(self.world)3082.allow::<B>()3083.clone_entity(self.entity, target);30843085self.world.flush();3086self.update_location();3087self3088}30893090/// Clones the specified components of this entity and inserts them into another entity,3091/// then removes the components from this entity.3092///3093/// Components can only be cloned if they implement3094/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).3095///3096/// # Panics3097///3098/// - If this entity has been despawned while this `EntityWorldMut` is still alive.3099/// - If the target entity does not exist.3100pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {3101self.assert_not_despawned();31023103EntityCloner::build_opt_in(self.world)3104.allow::<B>()3105.move_components(true)3106.clone_entity(self.entity, target);31073108self.world.flush();3109self.update_location();3110self3111}31123113/// Returns the source code location from which this entity has last been spawned.3114pub fn spawned_by(&self) -> MaybeLocation {3115self.world()3116.entities()3117.entity_get_spawned_or_despawned_by(self.entity)3118.map(|location| location.unwrap())3119}31203121/// Returns the [`Tick`] at which this entity has last been spawned.3122pub fn spawned_at(&self) -> Tick {3123self.assert_not_despawned();31243125// SAFETY: entity being alive was asserted3126unsafe {3127self.world()3128.entities()3129.entity_get_spawned_or_despawned_unchecked(self.entity)3130.13131}3132}31333134/// Reborrows this entity in a temporary scope.3135/// This is useful for executing a function that requires a `EntityWorldMut`3136/// but you do not want to move out the entity ownership.3137pub fn reborrow_scope<U>(&mut self, f: impl FnOnce(EntityWorldMut) -> U) -> U {3138let Self {3139entity, location, ..3140} = *self;3141self.world_scope(move |world| {3142f(EntityWorldMut {3143world,3144entity,3145location,3146})3147})3148}3149}31503151/// A view into a single entity and component in a world, which may either be vacant or occupied.3152///3153/// This `enum` can only be constructed from the [`entry`] method on [`EntityWorldMut`].3154///3155/// [`entry`]: EntityWorldMut::entry3156pub enum ComponentEntry<'w, 'a, T: Component> {3157/// An occupied entry.3158Occupied(OccupiedComponentEntry<'w, 'a, T>),3159/// A vacant entry.3160Vacant(VacantComponentEntry<'w, 'a, T>),3161}31623163impl<'w, 'a, T: Component<Mutability = Mutable>> ComponentEntry<'w, 'a, T> {3164/// Provides in-place mutable access to an occupied entry.3165///3166/// # Examples3167///3168/// ```3169/// # use bevy_ecs::prelude::*;3170/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3171/// struct Comp(u32);3172///3173/// # let mut world = World::new();3174/// let mut entity = world.spawn(Comp(0));3175///3176/// entity.entry::<Comp>().and_modify(|mut c| c.0 += 1);3177/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 1);3178/// ```3179#[inline]3180pub fn and_modify<F: FnOnce(Mut<'_, T>)>(self, f: F) -> Self {3181match self {3182ComponentEntry::Occupied(mut entry) => {3183f(entry.get_mut());3184ComponentEntry::Occupied(entry)3185}3186ComponentEntry::Vacant(entry) => ComponentEntry::Vacant(entry),3187}3188}3189}31903191impl<'w, 'a, T: Component> ComponentEntry<'w, 'a, T> {3192/// Replaces the component of the entry, and returns an [`OccupiedComponentEntry`].3193///3194/// # Examples3195///3196/// ```3197/// # use bevy_ecs::prelude::*;3198/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3199/// struct Comp(u32);3200///3201/// # let mut world = World::new();3202/// let mut entity = world.spawn_empty();3203///3204/// let entry = entity.entry().insert_entry(Comp(4));3205/// assert_eq!(entry.get(), &Comp(4));3206///3207/// let entry = entity.entry().insert_entry(Comp(2));3208/// assert_eq!(entry.get(), &Comp(2));3209/// ```3210#[inline]3211pub fn insert_entry(self, component: T) -> OccupiedComponentEntry<'w, 'a, T> {3212match self {3213ComponentEntry::Occupied(mut entry) => {3214entry.insert(component);3215entry3216}3217ComponentEntry::Vacant(entry) => entry.insert(component),3218}3219}32203221/// Ensures the entry has this component by inserting the given default if empty, and3222/// returns a mutable reference to this component in the entry.3223///3224/// # Examples3225///3226/// ```3227/// # use bevy_ecs::prelude::*;3228/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3229/// struct Comp(u32);3230///3231/// # let mut world = World::new();3232/// let mut entity = world.spawn_empty();3233///3234/// entity.entry().or_insert(Comp(4));3235/// # let entity_id = entity.id();3236/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 4);3237///3238/// # let mut entity = world.get_entity_mut(entity_id).unwrap();3239/// entity.entry().or_insert(Comp(15)).into_mut().0 *= 2;3240/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 8);3241/// ```3242#[inline]3243pub fn or_insert(self, default: T) -> OccupiedComponentEntry<'w, 'a, T> {3244match self {3245ComponentEntry::Occupied(entry) => entry,3246ComponentEntry::Vacant(entry) => entry.insert(default),3247}3248}32493250/// Ensures the entry has this component by inserting the result of the default function if3251/// empty, and returns a mutable reference to this component in the entry.3252///3253/// # Examples3254///3255/// ```3256/// # use bevy_ecs::prelude::*;3257/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3258/// struct Comp(u32);3259///3260/// # let mut world = World::new();3261/// let mut entity = world.spawn_empty();3262///3263/// entity.entry().or_insert_with(|| Comp(4));3264/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 4);3265/// ```3266#[inline]3267pub fn or_insert_with<F: FnOnce() -> T>(self, default: F) -> OccupiedComponentEntry<'w, 'a, T> {3268match self {3269ComponentEntry::Occupied(entry) => entry,3270ComponentEntry::Vacant(entry) => entry.insert(default()),3271}3272}3273}32743275impl<'w, 'a, T: Component + Default> ComponentEntry<'w, 'a, T> {3276/// Ensures the entry has this component by inserting the default value if empty, and3277/// returns a mutable reference to this component in the entry.3278///3279/// # Examples3280///3281/// ```3282/// # use bevy_ecs::prelude::*;3283/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3284/// struct Comp(u32);3285///3286/// # let mut world = World::new();3287/// let mut entity = world.spawn_empty();3288///3289/// entity.entry::<Comp>().or_default();3290/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 0);3291/// ```3292#[inline]3293pub fn or_default(self) -> OccupiedComponentEntry<'w, 'a, T> {3294match self {3295ComponentEntry::Occupied(entry) => entry,3296ComponentEntry::Vacant(entry) => entry.insert(Default::default()),3297}3298}3299}33003301/// A view into an occupied entry in a [`EntityWorldMut`]. It is part of the [`OccupiedComponentEntry`] enum.3302///3303/// The contained entity must have the component type parameter if we have this struct.3304pub struct OccupiedComponentEntry<'w, 'a, T: Component> {3305entity_world: &'a mut EntityWorldMut<'w>,3306_marker: PhantomData<T>,3307}33083309impl<'w, 'a, T: Component> OccupiedComponentEntry<'w, 'a, T> {3310/// Gets a reference to the component in the entry.3311///3312/// # Examples3313///3314/// ```3315/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3316/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3317/// struct Comp(u32);3318///3319/// # let mut world = World::new();3320/// let mut entity = world.spawn(Comp(5));3321///3322/// if let ComponentEntry::Occupied(o) = entity.entry::<Comp>() {3323/// assert_eq!(o.get().0, 5);3324/// }3325/// ```3326#[inline]3327pub fn get(&self) -> &T {3328// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.3329self.entity_world.get::<T>().unwrap()3330}33313332/// Replaces the component of the entry.3333///3334/// # Examples3335///3336/// ```3337/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3338/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3339/// struct Comp(u32);3340///3341/// # let mut world = World::new();3342/// let mut entity = world.spawn(Comp(5));3343///3344/// if let ComponentEntry::Occupied(mut o) = entity.entry::<Comp>() {3345/// o.insert(Comp(10));3346/// }3347///3348/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 10);3349/// ```3350#[inline]3351pub fn insert(&mut self, component: T) {3352self.entity_world.insert(component);3353}33543355/// Removes the component from the entry and returns it.3356///3357/// # Examples3358///3359/// ```3360/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3361/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3362/// struct Comp(u32);3363///3364/// # let mut world = World::new();3365/// let mut entity = world.spawn(Comp(5));3366///3367/// if let ComponentEntry::Occupied(o) = entity.entry::<Comp>() {3368/// assert_eq!(o.take(), Comp(5));3369/// }3370///3371/// assert_eq!(world.query::<&Comp>().iter(&world).len(), 0);3372/// ```3373#[inline]3374pub fn take(self) -> T {3375// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.3376self.entity_world.take().unwrap()3377}3378}33793380impl<'w, 'a, T: Component<Mutability = Mutable>> OccupiedComponentEntry<'w, 'a, T> {3381/// Gets a mutable reference to the component in the entry.3382///3383/// If you need a reference to the [`OccupiedComponentEntry`] which may outlive the destruction of3384/// the [`OccupiedComponentEntry`] value, see [`into_mut`].3385///3386/// [`into_mut`]: Self::into_mut3387///3388/// # Examples3389///3390/// ```3391/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3392/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3393/// struct Comp(u32);3394///3395/// # let mut world = World::new();3396/// let mut entity = world.spawn(Comp(5));3397///3398/// if let ComponentEntry::Occupied(mut o) = entity.entry::<Comp>() {3399/// o.get_mut().0 += 10;3400/// assert_eq!(o.get().0, 15);3401///3402/// // We can use the same Entry multiple times.3403/// o.get_mut().0 += 23404/// }3405///3406/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 17);3407/// ```3408#[inline]3409pub fn get_mut(&mut self) -> Mut<'_, T> {3410// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.3411self.entity_world.get_mut::<T>().unwrap()3412}34133414/// Converts the [`OccupiedComponentEntry`] into a mutable reference to the value in the entry with3415/// a lifetime bound to the `EntityWorldMut`.3416///3417/// If you need multiple references to the [`OccupiedComponentEntry`], see [`get_mut`].3418///3419/// [`get_mut`]: Self::get_mut3420///3421/// # Examples3422///3423/// ```3424/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3425/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3426/// struct Comp(u32);3427///3428/// # let mut world = World::new();3429/// let mut entity = world.spawn(Comp(5));3430///3431/// if let ComponentEntry::Occupied(o) = entity.entry::<Comp>() {3432/// o.into_mut().0 += 10;3433/// }3434///3435/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 15);3436/// ```3437#[inline]3438pub fn into_mut(self) -> Mut<'a, T> {3439// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.3440self.entity_world.get_mut().unwrap()3441}3442}34433444/// A view into a vacant entry in a [`EntityWorldMut`]. It is part of the [`ComponentEntry`] enum.3445pub struct VacantComponentEntry<'w, 'a, T: Component> {3446entity_world: &'a mut EntityWorldMut<'w>,3447_marker: PhantomData<T>,3448}34493450impl<'w, 'a, T: Component> VacantComponentEntry<'w, 'a, T> {3451/// Inserts the component into the [`VacantComponentEntry`] and returns an [`OccupiedComponentEntry`].3452///3453/// # Examples3454///3455/// ```3456/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3457/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3458/// struct Comp(u32);3459///3460/// # let mut world = World::new();3461/// let mut entity = world.spawn_empty();3462///3463/// if let ComponentEntry::Vacant(v) = entity.entry::<Comp>() {3464/// v.insert(Comp(10));3465/// }3466///3467/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 10);3468/// ```3469#[inline]3470pub fn insert(self, component: T) -> OccupiedComponentEntry<'w, 'a, T> {3471self.entity_world.insert(component);3472OccupiedComponentEntry {3473entity_world: self.entity_world,3474_marker: PhantomData,3475}3476}3477}34783479/// Provides read-only access to a single entity and some of its components defined by the contained [`Access`].3480///3481/// To define the access when used as a [`QueryData`](crate::query::QueryData),3482/// use a [`QueryBuilder`](crate::query::QueryBuilder) or [`QueryParamBuilder`](crate::system::QueryParamBuilder).3483/// The [`FilteredEntityRef`] must be the entire [`QueryData`](crate::query::QueryData), and not nested inside a tuple with other data.3484///3485/// ```3486/// # use bevy_ecs::{prelude::*, world::FilteredEntityRef};3487/// #3488/// # #[derive(Component)]3489/// # struct A;3490/// #3491/// # let mut world = World::new();3492/// # world.spawn(A);3493/// #3494/// // This gives the `FilteredEntityRef` access to `&A`.3495/// let mut query = QueryBuilder::<FilteredEntityRef>::new(&mut world)3496/// .data::<&A>()3497/// .build();3498///3499/// let filtered_entity: FilteredEntityRef = query.single(&mut world).unwrap();3500/// let component: &A = filtered_entity.get().unwrap();3501/// ```3502#[derive(Clone, Copy)]3503pub struct FilteredEntityRef<'w, 's> {3504entity: UnsafeEntityCell<'w>,3505access: &'s Access,3506}35073508impl<'w, 's> FilteredEntityRef<'w, 's> {3509/// # Safety3510/// - No `&mut World` can exist from the underlying `UnsafeWorldCell`3511/// - If `access` takes read access to a component no mutable reference to that3512/// component can exist at the same time as the returned [`FilteredEntityMut`]3513/// - If `access` takes any access for a component `entity` must have that component.3514#[inline]3515pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {3516Self { entity, access }3517}35183519/// Returns the [ID](Entity) of the current entity.3520#[inline]3521#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]3522pub fn id(&self) -> Entity {3523self.entity.id()3524}35253526/// Gets metadata indicating the location where the current entity is stored.3527#[inline]3528pub fn location(&self) -> EntityLocation {3529self.entity.location()3530}35313532/// Returns the archetype that the current entity belongs to.3533#[inline]3534pub fn archetype(&self) -> &Archetype {3535self.entity.archetype()3536}35373538/// Returns a reference to the underlying [`Access`].3539#[inline]3540pub fn access(&self) -> &Access {3541self.access3542}35433544/// Returns `true` if the current entity has a component of type `T`.3545/// Otherwise, this returns `false`.3546///3547/// ## Notes3548///3549/// If you do not know the concrete type of a component, consider using3550/// [`Self::contains_id`] or [`Self::contains_type_id`].3551#[inline]3552pub fn contains<T: Component>(&self) -> bool {3553self.contains_type_id(TypeId::of::<T>())3554}35553556/// Returns `true` if the current entity has a component identified by `component_id`.3557/// Otherwise, this returns false.3558///3559/// ## Notes3560///3561/// - If you know the concrete type of the component, you should prefer [`Self::contains`].3562/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using3563/// [`Self::contains_type_id`].3564#[inline]3565pub fn contains_id(&self, component_id: ComponentId) -> bool {3566self.entity.contains_id(component_id)3567}35683569/// Returns `true` if the current entity has a component with the type identified by `type_id`.3570/// Otherwise, this returns false.3571///3572/// ## Notes3573///3574/// - If you know the concrete type of the component, you should prefer [`Self::contains`].3575/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].3576#[inline]3577pub fn contains_type_id(&self, type_id: TypeId) -> bool {3578self.entity.contains_type_id(type_id)3579}35803581/// Gets access to the component of type `T` for the current entity.3582/// Returns `None` if the entity does not have a component of type `T`.3583#[inline]3584pub fn get<T: Component>(&self) -> Option<&'w T> {3585let id = self3586.entity3587.world()3588.components()3589.get_valid_id(TypeId::of::<T>())?;3590self.access3591.has_component_read(id)3592// SAFETY: We have read access3593.then(|| unsafe { self.entity.get() })3594.flatten()3595}35963597/// Gets access to the component of type `T` for the current entity,3598/// including change detection information as a [`Ref`].3599///3600/// Returns `None` if the entity does not have a component of type `T`.3601#[inline]3602pub fn get_ref<T: Component>(&self) -> Option<Ref<'w, T>> {3603let id = self3604.entity3605.world()3606.components()3607.get_valid_id(TypeId::of::<T>())?;3608self.access3609.has_component_read(id)3610// SAFETY: We have read access3611.then(|| unsafe { self.entity.get_ref() })3612.flatten()3613}36143615/// Retrieves the change ticks for the given component. This can be useful for implementing change3616/// detection in custom runtimes.3617#[inline]3618pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {3619let id = self3620.entity3621.world()3622.components()3623.get_valid_id(TypeId::of::<T>())?;3624self.access3625.has_component_read(id)3626// SAFETY: We have read access3627.then(|| unsafe { self.entity.get_change_ticks::<T>() })3628.flatten()3629}36303631/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change3632/// detection in custom runtimes.3633///3634/// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only3635/// use this in cases where the actual component types are not known at3636/// compile time.**3637#[inline]3638pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {3639self.access3640.has_component_read(component_id)3641// SAFETY: We have read access3642.then(|| unsafe { self.entity.get_change_ticks_by_id(component_id) })3643.flatten()3644}36453646/// Gets the component of the given [`ComponentId`] from the entity.3647///3648/// **You should prefer to use the typed API [`Self::get`] where possible and only3649/// use this in cases where the actual component types are not known at3650/// compile time.**3651///3652/// Unlike [`FilteredEntityRef::get`], this returns a raw pointer to the component,3653/// which is only valid while the [`FilteredEntityRef`] is alive.3654#[inline]3655pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'w>> {3656self.access3657.has_component_read(component_id)3658// SAFETY: We have read access3659.then(|| unsafe { self.entity.get_by_id(component_id) })3660.flatten()3661}36623663/// Returns the source code location from which this entity has been spawned.3664pub fn spawned_by(&self) -> MaybeLocation {3665self.entity.spawned_by()3666}36673668/// Returns the [`Tick`] at which this entity has been spawned.3669pub fn spawned_at(&self) -> Tick {3670self.entity.spawned_at()3671}3672}36733674impl<'w, 's> From<FilteredEntityMut<'w, 's>> for FilteredEntityRef<'w, 's> {3675#[inline]3676fn from(entity: FilteredEntityMut<'w, 's>) -> Self {3677// SAFETY:3678// - `FilteredEntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.3679unsafe { FilteredEntityRef::new(entity.entity, entity.access) }3680}3681}36823683impl<'w, 's> From<&'w FilteredEntityMut<'_, 's>> for FilteredEntityRef<'w, 's> {3684#[inline]3685fn from(entity: &'w FilteredEntityMut<'_, 's>) -> Self {3686// SAFETY:3687// - `FilteredEntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.3688unsafe { FilteredEntityRef::new(entity.entity, entity.access) }3689}3690}36913692impl<'a> From<EntityRef<'a>> for FilteredEntityRef<'a, 'static> {3693fn from(entity: EntityRef<'a>) -> Self {3694// SAFETY:3695// - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`.3696unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }3697}3698}36993700impl<'a> From<&'a EntityRef<'_>> for FilteredEntityRef<'a, 'static> {3701fn from(entity: &'a EntityRef<'_>) -> Self {3702// SAFETY:3703// - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`.3704unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }3705}3706}37073708impl<'a> From<EntityMut<'a>> for FilteredEntityRef<'a, 'static> {3709fn from(entity: EntityMut<'a>) -> Self {3710// SAFETY:3711// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.3712unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }3713}3714}37153716impl<'a> From<&'a EntityMut<'_>> for FilteredEntityRef<'a, 'static> {3717fn from(entity: &'a EntityMut<'_>) -> Self {3718// SAFETY:3719// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.3720unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }3721}3722}37233724impl<'a> From<EntityWorldMut<'a>> for FilteredEntityRef<'a, 'static> {3725fn from(entity: EntityWorldMut<'a>) -> Self {3726// SAFETY:3727// - `EntityWorldMut` guarantees exclusive access to the entire world.3728unsafe {3729FilteredEntityRef::new(3730entity.into_unsafe_entity_cell(),3731const { &Access::new_read_all() },3732)3733}3734}3735}37363737impl<'a> From<&'a EntityWorldMut<'_>> for FilteredEntityRef<'a, 'static> {3738fn from(entity: &'a EntityWorldMut<'_>) -> Self {3739// SAFETY:3740// - `EntityWorldMut` guarantees exclusive access to the entire world.3741unsafe {3742FilteredEntityRef::new(3743entity.as_unsafe_entity_cell_readonly(),3744const { &Access::new_read_all() },3745)3746}3747}3748}37493750impl<'w, 's, B: Bundle> From<&'w EntityRefExcept<'_, 's, B>> for FilteredEntityRef<'w, 's> {3751fn from(value: &'w EntityRefExcept<'_, 's, B>) -> Self {3752// SAFETY:3753// - The FilteredEntityRef has the same component access as the given EntityRefExcept.3754unsafe { FilteredEntityRef::new(value.entity, value.access) }3755}3756}37573758impl PartialEq for FilteredEntityRef<'_, '_> {3759fn eq(&self, other: &Self) -> bool {3760self.entity() == other.entity()3761}3762}37633764impl Eq for FilteredEntityRef<'_, '_> {}37653766impl PartialOrd for FilteredEntityRef<'_, '_> {3767/// [`FilteredEntityRef`]'s comparison trait implementations match the underlying [`Entity`],3768/// and cannot discern between different worlds.3769fn partial_cmp(&self, other: &Self) -> Option<Ordering> {3770Some(self.cmp(other))3771}3772}37733774impl Ord for FilteredEntityRef<'_, '_> {3775fn cmp(&self, other: &Self) -> Ordering {3776self.entity().cmp(&other.entity())3777}3778}37793780impl Hash for FilteredEntityRef<'_, '_> {3781fn hash<H: Hasher>(&self, state: &mut H) {3782self.entity().hash(state);3783}3784}37853786impl ContainsEntity for FilteredEntityRef<'_, '_> {3787fn entity(&self) -> Entity {3788self.id()3789}3790}37913792// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.3793unsafe impl EntityEquivalent for FilteredEntityRef<'_, '_> {}37943795/// Provides mutable access to a single entity and some of its components defined by the contained [`Access`].3796///3797/// To define the access when used as a [`QueryData`](crate::query::QueryData),3798/// use a [`QueryBuilder`](crate::query::QueryBuilder) or [`QueryParamBuilder`](crate::system::QueryParamBuilder).3799/// The `FilteredEntityMut` must be the entire `QueryData`, and not nested inside a tuple with other data.3800///3801/// ```3802/// # use bevy_ecs::{prelude::*, world::FilteredEntityMut};3803/// #3804/// # #[derive(Component)]3805/// # struct A;3806/// #3807/// # let mut world = World::new();3808/// # world.spawn(A);3809/// #3810/// // This gives the `FilteredEntityMut` access to `&mut A`.3811/// let mut query = QueryBuilder::<FilteredEntityMut>::new(&mut world)3812/// .data::<&mut A>()3813/// .build();3814///3815/// let mut filtered_entity: FilteredEntityMut = query.single_mut(&mut world).unwrap();3816/// let component: Mut<A> = filtered_entity.get_mut().unwrap();3817/// ```3818pub struct FilteredEntityMut<'w, 's> {3819entity: UnsafeEntityCell<'w>,3820access: &'s Access,3821}38223823impl<'w, 's> FilteredEntityMut<'w, 's> {3824/// # Safety3825/// - No `&mut World` can exist from the underlying `UnsafeWorldCell`3826/// - If `access` takes read access to a component no mutable reference to that3827/// component can exist at the same time as the returned [`FilteredEntityMut`]3828/// - If `access` takes write access to a component, no reference to that component3829/// may exist at the same time as the returned [`FilteredEntityMut`]3830/// - If `access` takes any access for a component `entity` must have that component.3831#[inline]3832pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {3833Self { entity, access }3834}38353836/// Returns a new instance with a shorter lifetime.3837/// This is useful if you have `&mut FilteredEntityMut`, but you need `FilteredEntityMut`.3838pub fn reborrow(&mut self) -> FilteredEntityMut<'_, 's> {3839// SAFETY: We have exclusive access to the entire entity and its components.3840unsafe { Self::new(self.entity, self.access) }3841}38423843/// Gets read-only access to all of the entity's components.3844#[inline]3845pub fn as_readonly(&self) -> FilteredEntityRef<'_, 's> {3846FilteredEntityRef::from(self)3847}38483849/// Returns the [ID](Entity) of the current entity.3850#[inline]3851#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]3852pub fn id(&self) -> Entity {3853self.entity.id()3854}38553856/// Gets metadata indicating the location where the current entity is stored.3857#[inline]3858pub fn location(&self) -> EntityLocation {3859self.entity.location()3860}38613862/// Returns the archetype that the current entity belongs to.3863#[inline]3864pub fn archetype(&self) -> &Archetype {3865self.entity.archetype()3866}38673868/// Returns a reference to the underlying [`Access`].3869#[inline]3870pub fn access(&self) -> &Access {3871self.access3872}38733874/// Returns `true` if the current entity has a component of type `T`.3875/// Otherwise, this returns `false`.3876///3877/// ## Notes3878///3879/// If you do not know the concrete type of a component, consider using3880/// [`Self::contains_id`] or [`Self::contains_type_id`].3881#[inline]3882pub fn contains<T: Component>(&self) -> bool {3883self.contains_type_id(TypeId::of::<T>())3884}38853886/// Returns `true` if the current entity has a component identified by `component_id`.3887/// Otherwise, this returns false.3888///3889/// ## Notes3890///3891/// - If you know the concrete type of the component, you should prefer [`Self::contains`].3892/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using3893/// [`Self::contains_type_id`].3894#[inline]3895pub fn contains_id(&self, component_id: ComponentId) -> bool {3896self.entity.contains_id(component_id)3897}38983899/// Returns `true` if the current entity has a component with the type identified by `type_id`.3900/// Otherwise, this returns false.3901///3902/// ## Notes3903///3904/// - If you know the concrete type of the component, you should prefer [`Self::contains`].3905/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].3906#[inline]3907pub fn contains_type_id(&self, type_id: TypeId) -> bool {3908self.entity.contains_type_id(type_id)3909}39103911/// Gets access to the component of type `T` for the current entity.3912/// Returns `None` if the entity does not have a component of type `T`.3913#[inline]3914pub fn get<T: Component>(&self) -> Option<&'_ T> {3915self.as_readonly().get()3916}39173918/// Gets access to the component of type `T` for the current entity,3919/// including change detection information as a [`Ref`].3920///3921/// Returns `None` if the entity does not have a component of type `T`.3922#[inline]3923pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {3924self.as_readonly().get_ref()3925}39263927/// Gets mutable access to the component of type `T` for the current entity.3928/// Returns `None` if the entity does not have a component of type `T`.3929#[inline]3930pub fn get_mut<T: Component<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {3931let id = self3932.entity3933.world()3934.components()3935.get_valid_id(TypeId::of::<T>())?;3936self.access3937.has_component_write(id)3938// SAFETY: We have write access3939.then(|| unsafe { self.entity.get_mut() })3940.flatten()3941}39423943/// Consumes self and gets mutable access to the component of type `T`3944/// with the world `'w` lifetime for the current entity.3945/// Returns `None` if the entity does not have a component of type `T`.3946#[inline]3947pub fn into_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {3948// SAFETY:3949// - We have write access3950// - The bound `T: Component<Mutability = Mutable>` ensures the component is mutable3951unsafe { self.into_mut_assume_mutable() }3952}39533954/// Consumes self and gets mutable access to the component of type `T`3955/// with the world `'w` lifetime for the current entity.3956/// Returns `None` if the entity does not have a component of type `T`.3957///3958/// # Safety3959///3960/// - `T` must be a mutable component3961#[inline]3962pub unsafe fn into_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {3963let id = self3964.entity3965.world()3966.components()3967.get_valid_id(TypeId::of::<T>())?;3968self.access3969.has_component_write(id)3970// SAFETY:3971// - We have write access3972// - Caller ensures `T` is a mutable component3973.then(|| unsafe { self.entity.get_mut_assume_mutable() })3974.flatten()3975}39763977/// Retrieves the change ticks for the given component. This can be useful for implementing change3978/// detection in custom runtimes.3979#[inline]3980pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {3981self.as_readonly().get_change_ticks::<T>()3982}39833984/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change3985/// detection in custom runtimes.3986///3987/// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only3988/// use this in cases where the actual component types are not known at3989/// compile time.**3990#[inline]3991pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {3992self.as_readonly().get_change_ticks_by_id(component_id)3993}39943995/// Gets the component of the given [`ComponentId`] from the entity.3996///3997/// **You should prefer to use the typed API [`Self::get`] where possible and only3998/// use this in cases where the actual component types are not known at3999/// compile time.**4000///4001/// Unlike [`FilteredEntityMut::get`], this returns a raw pointer to the component,4002/// which is only valid while the [`FilteredEntityMut`] is alive.4003#[inline]4004pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {4005self.as_readonly().get_by_id(component_id)4006}40074008/// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.4009///4010/// **You should prefer to use the typed API [`Self::get_mut`] where possible and only4011/// use this in cases where the actual component types are not known at4012/// compile time.**4013///4014/// Unlike [`FilteredEntityMut::get_mut`], this returns a raw pointer to the component,4015/// which is only valid while the [`FilteredEntityMut`] is alive.4016#[inline]4017pub fn get_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {4018self.access4019.has_component_write(component_id)4020// SAFETY: We have write access4021.then(|| unsafe { self.entity.get_mut_by_id(component_id).ok() })4022.flatten()4023}40244025/// Returns the source code location from which this entity has last been spawned.4026pub fn spawned_by(&self) -> MaybeLocation {4027self.entity.spawned_by()4028}40294030/// Returns the [`Tick`] at which this entity has been spawned.4031pub fn spawned_at(&self) -> Tick {4032self.entity.spawned_at()4033}4034}40354036impl<'a> From<EntityMut<'a>> for FilteredEntityMut<'a, 'static> {4037fn from(entity: EntityMut<'a>) -> Self {4038// SAFETY:4039// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityMut`.4040unsafe { FilteredEntityMut::new(entity.cell, const { &Access::new_write_all() }) }4041}4042}40434044impl<'a> From<&'a mut EntityMut<'_>> for FilteredEntityMut<'a, 'static> {4045fn from(entity: &'a mut EntityMut<'_>) -> Self {4046// SAFETY:4047// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityMut`.4048unsafe { FilteredEntityMut::new(entity.cell, const { &Access::new_write_all() }) }4049}4050}40514052impl<'a> From<EntityWorldMut<'a>> for FilteredEntityMut<'a, 'static> {4053fn from(entity: EntityWorldMut<'a>) -> Self {4054// SAFETY:4055// - `EntityWorldMut` guarantees exclusive access to the entire world.4056unsafe {4057FilteredEntityMut::new(4058entity.into_unsafe_entity_cell(),4059const { &Access::new_write_all() },4060)4061}4062}4063}40644065impl<'a> From<&'a mut EntityWorldMut<'_>> for FilteredEntityMut<'a, 'static> {4066fn from(entity: &'a mut EntityWorldMut<'_>) -> Self {4067// SAFETY:4068// - `EntityWorldMut` guarantees exclusive access to the entire world.4069unsafe {4070FilteredEntityMut::new(4071entity.as_unsafe_entity_cell(),4072const { &Access::new_write_all() },4073)4074}4075}4076}40774078impl<'w, 's, B: Bundle> From<&'w EntityMutExcept<'_, 's, B>> for FilteredEntityMut<'w, 's> {4079fn from(value: &'w EntityMutExcept<'_, 's, B>) -> Self {4080// SAFETY:4081// - The FilteredEntityMut has the same component access as the given EntityMutExcept.4082unsafe { FilteredEntityMut::new(value.entity, value.access) }4083}4084}40854086impl PartialEq for FilteredEntityMut<'_, '_> {4087fn eq(&self, other: &Self) -> bool {4088self.entity() == other.entity()4089}4090}40914092impl Eq for FilteredEntityMut<'_, '_> {}40934094impl PartialOrd for FilteredEntityMut<'_, '_> {4095/// [`FilteredEntityMut`]'s comparison trait implementations match the underlying [`Entity`],4096/// and cannot discern between different worlds.4097fn partial_cmp(&self, other: &Self) -> Option<Ordering> {4098Some(self.cmp(other))4099}4100}41014102impl Ord for FilteredEntityMut<'_, '_> {4103fn cmp(&self, other: &Self) -> Ordering {4104self.entity().cmp(&other.entity())4105}4106}41074108impl Hash for FilteredEntityMut<'_, '_> {4109fn hash<H: Hasher>(&self, state: &mut H) {4110self.entity().hash(state);4111}4112}41134114impl ContainsEntity for FilteredEntityMut<'_, '_> {4115fn entity(&self) -> Entity {4116self.id()4117}4118}41194120// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.4121unsafe impl EntityEquivalent for FilteredEntityMut<'_, '_> {}41224123/// Error type returned by [`TryFrom`] conversions from filtered entity types4124/// ([`FilteredEntityRef`]/[`FilteredEntityMut`]) to full-access entity types4125/// ([`EntityRef`]/[`EntityMut`]).4126#[derive(Error, Debug)]4127pub enum TryFromFilteredError {4128/// Error indicating that the filtered entity does not have read access to4129/// all components.4130#[error("Conversion failed, filtered entity ref does not have read access to all components")]4131MissingReadAllAccess,4132/// Error indicating that the filtered entity does not have write access to4133/// all components.4134#[error("Conversion failed, filtered entity ref does not have write access to all components")]4135MissingWriteAllAccess,4136}41374138/// Provides read-only access to a single entity and all its components, save4139/// for an explicitly-enumerated set.4140pub struct EntityRefExcept<'w, 's, B>4141where4142B: Bundle,4143{4144entity: UnsafeEntityCell<'w>,4145access: &'s Access,4146phantom: PhantomData<B>,4147}41484149impl<'w, 's, B> EntityRefExcept<'w, 's, B>4150where4151B: Bundle,4152{4153/// # Safety4154/// Other users of `UnsafeEntityCell` must only have mutable access to the components in `B`.4155pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {4156Self {4157entity,4158access,4159phantom: PhantomData,4160}4161}41624163/// Returns the [ID](Entity) of the current entity.4164#[inline]4165#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]4166pub fn id(&self) -> Entity {4167self.entity.id()4168}41694170/// Gets access to the component of type `C` for the current entity. Returns4171/// `None` if the component doesn't have a component of that type or if the4172/// type is one of the excluded components.4173#[inline]4174pub fn get<C>(&self) -> Option<&'w C>4175where4176C: Component,4177{4178let components = self.entity.world().components();4179let id = components.valid_component_id::<C>()?;4180if bundle_contains_component::<B>(components, id) {4181None4182} else {4183// SAFETY: We have read access for all components that weren't4184// covered by the `contains` check above.4185unsafe { self.entity.get() }4186}4187}41884189/// Gets access to the component of type `C` for the current entity,4190/// including change detection information. Returns `None` if the component4191/// doesn't have a component of that type or if the type is one of the4192/// excluded components.4193#[inline]4194pub fn get_ref<C>(&self) -> Option<Ref<'w, C>>4195where4196C: Component,4197{4198let components = self.entity.world().components();4199let id = components.valid_component_id::<C>()?;4200if bundle_contains_component::<B>(components, id) {4201None4202} else {4203// SAFETY: We have read access for all components that weren't4204// covered by the `contains` check above.4205unsafe { self.entity.get_ref() }4206}4207}42084209/// Returns the source code location from which this entity has been spawned.4210pub fn spawned_by(&self) -> MaybeLocation {4211self.entity.spawned_by()4212}42134214/// Returns the [`Tick`] at which this entity has been spawned.4215pub fn spawned_at(&self) -> Tick {4216self.entity.spawned_at()4217}42184219/// Gets the component of the given [`ComponentId`] from the entity.4220///4221/// **You should prefer to use the typed API [`Self::get`] where possible and only4222/// use this in cases where the actual component types are not known at4223/// compile time.**4224///4225/// Unlike [`EntityRefExcept::get`], this returns a raw pointer to the component,4226/// which is only valid while the [`EntityRefExcept`] is alive.4227#[inline]4228pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'w>> {4229let components = self.entity.world().components();4230(!bundle_contains_component::<B>(components, component_id))4231.then(|| {4232// SAFETY: We have read access for this component4233unsafe { self.entity.get_by_id(component_id) }4234})4235.flatten()4236}42374238/// Returns `true` if the current entity has a component of type `T`.4239/// Otherwise, this returns `false`.4240///4241/// ## Notes4242///4243/// If you do not know the concrete type of a component, consider using4244/// [`Self::contains_id`] or [`Self::contains_type_id`].4245#[inline]4246pub fn contains<T: Component>(&self) -> bool {4247self.contains_type_id(TypeId::of::<T>())4248}42494250/// Returns `true` if the current entity has a component identified by `component_id`.4251/// Otherwise, this returns false.4252///4253/// ## Notes4254///4255/// - If you know the concrete type of the component, you should prefer [`Self::contains`].4256/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using4257/// [`Self::contains_type_id`].4258#[inline]4259pub fn contains_id(&self, component_id: ComponentId) -> bool {4260self.entity.contains_id(component_id)4261}42624263/// Returns `true` if the current entity has a component with the type identified by `type_id`.4264/// Otherwise, this returns false.4265///4266/// ## Notes4267///4268/// - If you know the concrete type of the component, you should prefer [`Self::contains`].4269/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].4270#[inline]4271pub fn contains_type_id(&self, type_id: TypeId) -> bool {4272self.entity.contains_type_id(type_id)4273}42744275/// Retrieves the change ticks for the given component. This can be useful for implementing change4276/// detection in custom runtimes.4277#[inline]4278pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {4279let component_id = self4280.entity4281.world()4282.components()4283.get_valid_id(TypeId::of::<T>())?;4284let components = self.entity.world().components();4285(!bundle_contains_component::<B>(components, component_id))4286.then(|| {4287// SAFETY: We have read access4288unsafe { self.entity.get_change_ticks::<T>() }4289})4290.flatten()4291}42924293/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change4294/// detection in custom runtimes.4295///4296/// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only4297/// use this in cases where the actual component types are not known at4298/// compile time.**4299#[inline]4300pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {4301let components = self.entity.world().components();4302(!bundle_contains_component::<B>(components, component_id))4303.then(|| {4304// SAFETY: We have read access4305unsafe { self.entity.get_change_ticks_by_id(component_id) }4306})4307.flatten()4308}4309}43104311impl<'w, 's, B> From<&'w EntityMutExcept<'_, 's, B>> for EntityRefExcept<'w, 's, B>4312where4313B: Bundle,4314{4315fn from(entity: &'w EntityMutExcept<'_, 's, B>) -> Self {4316// SAFETY: All accesses that `EntityRefExcept` provides are also4317// accesses that `EntityMutExcept` provides.4318unsafe { EntityRefExcept::new(entity.entity, entity.access) }4319}4320}43214322impl<B: Bundle> Clone for EntityRefExcept<'_, '_, B> {4323fn clone(&self) -> Self {4324*self4325}4326}43274328impl<B: Bundle> Copy for EntityRefExcept<'_, '_, B> {}43294330impl<B: Bundle> PartialEq for EntityRefExcept<'_, '_, B> {4331fn eq(&self, other: &Self) -> bool {4332self.entity() == other.entity()4333}4334}43354336impl<B: Bundle> Eq for EntityRefExcept<'_, '_, B> {}43374338impl<B: Bundle> PartialOrd for EntityRefExcept<'_, '_, B> {4339/// [`EntityRefExcept`]'s comparison trait implementations match the underlying [`Entity`],4340/// and cannot discern between different worlds.4341fn partial_cmp(&self, other: &Self) -> Option<Ordering> {4342Some(self.cmp(other))4343}4344}43454346impl<B: Bundle> Ord for EntityRefExcept<'_, '_, B> {4347fn cmp(&self, other: &Self) -> Ordering {4348self.entity().cmp(&other.entity())4349}4350}43514352impl<B: Bundle> Hash for EntityRefExcept<'_, '_, B> {4353fn hash<H: Hasher>(&self, state: &mut H) {4354self.entity().hash(state);4355}4356}43574358impl<B: Bundle> ContainsEntity for EntityRefExcept<'_, '_, B> {4359fn entity(&self) -> Entity {4360self.id()4361}4362}43634364// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.4365unsafe impl<B: Bundle> EntityEquivalent for EntityRefExcept<'_, '_, B> {}43664367/// Provides mutable access to all components of an entity, with the exception4368/// of an explicit set.4369///4370/// This is a rather niche type that should only be used if you need access to4371/// *all* components of an entity, while still allowing you to consult other4372/// queries that might match entities that this query also matches. If you don't4373/// need access to all components, prefer a standard query with a4374/// [`crate::query::Without`] filter.4375pub struct EntityMutExcept<'w, 's, B>4376where4377B: Bundle,4378{4379entity: UnsafeEntityCell<'w>,4380access: &'s Access,4381phantom: PhantomData<B>,4382}43834384impl<'w, 's, B> EntityMutExcept<'w, 's, B>4385where4386B: Bundle,4387{4388/// # Safety4389/// Other users of `UnsafeEntityCell` must not have access to any components not in `B`.4390pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {4391Self {4392entity,4393access,4394phantom: PhantomData,4395}4396}43974398/// Returns the [ID](Entity) of the current entity.4399#[inline]4400#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]4401pub fn id(&self) -> Entity {4402self.entity.id()4403}44044405/// Returns a new instance with a shorter lifetime.4406///4407/// This is useful if you have `&mut EntityMutExcept`, but you need4408/// `EntityMutExcept`.4409pub fn reborrow(&mut self) -> EntityMutExcept<'_, 's, B> {4410// SAFETY: We have exclusive access to the entire entity and the4411// applicable components.4412unsafe { Self::new(self.entity, self.access) }4413}44144415/// Gets read-only access to all of the entity's components, except for the4416/// ones in `CL`.4417#[inline]4418pub fn as_readonly(&self) -> EntityRefExcept<'_, 's, B> {4419EntityRefExcept::from(self)4420}44214422/// Gets access to the component of type `C` for the current entity. Returns4423/// `None` if the component doesn't have a component of that type or if the4424/// type is one of the excluded components.4425#[inline]4426pub fn get<C>(&self) -> Option<&'_ C>4427where4428C: Component,4429{4430self.as_readonly().get()4431}44324433/// Gets access to the component of type `C` for the current entity,4434/// including change detection information. Returns `None` if the component4435/// doesn't have a component of that type or if the type is one of the4436/// excluded components.4437#[inline]4438pub fn get_ref<C>(&self) -> Option<Ref<'_, C>>4439where4440C: Component,4441{4442self.as_readonly().get_ref()4443}44444445/// Gets mutable access to the component of type `C` for the current entity.4446/// Returns `None` if the component doesn't have a component of that type or4447/// if the type is one of the excluded components.4448#[inline]4449pub fn get_mut<C>(&mut self) -> Option<Mut<'_, C>>4450where4451C: Component<Mutability = Mutable>,4452{4453let components = self.entity.world().components();4454let id = components.valid_component_id::<C>()?;4455if bundle_contains_component::<B>(components, id) {4456None4457} else {4458// SAFETY: We have write access for all components that weren't4459// covered by the `contains` check above.4460unsafe { self.entity.get_mut() }4461}4462}44634464/// Returns the source code location from which this entity has been spawned.4465pub fn spawned_by(&self) -> MaybeLocation {4466self.entity.spawned_by()4467}44684469/// Returns the [`Tick`] at which this entity has been spawned.4470pub fn spawned_at(&self) -> Tick {4471self.entity.spawned_at()4472}44734474/// Returns `true` if the current entity has a component of type `T`.4475/// Otherwise, this returns `false`.4476///4477/// ## Notes4478///4479/// If you do not know the concrete type of a component, consider using4480/// [`Self::contains_id`] or [`Self::contains_type_id`].4481#[inline]4482pub fn contains<T: Component>(&self) -> bool {4483self.contains_type_id(TypeId::of::<T>())4484}44854486/// Returns `true` if the current entity has a component identified by `component_id`.4487/// Otherwise, this returns false.4488///4489/// ## Notes4490///4491/// - If you know the concrete type of the component, you should prefer [`Self::contains`].4492/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using4493/// [`Self::contains_type_id`].4494#[inline]4495pub fn contains_id(&self, component_id: ComponentId) -> bool {4496self.entity.contains_id(component_id)4497}44984499/// Returns `true` if the current entity has a component with the type identified by `type_id`.4500/// Otherwise, this returns false.4501///4502/// ## Notes4503///4504/// - If you know the concrete type of the component, you should prefer [`Self::contains`].4505/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].4506#[inline]4507pub fn contains_type_id(&self, type_id: TypeId) -> bool {4508self.entity.contains_type_id(type_id)4509}45104511/// Gets the component of the given [`ComponentId`] from the entity.4512///4513/// **You should prefer to use the typed API [`Self::get`] where possible and only4514/// use this in cases where the actual component types are not known at4515/// compile time.**4516///4517/// Unlike [`EntityMutExcept::get`], this returns a raw pointer to the component,4518/// which is only valid while the [`EntityMutExcept`] is alive.4519#[inline]4520pub fn get_by_id(&'w self, component_id: ComponentId) -> Option<Ptr<'w>> {4521self.as_readonly().get_by_id(component_id)4522}45234524/// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.4525///4526/// **You should prefer to use the typed API [`Self::get_mut`] where possible and only4527/// use this in cases where the actual component types are not known at4528/// compile time.**4529///4530/// Unlike [`EntityMutExcept::get_mut`], this returns a raw pointer to the component,4531/// which is only valid while the [`EntityMutExcept`] is alive.4532#[inline]4533pub fn get_mut_by_id<F: DynamicComponentFetch>(4534&mut self,4535component_id: ComponentId,4536) -> Option<MutUntyped<'_>> {4537let components = self.entity.world().components();4538(!bundle_contains_component::<B>(components, component_id))4539.then(|| {4540// SAFETY: We have write access4541unsafe { self.entity.get_mut_by_id(component_id).ok() }4542})4543.flatten()4544}4545}45464547impl<B: Bundle> PartialEq for EntityMutExcept<'_, '_, B> {4548fn eq(&self, other: &Self) -> bool {4549self.entity() == other.entity()4550}4551}45524553impl<B: Bundle> Eq for EntityMutExcept<'_, '_, B> {}45544555impl<B: Bundle> PartialOrd for EntityMutExcept<'_, '_, B> {4556/// [`EntityMutExcept`]'s comparison trait implementations match the underlying [`Entity`],4557/// and cannot discern between different worlds.4558fn partial_cmp(&self, other: &Self) -> Option<Ordering> {4559Some(self.cmp(other))4560}4561}45624563impl<B: Bundle> Ord for EntityMutExcept<'_, '_, B> {4564fn cmp(&self, other: &Self) -> Ordering {4565self.entity().cmp(&other.entity())4566}4567}45684569impl<B: Bundle> Hash for EntityMutExcept<'_, '_, B> {4570fn hash<H: Hasher>(&self, state: &mut H) {4571self.entity().hash(state);4572}4573}45744575impl<B: Bundle> ContainsEntity for EntityMutExcept<'_, '_, B> {4576fn entity(&self) -> Entity {4577self.id()4578}4579}45804581// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.4582unsafe impl<B: Bundle> EntityEquivalent for EntityMutExcept<'_, '_, B> {}45834584fn bundle_contains_component<B>(components: &Components, query_id: ComponentId) -> bool4585where4586B: Bundle,4587{4588let mut found = false;4589B::get_component_ids(components, &mut |maybe_id| {4590if let Some(id) = maybe_id {4591found = found || id == query_id;4592}4593});4594found4595}45964597/// Inserts a dynamic [`Bundle`] into the entity.4598///4599/// # Safety4600///4601/// - [`OwningPtr`] and [`StorageType`] iterators must correspond to the4602/// [`BundleInfo`](crate::bundle::BundleInfo) used to construct [`BundleInserter`]4603/// - [`Entity`] must correspond to [`EntityLocation`]4604unsafe fn insert_dynamic_bundle<4605'a,4606I: Iterator<Item = OwningPtr<'a>>,4607S: Iterator<Item = StorageType>,4608>(4609mut bundle_inserter: BundleInserter<'_>,4610entity: Entity,4611location: EntityLocation,4612components: I,4613storage_types: S,4614mode: InsertMode,4615caller: MaybeLocation,4616relationship_hook_insert_mode: RelationshipHookMode,4617) -> EntityLocation {4618struct DynamicInsertBundle<'a, I: Iterator<Item = (StorageType, OwningPtr<'a>)>> {4619components: I,4620}46214622impl<'a, I: Iterator<Item = (StorageType, OwningPtr<'a>)>> DynamicBundle4623for DynamicInsertBundle<'a, I>4624{4625type Effect = ();4626fn get_components(self, func: &mut impl FnMut(StorageType, OwningPtr<'_>)) {4627self.components.for_each(|(t, ptr)| func(t, ptr));4628}4629}46304631let bundle = DynamicInsertBundle {4632components: storage_types.zip(components),4633};46344635// SAFETY: location matches current entity.4636unsafe {4637bundle_inserter4638.insert(4639entity,4640location,4641bundle,4642mode,4643caller,4644relationship_hook_insert_mode,4645)4646.04647}4648}46494650/// Types that can be used to fetch components from an entity dynamically by4651/// [`ComponentId`]s.4652///4653/// Provided implementations are:4654/// - [`ComponentId`]: Returns a single untyped reference.4655/// - `[ComponentId; N]` and `&[ComponentId; N]`: Returns a same-sized array of untyped references.4656/// - `&[ComponentId]`: Returns a [`Vec`] of untyped references.4657/// - [`&HashSet<ComponentId>`](HashSet): Returns a [`HashMap`] of IDs to untyped references.4658///4659/// # Performance4660///4661/// - The slice and array implementations perform an aliased mutability check in4662/// [`DynamicComponentFetch::fetch_mut`] that is `O(N^2)`.4663/// - The [`HashSet`] implementation performs no such check as the type itself4664/// guarantees unique IDs.4665/// - The single [`ComponentId`] implementation performs no such check as only4666/// one reference is returned.4667///4668/// # Safety4669///4670/// Implementor must ensure that:4671/// - No aliased mutability is caused by the returned references.4672/// - [`DynamicComponentFetch::fetch_ref`] returns only read-only references.4673pub unsafe trait DynamicComponentFetch {4674/// The read-only reference type returned by [`DynamicComponentFetch::fetch_ref`].4675type Ref<'w>;46764677/// The mutable reference type returned by [`DynamicComponentFetch::fetch_mut`].4678type Mut<'w>;46794680/// Returns untyped read-only reference(s) to the component(s) with the4681/// given [`ComponentId`]s, as determined by `self`.4682///4683/// # Safety4684///4685/// It is the caller's responsibility to ensure that:4686/// - The given [`UnsafeEntityCell`] has read-only access to the fetched components.4687/// - No other mutable references to the fetched components exist at the same time.4688///4689/// # Errors4690///4691/// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.4692unsafe fn fetch_ref(4693self,4694cell: UnsafeEntityCell<'_>,4695) -> Result<Self::Ref<'_>, EntityComponentError>;46964697/// Returns untyped mutable reference(s) to the component(s) with the4698/// given [`ComponentId`]s, as determined by `self`.4699///4700/// # Safety4701///4702/// It is the caller's responsibility to ensure that:4703/// - The given [`UnsafeEntityCell`] has mutable access to the fetched components.4704/// - No other references to the fetched components exist at the same time.4705///4706/// # Errors4707///4708/// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.4709/// - Returns [`EntityComponentError::AliasedMutability`] if a component is requested multiple times.4710unsafe fn fetch_mut(4711self,4712cell: UnsafeEntityCell<'_>,4713) -> Result<Self::Mut<'_>, EntityComponentError>;47144715/// Returns untyped mutable reference(s) to the component(s) with the4716/// given [`ComponentId`]s, as determined by `self`.4717/// Assumes all [`ComponentId`]s refer to mutable components.4718///4719/// # Safety4720///4721/// It is the caller's responsibility to ensure that:4722/// - The given [`UnsafeEntityCell`] has mutable access to the fetched components.4723/// - No other references to the fetched components exist at the same time.4724/// - The requested components are all mutable.4725///4726/// # Errors4727///4728/// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.4729/// - Returns [`EntityComponentError::AliasedMutability`] if a component is requested multiple times.4730unsafe fn fetch_mut_assume_mutable(4731self,4732cell: UnsafeEntityCell<'_>,4733) -> Result<Self::Mut<'_>, EntityComponentError>;4734}47354736// SAFETY:4737// - No aliased mutability is caused because a single reference is returned.4738// - No mutable references are returned by `fetch_ref`.4739unsafe impl DynamicComponentFetch for ComponentId {4740type Ref<'w> = Ptr<'w>;4741type Mut<'w> = MutUntyped<'w>;47424743unsafe fn fetch_ref(4744self,4745cell: UnsafeEntityCell<'_>,4746) -> Result<Self::Ref<'_>, EntityComponentError> {4747// SAFETY: caller ensures that the cell has read access to the component.4748unsafe { cell.get_by_id(self) }.ok_or(EntityComponentError::MissingComponent(self))4749}47504751unsafe fn fetch_mut(4752self,4753cell: UnsafeEntityCell<'_>,4754) -> Result<Self::Mut<'_>, EntityComponentError> {4755// SAFETY: caller ensures that the cell has mutable access to the component.4756unsafe { cell.get_mut_by_id(self) }4757.map_err(|_| EntityComponentError::MissingComponent(self))4758}47594760unsafe fn fetch_mut_assume_mutable(4761self,4762cell: UnsafeEntityCell<'_>,4763) -> Result<Self::Mut<'_>, EntityComponentError> {4764// SAFETY: caller ensures that the cell has mutable access to the component.4765unsafe { cell.get_mut_assume_mutable_by_id(self) }4766.map_err(|_| EntityComponentError::MissingComponent(self))4767}4768}47694770// SAFETY:4771// - No aliased mutability is caused because the array is checked for duplicates.4772// - No mutable references are returned by `fetch_ref`.4773unsafe impl<const N: usize> DynamicComponentFetch for [ComponentId; N] {4774type Ref<'w> = [Ptr<'w>; N];4775type Mut<'w> = [MutUntyped<'w>; N];47764777unsafe fn fetch_ref(4778self,4779cell: UnsafeEntityCell<'_>,4780) -> Result<Self::Ref<'_>, EntityComponentError> {4781<&Self>::fetch_ref(&self, cell)4782}47834784unsafe fn fetch_mut(4785self,4786cell: UnsafeEntityCell<'_>,4787) -> Result<Self::Mut<'_>, EntityComponentError> {4788<&Self>::fetch_mut(&self, cell)4789}47904791unsafe fn fetch_mut_assume_mutable(4792self,4793cell: UnsafeEntityCell<'_>,4794) -> Result<Self::Mut<'_>, EntityComponentError> {4795<&Self>::fetch_mut_assume_mutable(&self, cell)4796}4797}47984799// SAFETY:4800// - No aliased mutability is caused because the array is checked for duplicates.4801// - No mutable references are returned by `fetch_ref`.4802unsafe impl<const N: usize> DynamicComponentFetch for &'_ [ComponentId; N] {4803type Ref<'w> = [Ptr<'w>; N];4804type Mut<'w> = [MutUntyped<'w>; N];48054806unsafe fn fetch_ref(4807self,4808cell: UnsafeEntityCell<'_>,4809) -> Result<Self::Ref<'_>, EntityComponentError> {4810let mut ptrs = [const { MaybeUninit::uninit() }; N];4811for (ptr, &id) in core::iter::zip(&mut ptrs, self) {4812*ptr = MaybeUninit::new(4813// SAFETY: caller ensures that the cell has read access to the component.4814unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,4815);4816}48174818// SAFETY: Each ptr was initialized in the loop above.4819let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });48204821Ok(ptrs)4822}48234824unsafe fn fetch_mut(4825self,4826cell: UnsafeEntityCell<'_>,4827) -> Result<Self::Mut<'_>, EntityComponentError> {4828// Check for duplicate component IDs.4829for i in 0..self.len() {4830for j in 0..i {4831if self[i] == self[j] {4832return Err(EntityComponentError::AliasedMutability(self[i]));4833}4834}4835}48364837let mut ptrs = [const { MaybeUninit::uninit() }; N];4838for (ptr, &id) in core::iter::zip(&mut ptrs, self) {4839*ptr = MaybeUninit::new(4840// SAFETY: caller ensures that the cell has mutable access to the component.4841unsafe { cell.get_mut_by_id(id) }4842.map_err(|_| EntityComponentError::MissingComponent(id))?,4843);4844}48454846// SAFETY: Each ptr was initialized in the loop above.4847let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });48484849Ok(ptrs)4850}48514852unsafe fn fetch_mut_assume_mutable(4853self,4854cell: UnsafeEntityCell<'_>,4855) -> Result<Self::Mut<'_>, EntityComponentError> {4856// Check for duplicate component IDs.4857for i in 0..self.len() {4858for j in 0..i {4859if self[i] == self[j] {4860return Err(EntityComponentError::AliasedMutability(self[i]));4861}4862}4863}48644865let mut ptrs = [const { MaybeUninit::uninit() }; N];4866for (ptr, &id) in core::iter::zip(&mut ptrs, self) {4867*ptr = MaybeUninit::new(4868// SAFETY: caller ensures that the cell has mutable access to the component.4869unsafe { cell.get_mut_assume_mutable_by_id(id) }4870.map_err(|_| EntityComponentError::MissingComponent(id))?,4871);4872}48734874// SAFETY: Each ptr was initialized in the loop above.4875let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });48764877Ok(ptrs)4878}4879}48804881// SAFETY:4882// - No aliased mutability is caused because the slice is checked for duplicates.4883// - No mutable references are returned by `fetch_ref`.4884unsafe impl DynamicComponentFetch for &'_ [ComponentId] {4885type Ref<'w> = Vec<Ptr<'w>>;4886type Mut<'w> = Vec<MutUntyped<'w>>;48874888unsafe fn fetch_ref(4889self,4890cell: UnsafeEntityCell<'_>,4891) -> Result<Self::Ref<'_>, EntityComponentError> {4892let mut ptrs = Vec::with_capacity(self.len());4893for &id in self {4894ptrs.push(4895// SAFETY: caller ensures that the cell has read access to the component.4896unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,4897);4898}4899Ok(ptrs)4900}49014902unsafe fn fetch_mut(4903self,4904cell: UnsafeEntityCell<'_>,4905) -> Result<Self::Mut<'_>, EntityComponentError> {4906// Check for duplicate component IDs.4907for i in 0..self.len() {4908for j in 0..i {4909if self[i] == self[j] {4910return Err(EntityComponentError::AliasedMutability(self[i]));4911}4912}4913}49144915let mut ptrs = Vec::with_capacity(self.len());4916for &id in self {4917ptrs.push(4918// SAFETY: caller ensures that the cell has mutable access to the component.4919unsafe { cell.get_mut_by_id(id) }4920.map_err(|_| EntityComponentError::MissingComponent(id))?,4921);4922}4923Ok(ptrs)4924}49254926unsafe fn fetch_mut_assume_mutable(4927self,4928cell: UnsafeEntityCell<'_>,4929) -> Result<Self::Mut<'_>, EntityComponentError> {4930// Check for duplicate component IDs.4931for i in 0..self.len() {4932for j in 0..i {4933if self[i] == self[j] {4934return Err(EntityComponentError::AliasedMutability(self[i]));4935}4936}4937}49384939let mut ptrs = Vec::with_capacity(self.len());4940for &id in self {4941ptrs.push(4942// SAFETY: caller ensures that the cell has mutable access to the component.4943unsafe { cell.get_mut_assume_mutable_by_id(id) }4944.map_err(|_| EntityComponentError::MissingComponent(id))?,4945);4946}4947Ok(ptrs)4948}4949}49504951// SAFETY:4952// - No aliased mutability is caused because `HashSet` guarantees unique elements.4953// - No mutable references are returned by `fetch_ref`.4954unsafe impl DynamicComponentFetch for &'_ HashSet<ComponentId> {4955type Ref<'w> = HashMap<ComponentId, Ptr<'w>>;4956type Mut<'w> = HashMap<ComponentId, MutUntyped<'w>>;49574958unsafe fn fetch_ref(4959self,4960cell: UnsafeEntityCell<'_>,4961) -> Result<Self::Ref<'_>, EntityComponentError> {4962let mut ptrs = HashMap::with_capacity_and_hasher(self.len(), Default::default());4963for &id in self {4964ptrs.insert(4965id,4966// SAFETY: caller ensures that the cell has read access to the component.4967unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,4968);4969}4970Ok(ptrs)4971}49724973unsafe fn fetch_mut(4974self,4975cell: UnsafeEntityCell<'_>,4976) -> Result<Self::Mut<'_>, EntityComponentError> {4977let mut ptrs = HashMap::with_capacity_and_hasher(self.len(), Default::default());4978for &id in self {4979ptrs.insert(4980id,4981// SAFETY: caller ensures that the cell has mutable access to the component.4982unsafe { cell.get_mut_by_id(id) }4983.map_err(|_| EntityComponentError::MissingComponent(id))?,4984);4985}4986Ok(ptrs)4987}49884989unsafe fn fetch_mut_assume_mutable(4990self,4991cell: UnsafeEntityCell<'_>,4992) -> Result<Self::Mut<'_>, EntityComponentError> {4993let mut ptrs = HashMap::with_capacity_and_hasher(self.len(), Default::default());4994for &id in self {4995ptrs.insert(4996id,4997// SAFETY: caller ensures that the cell has mutable access to the component.4998unsafe { cell.get_mut_assume_mutable_by_id(id) }4999.map_err(|_| EntityComponentError::MissingComponent(id))?,5000);5001}5002Ok(ptrs)5003}5004}50055006#[cfg(test)]5007mod tests {5008use alloc::{vec, vec::Vec};5009use bevy_ptr::{OwningPtr, Ptr};5010use core::panic::AssertUnwindSafe;5011use std::sync::OnceLock;50125013use crate::component::Tick;5014use crate::lifecycle::HookContext;5015use crate::{5016change_detection::{MaybeLocation, MutUntyped},5017component::ComponentId,5018prelude::*,5019system::{assert_is_system, RunSystemOnce as _},5020world::{error::EntityComponentError, DeferredWorld, FilteredEntityMut, FilteredEntityRef},5021};50225023use super::{EntityMutExcept, EntityRefExcept};50245025#[derive(Component, Clone, Copy, Debug, PartialEq)]5026struct TestComponent(u32);50275028#[derive(Component, Clone, Copy, Debug, PartialEq)]5029#[component(storage = "SparseSet")]5030struct TestComponent2(u32);50315032#[test]5033fn entity_ref_get_by_id() {5034let mut world = World::new();5035let entity = world.spawn(TestComponent(42)).id();5036let component_id = world5037.components()5038.get_valid_id(core::any::TypeId::of::<TestComponent>())5039.unwrap();50405041let entity = world.entity(entity);5042let test_component = entity.get_by_id(component_id).unwrap();5043// SAFETY: points to a valid `TestComponent`5044let test_component = unsafe { test_component.deref::<TestComponent>() };50455046assert_eq!(test_component.0, 42);5047}50485049#[test]5050fn entity_mut_get_by_id() {5051let mut world = World::new();5052let entity = world.spawn(TestComponent(42)).id();5053let component_id = world5054.components()5055.get_valid_id(core::any::TypeId::of::<TestComponent>())5056.unwrap();50575058let mut entity_mut = world.entity_mut(entity);5059let mut test_component = entity_mut.get_mut_by_id(component_id).unwrap();5060{5061test_component.set_changed();5062let test_component =5063// SAFETY: `test_component` has unique access of the `EntityWorldMut` and is not used afterwards5064unsafe { test_component.into_inner().deref_mut::<TestComponent>() };5065test_component.0 = 43;5066}50675068let entity = world.entity(entity);5069let test_component = entity.get_by_id(component_id).unwrap();5070// SAFETY: `TestComponent` is the correct component type5071let test_component = unsafe { test_component.deref::<TestComponent>() };50725073assert_eq!(test_component.0, 43);5074}50755076#[test]5077fn entity_ref_get_by_id_invalid_component_id() {5078let invalid_component_id = ComponentId::new(usize::MAX);50795080let mut world = World::new();5081let entity = world.spawn_empty().id();5082let entity = world.entity(entity);5083assert!(entity.get_by_id(invalid_component_id).is_err());5084}50855086#[test]5087fn entity_mut_get_by_id_invalid_component_id() {5088let invalid_component_id = ComponentId::new(usize::MAX);50895090let mut world = World::new();5091let mut entity = world.spawn_empty();5092assert!(entity.get_by_id(invalid_component_id).is_err());5093assert!(entity.get_mut_by_id(invalid_component_id).is_err());5094}50955096#[derive(Resource)]5097struct R(usize);50985099#[test]5100fn entity_mut_resource_scope() {5101// Keep in sync with the `resource_scope` test in lib.rs5102let mut world = World::new();5103let mut entity = world.spawn_empty();51045105assert!(entity.try_resource_scope::<R, _>(|_, _| {}).is_none());5106entity.world_scope(|world| world.insert_resource(R(0)));5107entity.resource_scope(|entity: &mut EntityWorldMut, mut value: Mut<R>| {5108value.0 += 1;5109assert!(!entity.world().contains_resource::<R>());5110});5111assert_eq!(entity.resource::<R>().0, 1);5112}51135114#[test]5115fn entity_mut_resource_scope_panic() {5116let mut world = World::new();5117world.insert_resource(R(0));51185119let mut entity = world.spawn_empty();5120let old_location = entity.location();5121let result = std::panic::catch_unwind(AssertUnwindSafe(|| {5122entity.resource_scope(|entity: &mut EntityWorldMut, _: Mut<R>| {5123// Change the entity's `EntityLocation`.5124entity.insert(TestComponent(0));51255126// Ensure that the entity location still gets updated even in case of a panic.5127panic!("this should get caught by the outer scope")5128});5129}));5130assert!(result.is_err());51315132// Ensure that the location has been properly updated.5133assert_ne!(entity.location(), old_location);5134}51355136// regression test for https://github.com/bevyengine/bevy/pull/73875137#[test]5138fn entity_mut_world_scope_panic() {5139let mut world = World::new();51405141let mut entity = world.spawn_empty();5142let old_location = entity.location();5143let id = entity.id();5144let res = std::panic::catch_unwind(AssertUnwindSafe(|| {5145entity.world_scope(|w| {5146// Change the entity's `EntityLocation`, which invalidates the original `EntityWorldMut`.5147// This will get updated at the end of the scope.5148w.entity_mut(id).insert(TestComponent(0));51495150// Ensure that the entity location still gets updated even in case of a panic.5151panic!("this should get caught by the outer scope")5152});5153}));5154assert!(res.is_err());51555156// Ensure that the location has been properly updated.5157assert_ne!(entity.location(), old_location);5158}51595160#[test]5161fn entity_mut_reborrow_scope_panic() {5162let mut world = World::new();51635164let mut entity = world.spawn_empty();5165let old_location = entity.location();5166let res = std::panic::catch_unwind(AssertUnwindSafe(|| {5167entity.reborrow_scope(|mut entity| {5168// Change the entity's `EntityLocation`, which invalidates the original `EntityWorldMut`.5169// This will get updated at the end of the scope.5170entity.insert(TestComponent(0));51715172// Ensure that the entity location still gets updated even in case of a panic.5173panic!("this should get caught by the outer scope")5174});5175}));5176assert!(res.is_err());51775178// Ensure that the location has been properly updated.5179assert_ne!(entity.location(), old_location);5180}51815182// regression test for https://github.com/bevyengine/bevy/pull/78055183#[test]5184fn removing_sparse_updates_archetype_row() {5185#[derive(Component, PartialEq, Debug)]5186struct Dense(u8);51875188#[derive(Component)]5189#[component(storage = "SparseSet")]5190struct Sparse;51915192let mut world = World::new();5193let e1 = world.spawn((Dense(0), Sparse)).id();5194let e2 = world.spawn((Dense(1), Sparse)).id();51955196world.entity_mut(e1).remove::<Sparse>();5197assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));5198}51995200// regression test for https://github.com/bevyengine/bevy/pull/78055201#[test]5202fn removing_dense_updates_table_row() {5203#[derive(Component, PartialEq, Debug)]5204struct Dense(u8);52055206#[derive(Component)]5207#[component(storage = "SparseSet")]5208struct Sparse;52095210let mut world = World::new();5211let e1 = world.spawn((Dense(0), Sparse)).id();5212let e2 = world.spawn((Dense(1), Sparse)).id();52135214world.entity_mut(e1).remove::<Dense>();5215assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));5216}52175218// Test that calling retain with `()` removes all components.5219#[test]5220fn retain_nothing() {5221#[derive(Component)]5222struct Marker<const N: usize>;52235224let mut world = World::new();5225let ent = world.spawn((Marker::<1>, Marker::<2>, Marker::<3>)).id();52265227world.entity_mut(ent).retain::<()>();5228assert_eq!(world.entity(ent).archetype().components().len(), 0);5229}52305231// Test removing some components with `retain`, including components not on the entity.5232#[test]5233fn retain_some_components() {5234#[derive(Component)]5235struct Marker<const N: usize>;52365237let mut world = World::new();5238let ent = world.spawn((Marker::<1>, Marker::<2>, Marker::<3>)).id();52395240world.entity_mut(ent).retain::<(Marker<2>, Marker<4>)>();5241// Check that marker 2 was retained.5242assert!(world.entity(ent).get::<Marker<2>>().is_some());5243// Check that only marker 2 was retained.5244assert_eq!(world.entity(ent).archetype().components().len(), 1);5245}52465247// regression test for https://github.com/bevyengine/bevy/pull/78055248#[test]5249fn inserting_sparse_updates_archetype_row() {5250#[derive(Component, PartialEq, Debug)]5251struct Dense(u8);52525253#[derive(Component)]5254#[component(storage = "SparseSet")]5255struct Sparse;52565257let mut world = World::new();5258let e1 = world.spawn(Dense(0)).id();5259let e2 = world.spawn(Dense(1)).id();52605261world.entity_mut(e1).insert(Sparse);5262assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));5263}52645265// regression test for https://github.com/bevyengine/bevy/pull/78055266#[test]5267fn inserting_dense_updates_archetype_row() {5268#[derive(Component, PartialEq, Debug)]5269struct Dense(u8);52705271#[derive(Component)]5272struct Dense2;52735274#[derive(Component)]5275#[component(storage = "SparseSet")]5276struct Sparse;52775278let mut world = World::new();5279let e1 = world.spawn(Dense(0)).id();5280let e2 = world.spawn(Dense(1)).id();52815282world.entity_mut(e1).insert(Sparse).remove::<Sparse>();52835284// archetype with [e2, e1]5285// table with [e1, e2]52865287world.entity_mut(e2).insert(Dense2);52885289assert_eq!(world.entity(e1).get::<Dense>().unwrap(), &Dense(0));5290}52915292#[test]5293fn inserting_dense_updates_table_row() {5294#[derive(Component, PartialEq, Debug)]5295struct Dense(u8);52965297#[derive(Component)]5298struct Dense2;52995300#[derive(Component)]5301#[component(storage = "SparseSet")]5302struct Sparse;53035304let mut world = World::new();5305let e1 = world.spawn(Dense(0)).id();5306let e2 = world.spawn(Dense(1)).id();53075308world.entity_mut(e1).insert(Sparse).remove::<Sparse>();53095310// archetype with [e2, e1]5311// table with [e1, e2]53125313world.entity_mut(e1).insert(Dense2);53145315assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));5316}53175318// regression test for https://github.com/bevyengine/bevy/pull/78055319#[test]5320fn despawning_entity_updates_archetype_row() {5321#[derive(Component, PartialEq, Debug)]5322struct Dense(u8);53235324#[derive(Component)]5325#[component(storage = "SparseSet")]5326struct Sparse;53275328let mut world = World::new();5329let e1 = world.spawn(Dense(0)).id();5330let e2 = world.spawn(Dense(1)).id();53315332world.entity_mut(e1).insert(Sparse).remove::<Sparse>();53335334// archetype with [e2, e1]5335// table with [e1, e2]53365337world.entity_mut(e2).despawn();53385339assert_eq!(world.entity(e1).get::<Dense>().unwrap(), &Dense(0));5340}53415342// regression test for https://github.com/bevyengine/bevy/pull/78055343#[test]5344fn despawning_entity_updates_table_row() {5345#[derive(Component, PartialEq, Debug)]5346struct Dense(u8);53475348#[derive(Component)]5349#[component(storage = "SparseSet")]5350struct Sparse;53515352let mut world = World::new();5353let e1 = world.spawn(Dense(0)).id();5354let e2 = world.spawn(Dense(1)).id();53555356world.entity_mut(e1).insert(Sparse).remove::<Sparse>();53575358// archetype with [e2, e1]5359// table with [e1, e2]53605361world.entity_mut(e1).despawn();53625363assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));5364}53655366#[test]5367fn entity_mut_insert_by_id() {5368let mut world = World::new();5369let test_component_id = world.register_component::<TestComponent>();53705371let mut entity = world.spawn_empty();5372OwningPtr::make(TestComponent(42), |ptr| {5373// SAFETY: `ptr` matches the component id5374unsafe { entity.insert_by_id(test_component_id, ptr) };5375});53765377let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();53785379assert_eq!(components, vec![&TestComponent(42)]);53805381// Compare with `insert_bundle_by_id`53825383let mut entity = world.spawn_empty();5384OwningPtr::make(TestComponent(84), |ptr| {5385// SAFETY: `ptr` matches the component id5386unsafe { entity.insert_by_ids(&[test_component_id], vec![ptr].into_iter()) };5387});53885389let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();53905391assert_eq!(components, vec![&TestComponent(42), &TestComponent(84)]);5392}53935394#[test]5395fn entity_mut_insert_bundle_by_id() {5396let mut world = World::new();5397let test_component_id = world.register_component::<TestComponent>();5398let test_component_2_id = world.register_component::<TestComponent2>();53995400let component_ids = [test_component_id, test_component_2_id];5401let test_component_value = TestComponent(42);5402let test_component_2_value = TestComponent2(84);54035404let mut entity = world.spawn_empty();5405OwningPtr::make(test_component_value, |ptr1| {5406OwningPtr::make(test_component_2_value, |ptr2| {5407// SAFETY: `ptr1` and `ptr2` match the component ids5408unsafe { entity.insert_by_ids(&component_ids, vec![ptr1, ptr2].into_iter()) };5409});5410});54115412let dynamic_components: Vec<_> = world5413.query::<(&TestComponent, &TestComponent2)>()5414.iter(&world)5415.collect();54165417assert_eq!(5418dynamic_components,5419vec![(&TestComponent(42), &TestComponent2(84))]5420);54215422// Compare with `World` generated using static type equivalents5423let mut static_world = World::new();54245425static_world.spawn((test_component_value, test_component_2_value));5426let static_components: Vec<_> = static_world5427.query::<(&TestComponent, &TestComponent2)>()5428.iter(&static_world)5429.collect();54305431assert_eq!(dynamic_components, static_components);5432}54335434#[test]5435fn entity_mut_remove_by_id() {5436let mut world = World::new();5437let test_component_id = world.register_component::<TestComponent>();54385439let mut entity = world.spawn(TestComponent(42));5440entity.remove_by_id(test_component_id);54415442let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();54435444assert_eq!(components, vec![] as Vec<&TestComponent>);54455446// remove non-existent component does not panic5447world.spawn_empty().remove_by_id(test_component_id);5448}54495450/// Tests that components can be accessed through an `EntityRefExcept`.5451#[test]5452fn entity_ref_except() {5453let mut world = World::new();5454world.register_component::<TestComponent>();5455world.register_component::<TestComponent2>();54565457world.spawn(TestComponent(0)).insert(TestComponent2(0));54585459let mut query = world.query::<EntityRefExcept<TestComponent>>();54605461let mut found = false;5462for entity_ref in query.iter_mut(&mut world) {5463found = true;5464assert!(entity_ref.get::<TestComponent>().is_none());5465assert!(entity_ref.get_ref::<TestComponent>().is_none());5466assert!(matches!(5467entity_ref.get::<TestComponent2>(),5468Some(TestComponent2(0))5469));5470}54715472assert!(found);5473}54745475// Test that a single query can't both contain a mutable reference to a5476// component C and an `EntityRefExcept` that doesn't include C among its5477// exclusions.5478#[test]5479#[should_panic]5480fn entity_ref_except_conflicts_with_self() {5481let mut world = World::new();5482world.spawn(TestComponent(0)).insert(TestComponent2(0));54835484// This should panic, because we have a mutable borrow on5485// `TestComponent` but have a simultaneous indirect immutable borrow on5486// that component via `EntityRefExcept`.5487world.run_system_once(system).unwrap();54885489fn system(_: Query<(&mut TestComponent, EntityRefExcept<TestComponent2>)>) {}5490}54915492// Test that an `EntityRefExcept` that doesn't include a component C among5493// its exclusions can't coexist with a mutable query for that component.5494#[test]5495#[should_panic]5496fn entity_ref_except_conflicts_with_other() {5497let mut world = World::new();5498world.spawn(TestComponent(0)).insert(TestComponent2(0));54995500// This should panic, because we have a mutable borrow on5501// `TestComponent` but have a simultaneous indirect immutable borrow on5502// that component via `EntityRefExcept`.5503world.run_system_once(system).unwrap();55045505fn system(_: Query<&mut TestComponent>, _: Query<EntityRefExcept<TestComponent2>>) {}5506}55075508// Test that an `EntityRefExcept` with an exception for some component C can5509// coexist with a query for that component C.5510#[test]5511fn entity_ref_except_doesnt_conflict() {5512let mut world = World::new();5513world.spawn(TestComponent(0)).insert(TestComponent2(0));55145515world.run_system_once(system).unwrap();55165517fn system(_: Query<&mut TestComponent>, query: Query<EntityRefExcept<TestComponent>>) {5518for entity_ref in query.iter() {5519assert!(matches!(5520entity_ref.get::<TestComponent2>(),5521Some(TestComponent2(0))5522));5523}5524}5525}55265527/// Tests that components can be mutably accessed through an5528/// `EntityMutExcept`.5529#[test]5530fn entity_mut_except() {5531let mut world = World::new();5532world.spawn(TestComponent(0)).insert(TestComponent2(0));55335534let mut query = world.query::<EntityMutExcept<TestComponent>>();55355536let mut found = false;5537for mut entity_mut in query.iter_mut(&mut world) {5538found = true;5539assert!(entity_mut.get::<TestComponent>().is_none());5540assert!(entity_mut.get_ref::<TestComponent>().is_none());5541assert!(entity_mut.get_mut::<TestComponent>().is_none());5542assert!(matches!(5543entity_mut.get::<TestComponent2>(),5544Some(TestComponent2(0))5545));5546}55475548assert!(found);5549}55505551// Test that a single query can't both contain a mutable reference to a5552// component C and an `EntityMutExcept` that doesn't include C among its5553// exclusions.5554#[test]5555#[should_panic]5556fn entity_mut_except_conflicts_with_self() {5557let mut world = World::new();5558world.spawn(TestComponent(0)).insert(TestComponent2(0));55595560// This should panic, because we have a mutable borrow on5561// `TestComponent` but have a simultaneous indirect immutable borrow on5562// that component via `EntityRefExcept`.5563world.run_system_once(system).unwrap();55645565fn system(_: Query<(&mut TestComponent, EntityMutExcept<TestComponent2>)>) {}5566}55675568// Test that an `EntityMutExcept` that doesn't include a component C among5569// its exclusions can't coexist with a query for that component.5570#[test]5571#[should_panic]5572fn entity_mut_except_conflicts_with_other() {5573let mut world = World::new();5574world.spawn(TestComponent(0)).insert(TestComponent2(0));55755576// This should panic, because we have a mutable borrow on5577// `TestComponent` but have a simultaneous indirect immutable borrow on5578// that component via `EntityRefExcept`.5579world.run_system_once(system).unwrap();55805581fn system(_: Query<&mut TestComponent>, mut query: Query<EntityMutExcept<TestComponent2>>) {5582for mut entity_mut in query.iter_mut() {5583assert!(entity_mut5584.get_mut::<TestComponent2>()5585.is_some_and(|component| component.0 == 0));5586}5587}5588}55895590// Test that an `EntityMutExcept` with an exception for some component C can5591// coexist with a query for that component C.5592#[test]5593fn entity_mut_except_doesnt_conflict() {5594let mut world = World::new();5595world.spawn(TestComponent(0)).insert(TestComponent2(0));55965597world.run_system_once(system).unwrap();55985599fn system(_: Query<&mut TestComponent>, mut query: Query<EntityMutExcept<TestComponent>>) {5600for mut entity_mut in query.iter_mut() {5601assert!(entity_mut5602.get_mut::<TestComponent2>()5603.is_some_and(|component| component.0 == 0));5604}5605}5606}56075608#[test]5609fn entity_mut_except_registers_components() {5610// Checks for a bug where `EntityMutExcept` would not register the component and5611// would therefore not include an exception, causing it to conflict with the later query.5612fn system1(_query: Query<EntityMutExcept<TestComponent>>, _: Query<&mut TestComponent>) {}5613let mut world = World::new();5614world.run_system_once(system1).unwrap();56155616fn system2(_: Query<&mut TestComponent>, _query: Query<EntityMutExcept<TestComponent>>) {}5617let mut world = World::new();5618world.run_system_once(system2).unwrap();5619}56205621#[derive(Component)]5622struct A;56235624#[test]5625fn disjoint_access() {5626fn disjoint_readonly(_: Query<EntityMut, With<A>>, _: Query<EntityRef, Without<A>>) {}56275628fn disjoint_mutable(_: Query<EntityMut, With<A>>, _: Query<EntityMut, Without<A>>) {}56295630assert_is_system(disjoint_readonly);5631assert_is_system(disjoint_mutable);5632}56335634#[test]5635fn ref_compatible() {5636fn borrow_system(_: Query<(EntityRef, &A)>, _: Query<&A>) {}56375638assert_is_system(borrow_system);5639}56405641#[test]5642fn ref_compatible_with_resource() {5643fn borrow_system(_: Query<EntityRef>, _: Res<R>) {}56445645assert_is_system(borrow_system);5646}56475648#[test]5649fn ref_compatible_with_resource_mut() {5650fn borrow_system(_: Query<EntityRef>, _: ResMut<R>) {}56515652assert_is_system(borrow_system);5653}56545655#[test]5656#[should_panic]5657fn ref_incompatible_with_mutable_component() {5658fn incompatible_system(_: Query<(EntityRef, &mut A)>) {}56595660assert_is_system(incompatible_system);5661}56625663#[test]5664#[should_panic]5665fn ref_incompatible_with_mutable_query() {5666fn incompatible_system(_: Query<EntityRef>, _: Query<&mut A>) {}56675668assert_is_system(incompatible_system);5669}56705671#[test]5672fn mut_compatible_with_entity() {5673fn borrow_mut_system(_: Query<(Entity, EntityMut)>) {}56745675assert_is_system(borrow_mut_system);5676}56775678#[test]5679fn mut_compatible_with_resource() {5680fn borrow_mut_system(_: Res<R>, _: Query<EntityMut>) {}56815682assert_is_system(borrow_mut_system);5683}56845685#[test]5686fn mut_compatible_with_resource_mut() {5687fn borrow_mut_system(_: ResMut<R>, _: Query<EntityMut>) {}56885689assert_is_system(borrow_mut_system);5690}56915692#[test]5693#[should_panic]5694fn mut_incompatible_with_read_only_component() {5695fn incompatible_system(_: Query<(EntityMut, &A)>) {}56965697assert_is_system(incompatible_system);5698}56995700#[test]5701#[should_panic]5702fn mut_incompatible_with_mutable_component() {5703fn incompatible_system(_: Query<(EntityMut, &mut A)>) {}57045705assert_is_system(incompatible_system);5706}57075708#[test]5709#[should_panic]5710fn mut_incompatible_with_read_only_query() {5711fn incompatible_system(_: Query<EntityMut>, _: Query<&A>) {}57125713assert_is_system(incompatible_system);5714}57155716#[test]5717#[should_panic]5718fn mut_incompatible_with_mutable_query() {5719fn incompatible_system(_: Query<EntityMut>, _: Query<&mut A>) {}57205721assert_is_system(incompatible_system);5722}57235724#[test]5725fn filtered_entity_ref_normal() {5726let mut world = World::new();5727let a_id = world.register_component::<A>();57285729let e: FilteredEntityRef = world.spawn(A).into();57305731assert!(e.get::<A>().is_some());5732assert!(e.get_ref::<A>().is_some());5733assert!(e.get_change_ticks::<A>().is_some());5734assert!(e.get_by_id(a_id).is_some());5735assert!(e.get_change_ticks_by_id(a_id).is_some());5736}57375738#[test]5739fn filtered_entity_ref_missing() {5740let mut world = World::new();5741let a_id = world.register_component::<A>();57425743let e: FilteredEntityRef = world.spawn(()).into();57445745assert!(e.get::<A>().is_none());5746assert!(e.get_ref::<A>().is_none());5747assert!(e.get_change_ticks::<A>().is_none());5748assert!(e.get_by_id(a_id).is_none());5749assert!(e.get_change_ticks_by_id(a_id).is_none());5750}57515752#[test]5753fn filtered_entity_mut_normal() {5754let mut world = World::new();5755let a_id = world.register_component::<A>();57565757let mut e: FilteredEntityMut = world.spawn(A).into();57585759assert!(e.get::<A>().is_some());5760assert!(e.get_ref::<A>().is_some());5761assert!(e.get_mut::<A>().is_some());5762assert!(e.get_change_ticks::<A>().is_some());5763assert!(e.get_by_id(a_id).is_some());5764assert!(e.get_mut_by_id(a_id).is_some());5765assert!(e.get_change_ticks_by_id(a_id).is_some());5766}57675768#[test]5769fn filtered_entity_mut_missing() {5770let mut world = World::new();5771let a_id = world.register_component::<A>();57725773let mut e: FilteredEntityMut = world.spawn(()).into();57745775assert!(e.get::<A>().is_none());5776assert!(e.get_ref::<A>().is_none());5777assert!(e.get_mut::<A>().is_none());5778assert!(e.get_change_ticks::<A>().is_none());5779assert!(e.get_by_id(a_id).is_none());5780assert!(e.get_mut_by_id(a_id).is_none());5781assert!(e.get_change_ticks_by_id(a_id).is_none());5782}57835784#[derive(Component, PartialEq, Eq, Debug)]5785struct X(usize);57865787#[derive(Component, PartialEq, Eq, Debug)]5788struct Y(usize);57895790#[test]5791fn get_components() {5792let mut world = World::default();5793let e1 = world.spawn((X(7), Y(10))).id();5794let e2 = world.spawn(X(8)).id();5795let e3 = world.spawn_empty().id();57965797assert_eq!(5798Some((&X(7), &Y(10))),5799world.entity(e1).get_components::<(&X, &Y)>()5800);5801assert_eq!(None, world.entity(e2).get_components::<(&X, &Y)>());5802assert_eq!(None, world.entity(e3).get_components::<(&X, &Y)>());5803}58045805#[test]5806fn get_by_id_array() {5807let mut world = World::default();5808let e1 = world.spawn((X(7), Y(10))).id();5809let e2 = world.spawn(X(8)).id();5810let e3 = world.spawn_empty().id();58115812let x_id = world.register_component::<X>();5813let y_id = world.register_component::<Y>();58145815assert_eq!(5816Ok((&X(7), &Y(10))),5817world5818.entity(e1)5819.get_by_id([x_id, y_id])5820.map(|[x_ptr, y_ptr]| {5821// SAFETY: components match the id they were fetched with5822(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5823})5824);5825assert_eq!(5826Err(EntityComponentError::MissingComponent(y_id)),5827world5828.entity(e2)5829.get_by_id([x_id, y_id])5830.map(|[x_ptr, y_ptr]| {5831// SAFETY: components match the id they were fetched with5832(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5833})5834);5835assert_eq!(5836Err(EntityComponentError::MissingComponent(x_id)),5837world5838.entity(e3)5839.get_by_id([x_id, y_id])5840.map(|[x_ptr, y_ptr]| {5841// SAFETY: components match the id they were fetched with5842(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5843})5844);5845}58465847#[test]5848fn get_by_id_vec() {5849let mut world = World::default();5850let e1 = world.spawn((X(7), Y(10))).id();5851let e2 = world.spawn(X(8)).id();5852let e3 = world.spawn_empty().id();58535854let x_id = world.register_component::<X>();5855let y_id = world.register_component::<Y>();58565857assert_eq!(5858Ok((&X(7), &Y(10))),5859world5860.entity(e1)5861.get_by_id(&[x_id, y_id] as &[ComponentId])5862.map(|ptrs| {5863let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {5864panic!("get_by_id(slice) didn't return 2 elements")5865};58665867// SAFETY: components match the id they were fetched with5868(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5869})5870);5871assert_eq!(5872Err(EntityComponentError::MissingComponent(y_id)),5873world5874.entity(e2)5875.get_by_id(&[x_id, y_id] as &[ComponentId])5876.map(|ptrs| {5877let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {5878panic!("get_by_id(slice) didn't return 2 elements")5879};58805881// SAFETY: components match the id they were fetched with5882(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5883})5884);5885assert_eq!(5886Err(EntityComponentError::MissingComponent(x_id)),5887world5888.entity(e3)5889.get_by_id(&[x_id, y_id] as &[ComponentId])5890.map(|ptrs| {5891let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {5892panic!("get_by_id(slice) didn't return 2 elements")5893};58945895// SAFETY: components match the id they were fetched with5896(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5897})5898);5899}59005901#[test]5902fn get_mut_by_id_array() {5903let mut world = World::default();5904let e1 = world.spawn((X(7), Y(10))).id();5905let e2 = world.spawn(X(8)).id();5906let e3 = world.spawn_empty().id();59075908let x_id = world.register_component::<X>();5909let y_id = world.register_component::<Y>();59105911assert_eq!(5912Ok((&mut X(7), &mut Y(10))),5913world5914.entity_mut(e1)5915.get_mut_by_id([x_id, y_id])5916.map(|[x_ptr, y_ptr]| {5917// SAFETY: components match the id they were fetched with5918(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {5919y_ptr.into_inner().deref_mut::<Y>()5920})5921})5922);5923assert_eq!(5924Err(EntityComponentError::MissingComponent(y_id)),5925world5926.entity_mut(e2)5927.get_mut_by_id([x_id, y_id])5928.map(|[x_ptr, y_ptr]| {5929// SAFETY: components match the id they were fetched with5930(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {5931y_ptr.into_inner().deref_mut::<Y>()5932})5933})5934);5935assert_eq!(5936Err(EntityComponentError::MissingComponent(x_id)),5937world5938.entity_mut(e3)5939.get_mut_by_id([x_id, y_id])5940.map(|[x_ptr, y_ptr]| {5941// SAFETY: components match the id they were fetched with5942(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {5943y_ptr.into_inner().deref_mut::<Y>()5944})5945})5946);59475948assert_eq!(5949Err(EntityComponentError::AliasedMutability(x_id)),5950world5951.entity_mut(e1)5952.get_mut_by_id([x_id, x_id])5953.map(|_| { unreachable!() })5954);5955assert_eq!(5956Err(EntityComponentError::AliasedMutability(x_id)),5957world5958.entity_mut(e3)5959.get_mut_by_id([x_id, x_id])5960.map(|_| { unreachable!() })5961);5962}59635964#[test]5965fn get_mut_by_id_vec() {5966let mut world = World::default();5967let e1 = world.spawn((X(7), Y(10))).id();5968let e2 = world.spawn(X(8)).id();5969let e3 = world.spawn_empty().id();59705971let x_id = world.register_component::<X>();5972let y_id = world.register_component::<Y>();59735974assert_eq!(5975Ok((&mut X(7), &mut Y(10))),5976world5977.entity_mut(e1)5978.get_mut_by_id(&[x_id, y_id] as &[ComponentId])5979.map(|ptrs| {5980let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {5981panic!("get_mut_by_id(slice) didn't return 2 elements")5982};59835984// SAFETY: components match the id they were fetched with5985(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {5986y_ptr.into_inner().deref_mut::<Y>()5987})5988})5989);5990assert_eq!(5991Err(EntityComponentError::MissingComponent(y_id)),5992world5993.entity_mut(e2)5994.get_mut_by_id(&[x_id, y_id] as &[ComponentId])5995.map(|ptrs| {5996let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {5997panic!("get_mut_by_id(slice) didn't return 2 elements")5998};59996000// SAFETY: components match the id they were fetched with6001(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {6002y_ptr.into_inner().deref_mut::<Y>()6003})6004})6005);6006assert_eq!(6007Err(EntityComponentError::MissingComponent(x_id)),6008world6009.entity_mut(e3)6010.get_mut_by_id(&[x_id, y_id] as &[ComponentId])6011.map(|ptrs| {6012let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {6013panic!("get_mut_by_id(slice) didn't return 2 elements")6014};60156016// SAFETY: components match the id they were fetched with6017(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {6018y_ptr.into_inner().deref_mut::<Y>()6019})6020})6021);60226023assert_eq!(6024Err(EntityComponentError::AliasedMutability(x_id)),6025world6026.entity_mut(e1)6027.get_mut_by_id(&[x_id, x_id])6028.map(|_| { unreachable!() })6029);6030assert_eq!(6031Err(EntityComponentError::AliasedMutability(x_id)),6032world6033.entity_mut(e3)6034.get_mut_by_id(&[x_id, x_id])6035.map(|_| { unreachable!() })6036);6037}60386039#[test]6040fn get_mut_by_id_unchecked() {6041let mut world = World::default();6042let e1 = world.spawn((X(7), Y(10))).id();6043let x_id = world.register_component::<X>();6044let y_id = world.register_component::<Y>();60456046let e1_mut = &world.get_entity_mut([e1]).unwrap()[0];6047// SAFETY: The entity e1 contains component X.6048let x_ptr = unsafe { e1_mut.get_mut_by_id_unchecked(x_id) }.unwrap();6049// SAFETY: The entity e1 contains component Y, with components X and Y being mutually independent.6050let y_ptr = unsafe { e1_mut.get_mut_by_id_unchecked(y_id) }.unwrap();60516052// SAFETY: components match the id they were fetched with6053let x_component = unsafe { x_ptr.into_inner().deref_mut::<X>() };6054x_component.0 += 1;6055// SAFETY: components match the id they were fetched with6056let y_component = unsafe { y_ptr.into_inner().deref_mut::<Y>() };6057y_component.0 -= 1;60586059assert_eq!((&mut X(8), &mut Y(9)), (x_component, y_component));6060}60616062#[derive(EntityEvent)]6063struct TestEvent(Entity);60646065#[test]6066fn adding_observer_updates_location() {6067let mut world = World::new();6068let entity = world6069.spawn_empty()6070.observe(|event: On<TestEvent>, mut commands: Commands| {6071commands6072.entity(event.event_target())6073.insert(TestComponent(0));6074})6075.id();60766077// this should not be needed, but is currently required to tease out the bug6078world.flush();60796080let mut a = world.entity_mut(entity);6081// SAFETY: this _intentionally_ doesn't update the location, to ensure that we're actually testing6082// that observe() updates location6083unsafe { a.world_mut().trigger(TestEvent(entity)) }6084a.observe(|_: On<TestEvent>| {}); // this flushes commands implicitly by spawning6085let location = a.location();6086assert_eq!(world.entities().get(entity), Some(location));6087}60886089#[test]6090#[should_panic]6091fn location_on_despawned_entity_panics() {6092let mut world = World::new();6093world.add_observer(|add: On<Add, TestComponent>, mut commands: Commands| {6094commands.entity(add.entity).despawn();6095});6096let entity = world.spawn_empty().id();6097let mut a = world.entity_mut(entity);6098a.insert(TestComponent(0));6099a.location();6100}61016102#[derive(Resource)]6103struct TestFlush(usize);61046105fn count_flush(world: &mut World) {6106world.resource_mut::<TestFlush>().0 += 1;6107}61086109#[test]6110fn archetype_modifications_trigger_flush() {6111let mut world = World::new();6112world.insert_resource(TestFlush(0));6113world.add_observer(|_: On<Add, TestComponent>, mut commands: Commands| {6114commands.queue(count_flush);6115});6116world.add_observer(|_: On<Remove, TestComponent>, mut commands: Commands| {6117commands.queue(count_flush);6118});6119world.commands().queue(count_flush);6120let entity = world.spawn_empty().id();6121assert_eq!(world.resource::<TestFlush>().0, 1);6122world.commands().queue(count_flush);6123world.flush_commands();6124let mut a = world.entity_mut(entity);6125assert_eq!(a.world().resource::<TestFlush>().0, 2);6126a.insert(TestComponent(0));6127assert_eq!(a.world().resource::<TestFlush>().0, 3);6128a.remove::<TestComponent>();6129assert_eq!(a.world().resource::<TestFlush>().0, 4);6130a.insert(TestComponent(0));6131assert_eq!(a.world().resource::<TestFlush>().0, 5);6132let _ = a.take::<TestComponent>();6133assert_eq!(a.world().resource::<TestFlush>().0, 6);6134a.insert(TestComponent(0));6135assert_eq!(a.world().resource::<TestFlush>().0, 7);6136a.retain::<()>();6137assert_eq!(a.world().resource::<TestFlush>().0, 8);6138a.insert(TestComponent(0));6139assert_eq!(a.world().resource::<TestFlush>().0, 9);6140a.clear();6141assert_eq!(a.world().resource::<TestFlush>().0, 10);6142a.insert(TestComponent(0));6143assert_eq!(a.world().resource::<TestFlush>().0, 11);6144a.despawn();6145assert_eq!(world.resource::<TestFlush>().0, 12);6146}61476148#[derive(Resource)]6149struct TestVec(Vec<&'static str>);61506151#[derive(Component)]6152#[component(on_add = ord_a_hook_on_add, on_insert = ord_a_hook_on_insert, on_replace = ord_a_hook_on_replace, on_remove = ord_a_hook_on_remove)]6153struct OrdA;61546155fn ord_a_hook_on_add(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {6156world.resource_mut::<TestVec>().0.push("OrdA hook on_add");6157world.commands().entity(entity).insert(OrdB);6158}61596160fn ord_a_hook_on_insert(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {6161world6162.resource_mut::<TestVec>()6163.06164.push("OrdA hook on_insert");6165world.commands().entity(entity).remove::<OrdA>();6166world.commands().entity(entity).remove::<OrdB>();6167}61686169fn ord_a_hook_on_replace(mut world: DeferredWorld, _: HookContext) {6170world6171.resource_mut::<TestVec>()6172.06173.push("OrdA hook on_replace");6174}61756176fn ord_a_hook_on_remove(mut world: DeferredWorld, _: HookContext) {6177world6178.resource_mut::<TestVec>()6179.06180.push("OrdA hook on_remove");6181}61826183fn ord_a_observer_on_add(_event: On<Add, OrdA>, mut res: ResMut<TestVec>) {6184res.0.push("OrdA observer on_add");6185}61866187fn ord_a_observer_on_insert(_event: On<Insert, OrdA>, mut res: ResMut<TestVec>) {6188res.0.push("OrdA observer on_insert");6189}61906191fn ord_a_observer_on_replace(_event: On<Replace, OrdA>, mut res: ResMut<TestVec>) {6192res.0.push("OrdA observer on_replace");6193}61946195fn ord_a_observer_on_remove(_event: On<Remove, OrdA>, mut res: ResMut<TestVec>) {6196res.0.push("OrdA observer on_remove");6197}61986199#[derive(Component)]6200#[component(on_add = ord_b_hook_on_add, on_insert = ord_b_hook_on_insert, on_replace = ord_b_hook_on_replace, on_remove = ord_b_hook_on_remove)]6201struct OrdB;62026203fn ord_b_hook_on_add(mut world: DeferredWorld, _: HookContext) {6204world.resource_mut::<TestVec>().0.push("OrdB hook on_add");6205world.commands().queue(|world: &mut World| {6206world6207.resource_mut::<TestVec>()6208.06209.push("OrdB command on_add");6210});6211}62126213fn ord_b_hook_on_insert(mut world: DeferredWorld, _: HookContext) {6214world6215.resource_mut::<TestVec>()6216.06217.push("OrdB hook on_insert");6218}62196220fn ord_b_hook_on_replace(mut world: DeferredWorld, _: HookContext) {6221world6222.resource_mut::<TestVec>()6223.06224.push("OrdB hook on_replace");6225}62266227fn ord_b_hook_on_remove(mut world: DeferredWorld, _: HookContext) {6228world6229.resource_mut::<TestVec>()6230.06231.push("OrdB hook on_remove");6232}62336234fn ord_b_observer_on_add(_event: On<Add, OrdB>, mut res: ResMut<TestVec>) {6235res.0.push("OrdB observer on_add");6236}62376238fn ord_b_observer_on_insert(_event: On<Insert, OrdB>, mut res: ResMut<TestVec>) {6239res.0.push("OrdB observer on_insert");6240}62416242fn ord_b_observer_on_replace(_event: On<Replace, OrdB>, mut res: ResMut<TestVec>) {6243res.0.push("OrdB observer on_replace");6244}62456246fn ord_b_observer_on_remove(_event: On<Remove, OrdB>, mut res: ResMut<TestVec>) {6247res.0.push("OrdB observer on_remove");6248}62496250#[test]6251fn command_ordering_is_correct() {6252let mut world = World::new();6253world.insert_resource(TestVec(Vec::new()));6254world.add_observer(ord_a_observer_on_add);6255world.add_observer(ord_a_observer_on_insert);6256world.add_observer(ord_a_observer_on_replace);6257world.add_observer(ord_a_observer_on_remove);6258world.add_observer(ord_b_observer_on_add);6259world.add_observer(ord_b_observer_on_insert);6260world.add_observer(ord_b_observer_on_replace);6261world.add_observer(ord_b_observer_on_remove);6262let _entity = world.spawn(OrdA).id();6263let expected = [6264"OrdA hook on_add", // adds command to insert OrdB6265"OrdA observer on_add",6266"OrdA hook on_insert", // adds command to despawn entity6267"OrdA observer on_insert",6268"OrdB hook on_add", // adds command to just add to this log6269"OrdB observer on_add",6270"OrdB hook on_insert",6271"OrdB observer on_insert",6272"OrdB command on_add", // command added by OrdB hook on_add, needs to run before despawn command6273"OrdA observer on_replace", // start of despawn6274"OrdA hook on_replace",6275"OrdA observer on_remove",6276"OrdA hook on_remove",6277"OrdB observer on_replace",6278"OrdB hook on_replace",6279"OrdB observer on_remove",6280"OrdB hook on_remove",6281];6282world.flush();6283assert_eq!(world.resource_mut::<TestVec>().0.as_slice(), &expected[..]);6284}62856286#[test]6287fn entity_world_mut_clone_and_move_components() {6288#[derive(Component, Clone, PartialEq, Debug)]6289struct A;62906291#[derive(Component, Clone, PartialEq, Debug)]6292struct B;62936294#[derive(Component, Clone, PartialEq, Debug)]6295struct C(u32);62966297let mut world = World::new();6298let entity_a = world.spawn((A, B, C(5))).id();6299let entity_b = world.spawn((A, C(4))).id();63006301world.entity_mut(entity_a).clone_components::<B>(entity_b);6302assert_eq!(world.entity(entity_a).get::<B>(), Some(&B));6303assert_eq!(world.entity(entity_b).get::<B>(), Some(&B));63046305world.entity_mut(entity_a).move_components::<C>(entity_b);6306assert_eq!(world.entity(entity_a).get::<C>(), None);6307assert_eq!(world.entity(entity_b).get::<C>(), Some(&C(5)));63086309assert_eq!(world.entity(entity_a).get::<A>(), Some(&A));6310assert_eq!(world.entity(entity_b).get::<A>(), Some(&A));6311}63126313#[test]6314fn entity_world_mut_clone_with_move_and_require() {6315#[derive(Component, Clone, PartialEq, Debug)]6316#[require(B(3))]6317struct A;63186319#[derive(Component, Clone, PartialEq, Debug, Default)]6320#[require(C(3))]6321struct B(u32);63226323#[derive(Component, Clone, PartialEq, Debug, Default)]6324#[require(D)]6325struct C(u32);63266327#[derive(Component, Clone, PartialEq, Debug, Default)]6328struct D;63296330let mut world = World::new();6331let entity_a = world.spawn((A, B(5))).id();6332let entity_b = world.spawn_empty().id();63336334world6335.entity_mut(entity_a)6336.clone_with_opt_in(entity_b, |builder| {6337builder6338.move_components(true)6339.allow::<C>()6340.without_required_components(|builder| {6341builder.allow::<A>();6342});6343});63446345assert_eq!(world.entity(entity_a).get::<A>(), None);6346assert_eq!(world.entity(entity_b).get::<A>(), Some(&A));63476348assert_eq!(world.entity(entity_a).get::<B>(), Some(&B(5)));6349assert_eq!(world.entity(entity_b).get::<B>(), Some(&B(3)));63506351assert_eq!(world.entity(entity_a).get::<C>(), None);6352assert_eq!(world.entity(entity_b).get::<C>(), Some(&C(3)));63536354assert_eq!(world.entity(entity_a).get::<D>(), None);6355assert_eq!(world.entity(entity_b).get::<D>(), Some(&D));6356}63576358#[test]6359fn update_despawned_by_after_observers() {6360let mut world = World::new();63616362#[derive(Component)]6363#[component(on_remove = get_tracked)]6364struct C;63656366static TRACKED: OnceLock<(MaybeLocation, Tick)> = OnceLock::new();6367fn get_tracked(world: DeferredWorld, HookContext { entity, .. }: HookContext) {6368TRACKED.get_or_init(|| {6369let by = world6370.entities6371.entity_get_spawned_or_despawned_by(entity)6372.map(|l| l.unwrap());6373let at = world6374.entities6375.entity_get_spawned_or_despawned_at(entity)6376.unwrap();6377(by, at)6378});6379}63806381#[track_caller]6382fn caller_spawn(world: &mut World) -> (Entity, MaybeLocation, Tick) {6383let caller = MaybeLocation::caller();6384(world.spawn(C).id(), caller, world.change_tick())6385}6386let (entity, spawner, spawn_tick) = caller_spawn(&mut world);63876388assert_eq!(6389spawner,6390world6391.entities()6392.entity_get_spawned_or_despawned_by(entity)6393.map(|l| l.unwrap())6394);63956396#[track_caller]6397fn caller_despawn(world: &mut World, entity: Entity) -> (MaybeLocation, Tick) {6398world.despawn(entity);6399(MaybeLocation::caller(), world.change_tick())6400}6401let (despawner, despawn_tick) = caller_despawn(&mut world, entity);64026403assert_eq!((spawner, spawn_tick), *TRACKED.get().unwrap());6404assert_eq!(6405despawner,6406world6407.entities()6408.entity_get_spawned_or_despawned_by(entity)6409.map(|l| l.unwrap())6410);6411assert_eq!(6412despawn_tick,6413world6414.entities()6415.entity_get_spawned_or_despawned_at(entity)6416.unwrap()6417);6418}64196420#[test]6421fn with_component_activates_hooks() {6422use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};64236424#[derive(Component, PartialEq, Eq, Debug)]6425#[component(immutable)]6426struct Foo(bool);64276428static EXPECTED_VALUE: AtomicBool = AtomicBool::new(false);64296430static ADD_COUNT: AtomicU8 = AtomicU8::new(0);6431static REMOVE_COUNT: AtomicU8 = AtomicU8::new(0);6432static REPLACE_COUNT: AtomicU8 = AtomicU8::new(0);6433static INSERT_COUNT: AtomicU8 = AtomicU8::new(0);64346435let mut world = World::default();64366437world.register_component::<Foo>();6438world6439.register_component_hooks::<Foo>()6440.on_add(|world, context| {6441ADD_COUNT.fetch_add(1, Ordering::Relaxed);64426443assert_eq!(6444world.get(context.entity),6445Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))6446);6447})6448.on_remove(|world, context| {6449REMOVE_COUNT.fetch_add(1, Ordering::Relaxed);64506451assert_eq!(6452world.get(context.entity),6453Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))6454);6455})6456.on_replace(|world, context| {6457REPLACE_COUNT.fetch_add(1, Ordering::Relaxed);64586459assert_eq!(6460world.get(context.entity),6461Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))6462);6463})6464.on_insert(|world, context| {6465INSERT_COUNT.fetch_add(1, Ordering::Relaxed);64666467assert_eq!(6468world.get(context.entity),6469Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))6470);6471});64726473let entity = world.spawn(Foo(false)).id();64746475assert_eq!(ADD_COUNT.load(Ordering::Relaxed), 1);6476assert_eq!(REMOVE_COUNT.load(Ordering::Relaxed), 0);6477assert_eq!(REPLACE_COUNT.load(Ordering::Relaxed), 0);6478assert_eq!(INSERT_COUNT.load(Ordering::Relaxed), 1);64796480let mut entity = world.entity_mut(entity);64816482let archetype_pointer_before = &raw const *entity.archetype();64836484assert_eq!(entity.get::<Foo>(), Some(&Foo(false)));64856486entity.modify_component(|foo: &mut Foo| {6487foo.0 = true;6488EXPECTED_VALUE.store(foo.0, Ordering::Relaxed);6489});64906491let archetype_pointer_after = &raw const *entity.archetype();64926493assert_eq!(entity.get::<Foo>(), Some(&Foo(true)));64946495assert_eq!(ADD_COUNT.load(Ordering::Relaxed), 1);6496assert_eq!(REMOVE_COUNT.load(Ordering::Relaxed), 0);6497assert_eq!(REPLACE_COUNT.load(Ordering::Relaxed), 1);6498assert_eq!(INSERT_COUNT.load(Ordering::Relaxed), 2);64996500assert_eq!(archetype_pointer_before, archetype_pointer_after);6501}65026503#[test]6504fn bundle_remove_only_triggers_for_present_components() {6505let mut world = World::default();65066507#[derive(Component)]6508struct A;65096510#[derive(Component)]6511struct B;65126513#[derive(Resource, PartialEq, Eq, Debug)]6514struct Tracker {6515a: bool,6516b: bool,6517}65186519world.insert_resource(Tracker { a: false, b: false });6520let entity = world.spawn(A).id();65216522world.add_observer(|_: On<Remove, A>, mut tracker: ResMut<Tracker>| {6523tracker.a = true;6524});6525world.add_observer(|_: On<Remove, B>, mut tracker: ResMut<Tracker>| {6526tracker.b = true;6527});65286529world.entity_mut(entity).remove::<(A, B)>();65306531assert_eq!(6532world.resource::<Tracker>(),6533&Tracker {6534a: true,6535// The entity didn't have a B component, so it should not have been triggered.6536b: false,6537}6538);6539}6540}654165426543