Path: blob/main/crates/bevy_ecs/src/world/entity_ref.rs
6849 views
use crate::{1archetype::Archetype,2bundle::{3Bundle, BundleFromComponents, BundleInserter, BundleRemover, DynamicBundle, InsertMode,4},5change_detection::{MaybeLocation, MutUntyped},6component::{Component, ComponentId, ComponentTicks, Components, Mutable, StorageType, Tick},7entity::{8ContainsEntity, Entity, EntityCloner, EntityClonerBuilder, EntityEquivalent,9EntityIdLocation, EntityLocation, OptIn, OptOut,10},11event::{EntityComponentsTrigger, EntityEvent},12lifecycle::{Despawn, Remove, Replace, DESPAWN, REMOVE, REPLACE},13observer::Observer,14query::{Access, DebugCheckedUnwrap, ReadOnlyQueryData, ReleaseStateQueryData},15relationship::RelationshipHookMode,16resource::Resource,17storage::{SparseSets, Table},18system::IntoObserverSystem,19world::{error::EntityComponentError, unsafe_world_cell::UnsafeEntityCell, Mut, Ref, World},20};21use alloc::vec::Vec;22use bevy_platform::collections::{HashMap, HashSet};23use bevy_ptr::{move_as_ptr, MovingPtr, OwningPtr, Ptr};24use core::{25any::TypeId,26cmp::Ordering,27hash::{Hash, Hasher},28marker::PhantomData,29mem::MaybeUninit,30};31use thiserror::Error;3233/// A read-only reference to a particular [`Entity`] and all of its components.34///35/// # Examples36///37/// Read-only access disjoint with mutable access.38///39/// ```40/// # use bevy_ecs::prelude::*;41/// # #[derive(Component)] pub struct A;42/// # #[derive(Component)] pub struct B;43/// fn disjoint_system(44/// query1: Query<&mut A>,45/// query2: Query<EntityRef, Without<A>>,46/// ) {47/// // ...48/// }49/// # bevy_ecs::system::assert_is_system(disjoint_system);50/// ```51#[derive(Copy, Clone)]52pub struct EntityRef<'w> {53cell: UnsafeEntityCell<'w>,54}5556impl<'w> EntityRef<'w> {57/// # Safety58/// - `cell` must have permission to read every component of the entity.59/// - No mutable accesses to any of the entity's components may exist60/// at the same time as the returned [`EntityRef`].61#[inline]62pub(crate) unsafe fn new(cell: UnsafeEntityCell<'w>) -> Self {63Self { cell }64}6566/// Returns the [ID](Entity) of the current entity.67#[inline]68#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]69pub fn id(&self) -> Entity {70self.cell.id()71}7273/// Gets metadata indicating the location where the current entity is stored.74#[inline]75pub fn location(&self) -> EntityLocation {76self.cell.location()77}7879/// Returns the archetype that the current entity belongs to.80#[inline]81pub fn archetype(&self) -> &Archetype {82self.cell.archetype()83}8485/// Returns `true` if the current entity has a component of type `T`.86/// Otherwise, this returns `false`.87///88/// ## Notes89///90/// If you do not know the concrete type of a component, consider using91/// [`Self::contains_id`] or [`Self::contains_type_id`].92#[inline]93pub fn contains<T: Component>(&self) -> bool {94self.contains_type_id(TypeId::of::<T>())95}9697/// Returns `true` if the current entity has a component identified by `component_id`.98/// Otherwise, this returns false.99///100/// ## Notes101///102/// - If you know the concrete type of the component, you should prefer [`Self::contains`].103/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using104/// [`Self::contains_type_id`].105#[inline]106pub fn contains_id(&self, component_id: ComponentId) -> bool {107self.cell.contains_id(component_id)108}109110/// Returns `true` if the current entity has a component with the type identified by `type_id`.111/// Otherwise, this returns false.112///113/// ## Notes114///115/// - If you know the concrete type of the component, you should prefer [`Self::contains`].116/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].117#[inline]118pub fn contains_type_id(&self, type_id: TypeId) -> bool {119self.cell.contains_type_id(type_id)120}121122/// Gets access to the component of type `T` for the current entity.123/// Returns `None` if the entity does not have a component of type `T`.124#[inline]125pub fn get<T: Component>(&self) -> Option<&'w T> {126// SAFETY: We have read-only access to all components of this entity.127unsafe { self.cell.get::<T>() }128}129130/// Gets access to the component of type `T` for the current entity,131/// including change detection information as a [`Ref`].132///133/// Returns `None` if the entity does not have a component of type `T`.134#[inline]135pub fn get_ref<T: Component>(&self) -> Option<Ref<'w, T>> {136// SAFETY: We have read-only access to all components of this entity.137unsafe { self.cell.get_ref::<T>() }138}139140/// Retrieves the change ticks for the given component. This can be useful for implementing change141/// detection in custom runtimes.142#[inline]143pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {144// SAFETY: We have read-only access to all components of this entity.145unsafe { self.cell.get_change_ticks::<T>() }146}147148/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change149/// detection in custom runtimes.150///151/// **You should prefer to use the typed API [`EntityRef::get_change_ticks`] where possible and only152/// use this in cases where the actual component types are not known at153/// compile time.**154#[inline]155pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {156// SAFETY: We have read-only access to all components of this entity.157unsafe { self.cell.get_change_ticks_by_id(component_id) }158}159160/// Returns [untyped read-only reference(s)](Ptr) to component(s) for the161/// current entity, based on the given [`ComponentId`]s.162///163/// **You should prefer to use the typed API [`EntityRef::get`] where164/// possible and only use this in cases where the actual component types165/// are not known at compile time.**166///167/// Unlike [`EntityRef::get`], this returns untyped reference(s) to168/// component(s), and it's the job of the caller to ensure the correct169/// type(s) are dereferenced (if necessary).170///171/// # Errors172///173/// Returns [`EntityComponentError::MissingComponent`] if the entity does174/// not have a component.175///176/// # Examples177///178/// ## Single [`ComponentId`]179///180/// ```181/// # use bevy_ecs::prelude::*;182/// #183/// # #[derive(Component, PartialEq, Debug)]184/// # pub struct Foo(i32);185/// # let mut world = World::new();186/// let entity = world.spawn(Foo(42)).id();187///188/// // Grab the component ID for `Foo` in whatever way you like.189/// let component_id = world.register_component::<Foo>();190///191/// // Then, get the component by ID.192/// let ptr = world.entity(entity).get_by_id(component_id);193/// # assert_eq!(unsafe { ptr.unwrap().deref::<Foo>() }, &Foo(42));194/// ```195///196/// ## Array of [`ComponentId`]s197///198/// ```199/// # use bevy_ecs::prelude::*;200/// #201/// # #[derive(Component, PartialEq, Debug)]202/// # pub struct X(i32);203/// # #[derive(Component, PartialEq, Debug)]204/// # pub struct Y(i32);205/// # let mut world = World::new();206/// let entity = world.spawn((X(42), Y(10))).id();207///208/// // Grab the component IDs for `X` and `Y` in whatever way you like.209/// let x_id = world.register_component::<X>();210/// let y_id = world.register_component::<Y>();211///212/// // Then, get the components by ID. You'll receive a same-sized array.213/// let Ok([x_ptr, y_ptr]) = world.entity(entity).get_by_id([x_id, y_id]) else {214/// // Up to you to handle if a component is missing from the entity.215/// # unreachable!();216/// };217/// # assert_eq!((unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() }), (&X(42), &Y(10)));218/// ```219///220/// ## Slice of [`ComponentId`]s221///222/// ```223/// # use bevy_ecs::{prelude::*, component::ComponentId};224/// #225/// # #[derive(Component, PartialEq, Debug)]226/// # pub struct X(i32);227/// # #[derive(Component, PartialEq, Debug)]228/// # pub struct Y(i32);229/// # let mut world = World::new();230/// let entity = world.spawn((X(42), Y(10))).id();231///232/// // Grab the component IDs for `X` and `Y` in whatever way you like.233/// let x_id = world.register_component::<X>();234/// let y_id = world.register_component::<Y>();235///236/// // Then, get the components by ID. You'll receive a vec of ptrs.237/// let ptrs = world.entity(entity).get_by_id(&[x_id, y_id] as &[ComponentId]);238/// # let ptrs = ptrs.unwrap();239/// # assert_eq!((unsafe { ptrs[0].deref::<X>() }, unsafe { ptrs[1].deref::<Y>() }), (&X(42), &Y(10)));240/// ```241///242/// ## [`HashSet`] of [`ComponentId`]s243///244/// ```245/// # use bevy_platform::collections::HashSet;246/// # use bevy_ecs::{prelude::*, component::ComponentId};247/// #248/// # #[derive(Component, PartialEq, Debug)]249/// # pub struct X(i32);250/// # #[derive(Component, PartialEq, Debug)]251/// # pub struct Y(i32);252/// # let mut world = World::new();253/// let entity = world.spawn((X(42), Y(10))).id();254///255/// // Grab the component IDs for `X` and `Y` in whatever way you like.256/// let x_id = world.register_component::<X>();257/// let y_id = world.register_component::<Y>();258///259/// // Then, get the components by ID. You'll receive a vec of ptrs.260/// let ptrs = world.entity(entity).get_by_id(&HashSet::from_iter([x_id, y_id]));261/// # let ptrs = ptrs.unwrap();262/// # assert_eq!((unsafe { ptrs[&x_id].deref::<X>() }, unsafe { ptrs[&y_id].deref::<Y>() }), (&X(42), &Y(10)));263/// ```264#[inline]265pub fn get_by_id<F: DynamicComponentFetch>(266&self,267component_ids: F,268) -> Result<F::Ref<'w>, EntityComponentError> {269// SAFETY: We have read-only access to all components of this entity.270unsafe { component_ids.fetch_ref(self.cell) }271}272273/// Returns read-only components for the current entity that match the query `Q`.274///275/// # Panics276///277/// If the entity does not have the components required by the query `Q`.278pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'w, 'static> {279self.get_components::<Q>()280.expect("Query does not match the current entity")281}282283/// Returns read-only components for the current entity that match the query `Q`,284/// or `None` if the entity does not have the components required by the query `Q`.285pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(286&self,287) -> Option<Q::Item<'w, 'static>> {288// SAFETY:289// - We have read-only access to all components of this entity.290// - The query is read-only, and read-only references cannot have conflicts.291unsafe { self.cell.get_components::<Q>() }292}293294/// Returns the source code location from which this entity has been spawned.295pub fn spawned_by(&self) -> MaybeLocation {296self.cell.spawned_by()297}298299/// Returns the [`Tick`] at which this entity has been spawned.300pub fn spawn_tick(&self) -> Tick {301self.cell.spawn_tick()302}303}304305impl<'w> From<EntityWorldMut<'w>> for EntityRef<'w> {306fn from(entity: EntityWorldMut<'w>) -> EntityRef<'w> {307// SAFETY:308// - `EntityWorldMut` guarantees exclusive access to the entire world.309unsafe { EntityRef::new(entity.into_unsafe_entity_cell()) }310}311}312313impl<'a> From<&'a EntityWorldMut<'_>> for EntityRef<'a> {314fn from(entity: &'a EntityWorldMut<'_>) -> Self {315// SAFETY:316// - `EntityWorldMut` guarantees exclusive access to the entire world.317// - `&entity` ensures no mutable accesses are active.318unsafe { EntityRef::new(entity.as_unsafe_entity_cell_readonly()) }319}320}321322impl<'w> From<EntityMut<'w>> for EntityRef<'w> {323fn from(entity: EntityMut<'w>) -> Self {324// SAFETY:325// - `EntityMut` guarantees exclusive access to all of the entity's components.326unsafe { EntityRef::new(entity.cell) }327}328}329330impl<'a> From<&'a EntityMut<'_>> for EntityRef<'a> {331fn from(entity: &'a EntityMut<'_>) -> Self {332// SAFETY:333// - `EntityMut` guarantees exclusive access to all of the entity's components.334// - `&entity` ensures there are no mutable accesses.335unsafe { EntityRef::new(entity.cell) }336}337}338339impl<'a> TryFrom<FilteredEntityRef<'a, '_>> for EntityRef<'a> {340type Error = TryFromFilteredError;341342fn try_from(entity: FilteredEntityRef<'a, '_>) -> Result<Self, Self::Error> {343if !entity.access.has_read_all() {344Err(TryFromFilteredError::MissingReadAllAccess)345} else {346// SAFETY: check above guarantees read-only access to all components of the entity.347Ok(unsafe { EntityRef::new(entity.entity) })348}349}350}351352impl<'a> TryFrom<&'a FilteredEntityRef<'_, '_>> for EntityRef<'a> {353type Error = TryFromFilteredError;354355fn try_from(entity: &'a FilteredEntityRef<'_, '_>) -> Result<Self, Self::Error> {356if !entity.access.has_read_all() {357Err(TryFromFilteredError::MissingReadAllAccess)358} else {359// SAFETY: check above guarantees read-only access to all components of the entity.360Ok(unsafe { EntityRef::new(entity.entity) })361}362}363}364365impl<'a> TryFrom<FilteredEntityMut<'a, '_>> for EntityRef<'a> {366type Error = TryFromFilteredError;367368fn try_from(entity: FilteredEntityMut<'a, '_>) -> Result<Self, Self::Error> {369if !entity.access.has_read_all() {370Err(TryFromFilteredError::MissingReadAllAccess)371} else {372// SAFETY: check above guarantees read-only access to all components of the entity.373Ok(unsafe { EntityRef::new(entity.entity) })374}375}376}377378impl<'a> TryFrom<&'a FilteredEntityMut<'_, '_>> for EntityRef<'a> {379type Error = TryFromFilteredError;380381fn try_from(entity: &'a FilteredEntityMut<'_, '_>) -> Result<Self, Self::Error> {382if !entity.access.has_read_all() {383Err(TryFromFilteredError::MissingReadAllAccess)384} else {385// SAFETY: check above guarantees read-only access to all components of the entity.386Ok(unsafe { EntityRef::new(entity.entity) })387}388}389}390391impl PartialEq for EntityRef<'_> {392fn eq(&self, other: &Self) -> bool {393self.entity() == other.entity()394}395}396397impl Eq for EntityRef<'_> {}398399impl PartialOrd for EntityRef<'_> {400/// [`EntityRef`]'s comparison trait implementations match the underlying [`Entity`],401/// and cannot discern between different worlds.402fn partial_cmp(&self, other: &Self) -> Option<Ordering> {403Some(self.cmp(other))404}405}406407impl Ord for EntityRef<'_> {408fn cmp(&self, other: &Self) -> Ordering {409self.entity().cmp(&other.entity())410}411}412413impl Hash for EntityRef<'_> {414fn hash<H: Hasher>(&self, state: &mut H) {415self.entity().hash(state);416}417}418419impl ContainsEntity for EntityRef<'_> {420fn entity(&self) -> Entity {421self.id()422}423}424425// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.426unsafe impl EntityEquivalent for EntityRef<'_> {}427428/// Provides mutable access to a single entity and all of its components.429///430/// Contrast with [`EntityWorldMut`], which allows adding and removing components,431/// despawning the entity, and provides mutable access to the entire world.432/// Because of this, `EntityWorldMut` cannot coexist with any other world accesses.433///434/// # Examples435///436/// Disjoint mutable access.437///438/// ```439/// # use bevy_ecs::prelude::*;440/// # #[derive(Component)] pub struct A;441/// fn disjoint_system(442/// query1: Query<EntityMut, With<A>>,443/// query2: Query<EntityMut, Without<A>>,444/// ) {445/// // ...446/// }447/// # bevy_ecs::system::assert_is_system(disjoint_system);448/// ```449pub struct EntityMut<'w> {450cell: UnsafeEntityCell<'w>,451}452453impl<'w> EntityMut<'w> {454/// # Safety455/// - `cell` must have permission to mutate every component of the entity.456/// - No accesses to any of the entity's components may exist457/// at the same time as the returned [`EntityMut`].458#[inline]459pub(crate) unsafe fn new(cell: UnsafeEntityCell<'w>) -> Self {460Self { cell }461}462463/// Returns a new instance with a shorter lifetime.464/// This is useful if you have `&mut EntityMut`, but you need `EntityMut`.465pub fn reborrow(&mut self) -> EntityMut<'_> {466// SAFETY: We have exclusive access to the entire entity and its components.467unsafe { Self::new(self.cell) }468}469470/// Consumes `self` and returns read-only access to all of the entity's471/// components, with the world `'w` lifetime.472pub fn into_readonly(self) -> EntityRef<'w> {473EntityRef::from(self)474}475476/// Gets read-only access to all of the entity's components.477pub fn as_readonly(&self) -> EntityRef<'_> {478EntityRef::from(self)479}480481/// Returns the [ID](Entity) of the current entity.482#[inline]483#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]484pub fn id(&self) -> Entity {485self.cell.id()486}487488/// Gets metadata indicating the location where the current entity is stored.489#[inline]490pub fn location(&self) -> EntityLocation {491self.cell.location()492}493494/// Returns the archetype that the current entity belongs to.495#[inline]496pub fn archetype(&self) -> &Archetype {497self.cell.archetype()498}499500/// Returns `true` if the current entity has a component of type `T`.501/// Otherwise, this returns `false`.502///503/// ## Notes504///505/// If you do not know the concrete type of a component, consider using506/// [`Self::contains_id`] or [`Self::contains_type_id`].507#[inline]508pub fn contains<T: Component>(&self) -> bool {509self.contains_type_id(TypeId::of::<T>())510}511512/// Returns `true` if the current entity has a component identified by `component_id`.513/// Otherwise, this returns false.514///515/// ## Notes516///517/// - If you know the concrete type of the component, you should prefer [`Self::contains`].518/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using519/// [`Self::contains_type_id`].520#[inline]521pub fn contains_id(&self, component_id: ComponentId) -> bool {522self.cell.contains_id(component_id)523}524525/// Returns `true` if the current entity has a component with the type identified by `type_id`.526/// Otherwise, this returns false.527///528/// ## Notes529///530/// - If you know the concrete type of the component, you should prefer [`Self::contains`].531/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].532#[inline]533pub fn contains_type_id(&self, type_id: TypeId) -> bool {534self.cell.contains_type_id(type_id)535}536537/// Gets access to the component of type `T` for the current entity.538/// Returns `None` if the entity does not have a component of type `T`.539#[inline]540pub fn get<T: Component>(&self) -> Option<&'_ T> {541self.as_readonly().get()542}543544/// Returns read-only components for the current entity that match the query `Q`.545///546/// # Panics547///548/// If the entity does not have the components required by the query `Q`.549pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'_, 'static> {550self.as_readonly().components::<Q>()551}552553/// Returns read-only components for the current entity that match the query `Q`,554/// or `None` if the entity does not have the components required by the query `Q`.555pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(556&self,557) -> Option<Q::Item<'_, 'static>> {558self.as_readonly().get_components::<Q>()559}560561/// Returns components for the current entity that match the query `Q`,562/// or `None` if the entity does not have the components required by the query `Q`.563///564/// # Example565///566/// ```567/// # use bevy_ecs::prelude::*;568/// #569/// #[derive(Component)]570/// struct X(usize);571/// #[derive(Component)]572/// struct Y(usize);573///574/// # let mut world = World::default();575/// let mut entity = world.spawn((X(0), Y(0))).into_mutable();576/// // Get mutable access to two components at once577/// // SAFETY: X and Y are different components578/// let (mut x, mut y) =579/// unsafe { entity.get_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();580/// *x = X(1);581/// *y = Y(1);582/// // This would trigger undefined behavior, as the `&mut X`s would alias:583/// // entity.get_components_mut_unchecked::<(&mut X, &mut X)>();584/// ```585///586/// # Safety587/// It is the caller's responsibility to ensure that588/// the `QueryData` does not provide aliasing mutable references to the same component.589pub unsafe fn get_components_mut_unchecked<Q: ReleaseStateQueryData>(590&mut self,591) -> Option<Q::Item<'_, 'static>> {592// SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component593unsafe { self.reborrow().into_components_mut_unchecked::<Q>() }594}595596/// Consumes self and returns components for the current entity that match the query `Q` for the world lifetime `'w`,597/// or `None` if the entity does not have the components required by the query `Q`.598///599/// # Example600///601/// ```602/// # use bevy_ecs::prelude::*;603/// #604/// #[derive(Component)]605/// struct X(usize);606/// #[derive(Component)]607/// struct Y(usize);608///609/// # let mut world = World::default();610/// let mut entity = world.spawn((X(0), Y(0))).into_mutable();611/// // Get mutable access to two components at once612/// // SAFETY: X and Y are different components613/// let (mut x, mut y) =614/// unsafe { entity.into_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();615/// *x = X(1);616/// *y = Y(1);617/// // This would trigger undefined behavior, as the `&mut X`s would alias:618/// // entity.into_components_mut_unchecked::<(&mut X, &mut X)>();619/// ```620///621/// # Safety622/// It is the caller's responsibility to ensure that623/// the `QueryData` does not provide aliasing mutable references to the same component.624pub unsafe fn into_components_mut_unchecked<Q: ReleaseStateQueryData>(625self,626) -> Option<Q::Item<'w, 'static>> {627// SAFETY:628// - We have mutable access to all components of this entity.629// - Caller asserts the `QueryData` does not provide aliasing mutable references to the same component630unsafe { self.cell.get_components::<Q>() }631}632633/// Consumes `self` and gets access to the component of type `T` with the634/// world `'w` lifetime for the current entity.635///636/// Returns `None` if the entity does not have a component of type `T`.637#[inline]638pub fn into_borrow<T: Component>(self) -> Option<&'w T> {639self.into_readonly().get()640}641642/// Gets access to the component of type `T` for the current entity,643/// including change detection information as a [`Ref`].644///645/// Returns `None` if the entity does not have a component of type `T`.646#[inline]647pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {648self.as_readonly().get_ref()649}650651/// Consumes `self` and gets access to the component of type `T` with world652/// `'w` lifetime for the current entity, including change detection information653/// as a [`Ref<'w>`].654///655/// Returns `None` if the entity does not have a component of type `T`.656#[inline]657pub fn into_ref<T: Component>(self) -> Option<Ref<'w, T>> {658self.into_readonly().get_ref()659}660661/// Gets mutable access to the component of type `T` for the current entity.662/// Returns `None` if the entity does not have a component of type `T`.663#[inline]664pub fn get_mut<T: Component<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {665// SAFETY: &mut self implies exclusive access for duration of returned value666unsafe { self.cell.get_mut() }667}668669/// Gets mutable access to the component of type `T` for the current entity.670/// Returns `None` if the entity does not have a component of type `T`.671///672/// # Safety673///674/// - `T` must be a mutable component675#[inline]676pub unsafe fn get_mut_assume_mutable<T: Component>(&mut self) -> Option<Mut<'_, T>> {677// SAFETY:678// - &mut self implies exclusive access for duration of returned value679// - Caller ensures `T` is a mutable component680unsafe { self.cell.get_mut_assume_mutable() }681}682683/// Consumes self and gets mutable access to the component of type `T`684/// with the world `'w` lifetime for the current entity.685/// Returns `None` if the entity does not have a component of type `T`.686#[inline]687pub fn into_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {688// SAFETY: consuming `self` implies exclusive access689unsafe { self.cell.get_mut() }690}691692/// Gets mutable access to the component of type `T` for the current entity.693/// Returns `None` if the entity does not have a component of type `T`.694///695/// # Safety696///697/// - `T` must be a mutable component698#[inline]699pub unsafe fn into_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {700// SAFETY:701// - Consuming `self` implies exclusive access702// - Caller ensures `T` is a mutable component703unsafe { self.cell.get_mut_assume_mutable() }704}705706/// Retrieves the change ticks for the given component. This can be useful for implementing change707/// detection in custom runtimes.708#[inline]709pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {710self.as_readonly().get_change_ticks::<T>()711}712713/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change714/// detection in custom runtimes.715///716/// **You should prefer to use the typed API [`EntityWorldMut::get_change_ticks`] where possible and only717/// use this in cases where the actual component types are not known at718/// compile time.**719#[inline]720pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {721self.as_readonly().get_change_ticks_by_id(component_id)722}723724/// Returns [untyped read-only reference(s)](Ptr) to component(s) for the725/// current entity, based on the given [`ComponentId`]s.726///727/// **You should prefer to use the typed API [`EntityMut::get`] where728/// possible and only use this in cases where the actual component types729/// are not known at compile time.**730///731/// Unlike [`EntityMut::get`], this returns untyped reference(s) to732/// component(s), and it's the job of the caller to ensure the correct733/// type(s) are dereferenced (if necessary).734///735/// # Errors736///737/// Returns [`EntityComponentError::MissingComponent`] if the entity does738/// not have a component.739///740/// # Examples741///742/// For examples on how to use this method, see [`EntityRef::get_by_id`].743#[inline]744pub fn get_by_id<F: DynamicComponentFetch>(745&self,746component_ids: F,747) -> Result<F::Ref<'_>, EntityComponentError> {748self.as_readonly().get_by_id(component_ids)749}750751/// Consumes `self` and returns [untyped read-only reference(s)](Ptr) to752/// component(s) with lifetime `'w` for the current entity, based on the753/// given [`ComponentId`]s.754///755/// **You should prefer to use the typed API [`EntityMut::into_borrow`]756/// where possible and only use this in cases where the actual component757/// types are not known at compile time.**758///759/// Unlike [`EntityMut::into_borrow`], this returns untyped reference(s) to760/// component(s), and it's the job of the caller to ensure the correct761/// type(s) are dereferenced (if necessary).762///763/// # Errors764///765/// Returns [`EntityComponentError::MissingComponent`] if the entity does766/// not have a component.767///768/// # Examples769///770/// For examples on how to use this method, see [`EntityRef::get_by_id`].771#[inline]772pub fn into_borrow_by_id<F: DynamicComponentFetch>(773self,774component_ids: F,775) -> Result<F::Ref<'w>, EntityComponentError> {776self.into_readonly().get_by_id(component_ids)777}778779/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for780/// the current entity, based on the given [`ComponentId`]s.781///782/// **You should prefer to use the typed API [`EntityMut::get_mut`] where783/// possible and only use this in cases where the actual component types784/// are not known at compile time.**785///786/// Unlike [`EntityMut::get_mut`], this returns untyped reference(s) to787/// component(s), and it's the job of the caller to ensure the correct788/// type(s) are dereferenced (if necessary).789///790/// # Errors791///792/// - Returns [`EntityComponentError::MissingComponent`] if the entity does793/// not have a component.794/// - Returns [`EntityComponentError::AliasedMutability`] if a component795/// is requested multiple times.796///797/// # Examples798///799/// ## Single [`ComponentId`]800///801/// ```802/// # use bevy_ecs::prelude::*;803/// #804/// # #[derive(Component, PartialEq, Debug)]805/// # pub struct Foo(i32);806/// # let mut world = World::new();807/// let entity = world.spawn(Foo(42)).id();808///809/// // Grab the component ID for `Foo` in whatever way you like.810/// let component_id = world.register_component::<Foo>();811///812/// // Then, get the component by ID.813/// let mut entity_mut = world.entity_mut(entity);814/// let mut ptr = entity_mut.get_mut_by_id(component_id)815/// # .unwrap();816/// # assert_eq!(unsafe { ptr.as_mut().deref_mut::<Foo>() }, &mut Foo(42));817/// ```818///819/// ## Array of [`ComponentId`]s820///821/// ```822/// # use bevy_ecs::prelude::*;823/// #824/// # #[derive(Component, PartialEq, Debug)]825/// # pub struct X(i32);826/// # #[derive(Component, PartialEq, Debug)]827/// # pub struct Y(i32);828/// # let mut world = World::new();829/// let entity = world.spawn((X(42), Y(10))).id();830///831/// // Grab the component IDs for `X` and `Y` in whatever way you like.832/// let x_id = world.register_component::<X>();833/// let y_id = world.register_component::<Y>();834///835/// // Then, get the components by ID. You'll receive a same-sized array.836/// let mut entity_mut = world.entity_mut(entity);837/// let Ok([mut x_ptr, mut y_ptr]) = entity_mut.get_mut_by_id([x_id, y_id]) else {838/// // Up to you to handle if a component is missing from the entity.839/// # unreachable!();840/// };841/// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));842/// ```843///844/// ## Slice of [`ComponentId`]s845///846/// ```847/// # use bevy_ecs::{prelude::*, component::ComponentId, change_detection::MutUntyped};848/// #849/// # #[derive(Component, PartialEq, Debug)]850/// # pub struct X(i32);851/// # #[derive(Component, PartialEq, Debug)]852/// # pub struct Y(i32);853/// # let mut world = World::new();854/// let entity = world.spawn((X(42), Y(10))).id();855///856/// // Grab the component IDs for `X` and `Y` in whatever way you like.857/// let x_id = world.register_component::<X>();858/// let y_id = world.register_component::<Y>();859///860/// // Then, get the components by ID. You'll receive a vec of ptrs.861/// let mut entity_mut = world.entity_mut(entity);862/// let ptrs = entity_mut.get_mut_by_id(&[x_id, y_id] as &[ComponentId])863/// # .unwrap();864/// # let [mut x_ptr, mut y_ptr]: [MutUntyped; 2] = ptrs.try_into().unwrap();865/// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));866/// ```867///868/// ## [`HashSet`] of [`ComponentId`]s869///870/// ```871/// # use bevy_platform::collections::HashSet;872/// # use bevy_ecs::{prelude::*, component::ComponentId};873/// #874/// # #[derive(Component, PartialEq, Debug)]875/// # pub struct X(i32);876/// # #[derive(Component, PartialEq, Debug)]877/// # pub struct Y(i32);878/// # let mut world = World::new();879/// let entity = world.spawn((X(42), Y(10))).id();880///881/// // Grab the component IDs for `X` and `Y` in whatever way you like.882/// let x_id = world.register_component::<X>();883/// let y_id = world.register_component::<Y>();884///885/// // Then, get the components by ID. You'll receive a `HashMap` of ptrs.886/// let mut entity_mut = world.entity_mut(entity);887/// let mut ptrs = entity_mut.get_mut_by_id(&HashSet::from_iter([x_id, y_id]))888/// # .unwrap();889/// # let [Some(mut x_ptr), Some(mut y_ptr)] = ptrs.get_many_mut([&x_id, &y_id]) else { unreachable!() };890/// # assert_eq!((unsafe { x_ptr.as_mut().deref_mut::<X>() }, unsafe { y_ptr.as_mut().deref_mut::<Y>() }), (&mut X(42), &mut Y(10)));891/// ```892#[inline]893pub fn get_mut_by_id<F: DynamicComponentFetch>(894&mut self,895component_ids: F,896) -> Result<F::Mut<'_>, EntityComponentError> {897// SAFETY:898// - `&mut self` ensures that no references exist to this entity's components.899// - We have exclusive access to all components of this entity.900unsafe { component_ids.fetch_mut(self.cell) }901}902903/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for904/// the current entity, based on the given [`ComponentId`]s.905/// Assumes the given [`ComponentId`]s refer to mutable components.906///907/// **You should prefer to use the typed API [`EntityMut::get_mut_assume_mutable`] where908/// possible and only use this in cases where the actual component types909/// are not known at compile time.**910///911/// Unlike [`EntityMut::get_mut_assume_mutable`], this returns untyped reference(s) to912/// component(s), and it's the job of the caller to ensure the correct913/// type(s) are dereferenced (if necessary).914///915/// # Errors916///917/// - Returns [`EntityComponentError::MissingComponent`] if the entity does918/// not have a component.919/// - Returns [`EntityComponentError::AliasedMutability`] if a component920/// is requested multiple times.921///922/// # Safety923/// It is the callers responsibility to ensure that924/// - the provided [`ComponentId`]s must refer to mutable components.925#[inline]926pub unsafe fn get_mut_assume_mutable_by_id<F: DynamicComponentFetch>(927&mut self,928component_ids: F,929) -> Result<F::Mut<'_>, EntityComponentError> {930// SAFETY:931// - `&mut self` ensures that no references exist to this entity's components.932// - We have exclusive access to all components of this entity.933unsafe { component_ids.fetch_mut_assume_mutable(self.cell) }934}935936/// Returns [untyped mutable reference](MutUntyped) to component for937/// the current entity, based on the given [`ComponentId`].938///939/// Unlike [`EntityMut::get_mut_by_id`], this method borrows &self instead of940/// &mut self, allowing the caller to access multiple components simultaneously.941///942/// # Errors943///944/// - Returns [`EntityComponentError::MissingComponent`] if the entity does945/// not have a component.946/// - Returns [`EntityComponentError::AliasedMutability`] if a component947/// is requested multiple times.948///949/// # Safety950/// It is the callers responsibility to ensure that951/// - the [`UnsafeEntityCell`] has permission to access the component mutably952/// - no other references to the component exist at the same time953#[inline]954pub unsafe fn get_mut_by_id_unchecked<F: DynamicComponentFetch>(955&self,956component_ids: F,957) -> Result<F::Mut<'_>, EntityComponentError> {958// SAFETY:959// - The caller must ensure simultaneous access is limited960// - to components that are mutually independent.961unsafe { component_ids.fetch_mut(self.cell) }962}963964/// Returns [untyped mutable reference](MutUntyped) to component for965/// the current entity, based on the given [`ComponentId`].966/// Assumes the given [`ComponentId`]s refer to mutable components.967///968/// Unlike [`EntityMut::get_mut_assume_mutable_by_id`], this method borrows &self instead of969/// &mut self, allowing the caller to access multiple components simultaneously.970///971/// # Errors972///973/// - Returns [`EntityComponentError::MissingComponent`] if the entity does974/// not have a component.975/// - Returns [`EntityComponentError::AliasedMutability`] if a component976/// is requested multiple times.977///978/// # Safety979/// It is the callers responsibility to ensure that980/// - the [`UnsafeEntityCell`] has permission to access the component mutably981/// - no other references to the component exist at the same time982/// - the provided [`ComponentId`]s must refer to mutable components.983#[inline]984pub unsafe fn get_mut_assume_mutable_by_id_unchecked<F: DynamicComponentFetch>(985&self,986component_ids: F,987) -> Result<F::Mut<'_>, EntityComponentError> {988// SAFETY:989// - The caller must ensure simultaneous access is limited990// - to components that are mutually independent.991unsafe { component_ids.fetch_mut_assume_mutable(self.cell) }992}993994/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)995/// to component(s) with lifetime `'w` for the current entity, based on the996/// given [`ComponentId`]s.997///998/// **You should prefer to use the typed API [`EntityMut::into_mut`] where999/// possible and only use this in cases where the actual component types1000/// are not known at compile time.**1001///1002/// Unlike [`EntityMut::into_mut`], this returns untyped reference(s) to1003/// component(s), and it's the job of the caller to ensure the correct1004/// type(s) are dereferenced (if necessary).1005///1006/// # Errors1007///1008/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1009/// not have a component.1010/// - Returns [`EntityComponentError::AliasedMutability`] if a component1011/// is requested multiple times.1012///1013/// # Examples1014///1015/// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].1016#[inline]1017pub fn into_mut_by_id<F: DynamicComponentFetch>(1018self,1019component_ids: F,1020) -> Result<F::Mut<'w>, EntityComponentError> {1021// SAFETY:1022// - consuming `self` ensures that no references exist to this entity's components.1023// - We have exclusive access to all components of this entity.1024unsafe { component_ids.fetch_mut(self.cell) }1025}10261027/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)1028/// to component(s) with lifetime `'w` for the current entity, based on the1029/// given [`ComponentId`]s.1030/// Assumes the given [`ComponentId`]s refer to mutable components.1031///1032/// **You should prefer to use the typed API [`EntityMut::into_mut_assume_mutable`] where1033/// possible and only use this in cases where the actual component types1034/// are not known at compile time.**1035///1036/// Unlike [`EntityMut::into_mut_assume_mutable`], this returns untyped reference(s) to1037/// component(s), and it's the job of the caller to ensure the correct1038/// type(s) are dereferenced (if necessary).1039///1040/// # Errors1041///1042/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1043/// not have a component.1044/// - Returns [`EntityComponentError::AliasedMutability`] if a component1045/// is requested multiple times.1046///1047/// # Safety1048/// It is the callers responsibility to ensure that1049/// - the provided [`ComponentId`]s must refer to mutable components.1050#[inline]1051pub unsafe fn into_mut_assume_mutable_by_id<F: DynamicComponentFetch>(1052self,1053component_ids: F,1054) -> Result<F::Mut<'w>, EntityComponentError> {1055// SAFETY:1056// - consuming `self` ensures that no references exist to this entity's components.1057// - We have exclusive access to all components of this entity.1058unsafe { component_ids.fetch_mut_assume_mutable(self.cell) }1059}10601061/// Returns the source code location from which this entity has been spawned.1062pub fn spawned_by(&self) -> MaybeLocation {1063self.cell.spawned_by()1064}10651066/// Returns the [`Tick`] at which this entity has been spawned.1067pub fn spawn_tick(&self) -> Tick {1068self.cell.spawn_tick()1069}1070}10711072impl<'w> From<&'w mut EntityMut<'_>> for EntityMut<'w> {1073fn from(entity: &'w mut EntityMut<'_>) -> Self {1074entity.reborrow()1075}1076}10771078impl<'w> From<EntityWorldMut<'w>> for EntityMut<'w> {1079fn from(entity: EntityWorldMut<'w>) -> Self {1080// SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.1081unsafe { EntityMut::new(entity.into_unsafe_entity_cell()) }1082}1083}10841085impl<'a> From<&'a mut EntityWorldMut<'_>> for EntityMut<'a> {1086#[inline]1087fn from(entity: &'a mut EntityWorldMut<'_>) -> Self {1088// SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.1089unsafe { EntityMut::new(entity.as_unsafe_entity_cell()) }1090}1091}10921093impl<'a> TryFrom<FilteredEntityMut<'a, '_>> for EntityMut<'a> {1094type Error = TryFromFilteredError;10951096fn try_from(entity: FilteredEntityMut<'a, '_>) -> Result<Self, Self::Error> {1097if !entity.access.has_read_all() {1098Err(TryFromFilteredError::MissingReadAllAccess)1099} else if !entity.access.has_write_all() {1100Err(TryFromFilteredError::MissingWriteAllAccess)1101} else {1102// SAFETY: check above guarantees exclusive access to all components of the entity.1103Ok(unsafe { EntityMut::new(entity.entity) })1104}1105}1106}11071108impl<'a> TryFrom<&'a mut FilteredEntityMut<'_, '_>> for EntityMut<'a> {1109type Error = TryFromFilteredError;11101111fn try_from(entity: &'a mut FilteredEntityMut<'_, '_>) -> Result<Self, Self::Error> {1112if !entity.access.has_read_all() {1113Err(TryFromFilteredError::MissingReadAllAccess)1114} else if !entity.access.has_write_all() {1115Err(TryFromFilteredError::MissingWriteAllAccess)1116} else {1117// SAFETY: check above guarantees exclusive access to all components of the entity.1118Ok(unsafe { EntityMut::new(entity.entity) })1119}1120}1121}11221123impl PartialEq for EntityMut<'_> {1124fn eq(&self, other: &Self) -> bool {1125self.entity() == other.entity()1126}1127}11281129impl Eq for EntityMut<'_> {}11301131impl PartialOrd for EntityMut<'_> {1132/// [`EntityMut`]'s comparison trait implementations match the underlying [`Entity`],1133/// and cannot discern between different worlds.1134fn partial_cmp(&self, other: &Self) -> Option<Ordering> {1135Some(self.cmp(other))1136}1137}11381139impl Ord for EntityMut<'_> {1140fn cmp(&self, other: &Self) -> Ordering {1141self.entity().cmp(&other.entity())1142}1143}11441145impl Hash for EntityMut<'_> {1146fn hash<H: Hasher>(&self, state: &mut H) {1147self.entity().hash(state);1148}1149}11501151impl ContainsEntity for EntityMut<'_> {1152fn entity(&self) -> Entity {1153self.id()1154}1155}11561157// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.1158unsafe impl EntityEquivalent for EntityMut<'_> {}11591160/// A mutable reference to a particular [`Entity`], and the entire world.1161///1162/// This is essentially a performance-optimized `(Entity, &mut World)` tuple,1163/// which caches the [`EntityLocation`] to reduce duplicate lookups.1164///1165/// Since this type provides mutable access to the entire world, only one1166/// [`EntityWorldMut`] can exist at a time for a given world.1167///1168/// See also [`EntityMut`], which allows disjoint mutable access to multiple1169/// entities at once. Unlike `EntityMut`, this type allows adding and1170/// removing components, and despawning the entity.1171pub struct EntityWorldMut<'w> {1172world: &'w mut World,1173entity: Entity,1174location: EntityIdLocation,1175}11761177impl<'w> EntityWorldMut<'w> {1178#[track_caller]1179#[inline(never)]1180#[cold]1181fn panic_despawned(&self) -> ! {1182panic!(1183"Entity {} {}",1184self.entity,1185self.world1186.entities()1187.entity_does_not_exist_error_details(self.entity)1188);1189}11901191#[inline(always)]1192#[track_caller]1193pub(crate) fn assert_not_despawned(&self) {1194if self.location.is_none() {1195self.panic_despawned()1196}1197}11981199#[inline(always)]1200fn as_unsafe_entity_cell_readonly(&self) -> UnsafeEntityCell<'_> {1201let location = self.location();1202let last_change_tick = self.world.last_change_tick;1203let change_tick = self.world.read_change_tick();1204UnsafeEntityCell::new(1205self.world.as_unsafe_world_cell_readonly(),1206self.entity,1207location,1208last_change_tick,1209change_tick,1210)1211}12121213#[inline(always)]1214fn as_unsafe_entity_cell(&mut self) -> UnsafeEntityCell<'_> {1215let location = self.location();1216let last_change_tick = self.world.last_change_tick;1217let change_tick = self.world.change_tick();1218UnsafeEntityCell::new(1219self.world.as_unsafe_world_cell(),1220self.entity,1221location,1222last_change_tick,1223change_tick,1224)1225}12261227#[inline(always)]1228fn into_unsafe_entity_cell(self) -> UnsafeEntityCell<'w> {1229let location = self.location();1230let last_change_tick = self.world.last_change_tick;1231let change_tick = self.world.change_tick();1232UnsafeEntityCell::new(1233self.world.as_unsafe_world_cell(),1234self.entity,1235location,1236last_change_tick,1237change_tick,1238)1239}12401241/// # Safety1242///1243/// - `entity` must be valid for `world`: the generation should match that of the entity at the same index.1244/// - `location` must be sourced from `world`'s `Entities` and must exactly match the location for `entity`1245///1246/// The above is trivially satisfied if `location` was sourced from `world.entities().get(entity)`.1247#[inline]1248pub(crate) unsafe fn new(1249world: &'w mut World,1250entity: Entity,1251location: Option<EntityLocation>,1252) -> Self {1253debug_assert!(world.entities().contains(entity));1254debug_assert_eq!(world.entities().get(entity), location);12551256EntityWorldMut {1257world,1258entity,1259location,1260}1261}12621263/// Consumes `self` and returns read-only access to all of the entity's1264/// components, with the world `'w` lifetime.1265pub fn into_readonly(self) -> EntityRef<'w> {1266EntityRef::from(self)1267}12681269/// Gets read-only access to all of the entity's components.1270#[inline]1271pub fn as_readonly(&self) -> EntityRef<'_> {1272EntityRef::from(self)1273}12741275/// Consumes `self` and returns non-structural mutable access to all of the1276/// entity's components, with the world `'w` lifetime.1277pub fn into_mutable(self) -> EntityMut<'w> {1278EntityMut::from(self)1279}12801281/// Gets non-structural mutable access to all of the entity's components.1282#[inline]1283pub fn as_mutable(&mut self) -> EntityMut<'_> {1284EntityMut::from(self)1285}12861287/// Returns the [ID](Entity) of the current entity.1288#[inline]1289#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]1290pub fn id(&self) -> Entity {1291self.entity1292}12931294/// Gets metadata indicating the location where the current entity is stored.1295///1296/// # Panics1297///1298/// If the entity has been despawned while this `EntityWorldMut` is still alive.1299#[inline]1300pub fn location(&self) -> EntityLocation {1301match self.location {1302Some(loc) => loc,1303None => self.panic_despawned(),1304}1305}13061307/// Returns the archetype that the current entity belongs to.1308///1309/// # Panics1310///1311/// If the entity has been despawned while this `EntityWorldMut` is still alive.1312#[inline]1313pub fn archetype(&self) -> &Archetype {1314let location = self.location();1315&self.world.archetypes[location.archetype_id]1316}13171318/// Returns `true` if the current entity has a component of type `T`.1319/// Otherwise, this returns `false`.1320///1321/// ## Notes1322///1323/// If you do not know the concrete type of a component, consider using1324/// [`Self::contains_id`] or [`Self::contains_type_id`].1325///1326/// # Panics1327///1328/// If the entity has been despawned while this `EntityWorldMut` is still alive.1329#[inline]1330pub fn contains<T: Component>(&self) -> bool {1331self.contains_type_id(TypeId::of::<T>())1332}13331334/// Returns `true` if the current entity has a component identified by `component_id`.1335/// Otherwise, this returns false.1336///1337/// ## Notes1338///1339/// - If you know the concrete type of the component, you should prefer [`Self::contains`].1340/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using1341/// [`Self::contains_type_id`].1342///1343/// # Panics1344///1345/// If the entity has been despawned while this `EntityWorldMut` is still alive.1346#[inline]1347pub fn contains_id(&self, component_id: ComponentId) -> bool {1348self.as_unsafe_entity_cell_readonly()1349.contains_id(component_id)1350}13511352/// Returns `true` if the current entity has a component with the type identified by `type_id`.1353/// Otherwise, this returns false.1354///1355/// ## Notes1356///1357/// - If you know the concrete type of the component, you should prefer [`Self::contains`].1358/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].1359///1360/// # Panics1361///1362/// If the entity has been despawned while this `EntityWorldMut` is still alive.1363#[inline]1364pub fn contains_type_id(&self, type_id: TypeId) -> bool {1365self.as_unsafe_entity_cell_readonly()1366.contains_type_id(type_id)1367}13681369/// Gets access to the component of type `T` for the current entity.1370/// Returns `None` if the entity does not have a component of type `T`.1371///1372/// # Panics1373///1374/// If the entity has been despawned while this `EntityWorldMut` is still alive.1375#[inline]1376pub fn get<T: Component>(&self) -> Option<&'_ T> {1377self.as_readonly().get()1378}13791380/// Returns read-only components for the current entity that match the query `Q`.1381///1382/// # Panics1383///1384/// If the entity does not have the components required by the query `Q` or if the entity1385/// has been despawned while this `EntityWorldMut` is still alive.1386#[inline]1387pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'_, 'static> {1388self.as_readonly().components::<Q>()1389}13901391/// Returns read-only components for the current entity that match the query `Q`,1392/// or `None` if the entity does not have the components required by the query `Q`.1393///1394/// # Panics1395///1396/// If the entity has been despawned while this `EntityWorldMut` is still alive.1397#[inline]1398pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(1399&self,1400) -> Option<Q::Item<'_, 'static>> {1401self.as_readonly().get_components::<Q>()1402}14031404/// Returns components for the current entity that match the query `Q`,1405/// or `None` if the entity does not have the components required by the query `Q`.1406///1407/// # Example1408///1409/// ```1410/// # use bevy_ecs::prelude::*;1411/// #1412/// #[derive(Component)]1413/// struct X(usize);1414/// #[derive(Component)]1415/// struct Y(usize);1416///1417/// # let mut world = World::default();1418/// let mut entity = world.spawn((X(0), Y(0)));1419/// // Get mutable access to two components at once1420/// // SAFETY: X and Y are different components1421/// let (mut x, mut y) =1422/// unsafe { entity.get_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();1423/// *x = X(1);1424/// *y = Y(1);1425/// // This would trigger undefined behavior, as the `&mut X`s would alias:1426/// // entity.get_components_mut_unchecked::<(&mut X, &mut X)>();1427/// ```1428///1429/// # Safety1430/// It is the caller's responsibility to ensure that1431/// the `QueryData` does not provide aliasing mutable references to the same component.1432pub unsafe fn get_components_mut_unchecked<Q: ReleaseStateQueryData>(1433&mut self,1434) -> Option<Q::Item<'_, 'static>> {1435// SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component1436unsafe { self.as_mutable().into_components_mut_unchecked::<Q>() }1437}14381439/// Consumes self and returns components for the current entity that match the query `Q` for the world lifetime `'w`,1440/// or `None` if the entity does not have the components required by the query `Q`.1441///1442/// # Example1443///1444/// ```1445/// # use bevy_ecs::prelude::*;1446/// #1447/// #[derive(Component)]1448/// struct X(usize);1449/// #[derive(Component)]1450/// struct Y(usize);1451///1452/// # let mut world = World::default();1453/// let mut entity = world.spawn((X(0), Y(0)));1454/// // Get mutable access to two components at once1455/// // SAFETY: X and Y are different components1456/// let (mut x, mut y) =1457/// unsafe { entity.into_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();1458/// *x = X(1);1459/// *y = Y(1);1460/// // This would trigger undefined behavior, as the `&mut X`s would alias:1461/// // entity.into_components_mut_unchecked::<(&mut X, &mut X)>();1462/// ```1463///1464/// # Safety1465/// It is the caller's responsibility to ensure that1466/// the `QueryData` does not provide aliasing mutable references to the same component.1467pub unsafe fn into_components_mut_unchecked<Q: ReleaseStateQueryData>(1468self,1469) -> Option<Q::Item<'w, 'static>> {1470// SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component1471unsafe { self.into_mutable().into_components_mut_unchecked::<Q>() }1472}14731474/// Consumes `self` and gets access to the component of type `T` with1475/// the world `'w` lifetime for the current entity.1476/// Returns `None` if the entity does not have a component of type `T`.1477///1478/// # Panics1479///1480/// If the entity has been despawned while this `EntityWorldMut` is still alive.1481#[inline]1482pub fn into_borrow<T: Component>(self) -> Option<&'w T> {1483self.into_readonly().get()1484}14851486/// Gets access to the component of type `T` for the current entity,1487/// including change detection information as a [`Ref`].1488///1489/// Returns `None` if the entity does not have a component of type `T`.1490///1491/// # Panics1492///1493/// If the entity has been despawned while this `EntityWorldMut` is still alive.1494#[inline]1495pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {1496self.as_readonly().get_ref()1497}14981499/// Consumes `self` and gets access to the component of type `T`1500/// with the world `'w` lifetime for the current entity,1501/// including change detection information as a [`Ref`].1502///1503/// Returns `None` if the entity does not have a component of type `T`.1504///1505/// # Panics1506///1507/// If the entity has been despawned while this `EntityWorldMut` is still alive.1508#[inline]1509pub fn into_ref<T: Component>(self) -> Option<Ref<'w, T>> {1510self.into_readonly().get_ref()1511}15121513/// Gets mutable access to the component of type `T` for the current entity.1514/// Returns `None` if the entity does not have a component of type `T`.1515///1516/// # Panics1517///1518/// If the entity has been despawned while this `EntityWorldMut` is still alive.1519#[inline]1520pub fn get_mut<T: Component<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {1521self.as_mutable().into_mut()1522}15231524/// Temporarily removes a [`Component`] `T` from this [`Entity`] and runs the1525/// provided closure on it, returning the result if `T` was available.1526/// This will trigger the `Remove` and `Replace` component hooks without1527/// causing an archetype move.1528///1529/// This is most useful with immutable components, where removal and reinsertion1530/// is the only way to modify a value.1531///1532/// If you do not need to ensure the above hooks are triggered, and your component1533/// is mutable, prefer using [`get_mut`](EntityWorldMut::get_mut).1534///1535/// # Examples1536///1537/// ```rust1538/// # use bevy_ecs::prelude::*;1539/// #1540/// #[derive(Component, PartialEq, Eq, Debug)]1541/// #[component(immutable)]1542/// struct Foo(bool);1543///1544/// # let mut world = World::default();1545/// # world.register_component::<Foo>();1546/// #1547/// # let entity = world.spawn(Foo(false)).id();1548/// #1549/// # let mut entity = world.entity_mut(entity);1550/// #1551/// # assert_eq!(entity.get::<Foo>(), Some(&Foo(false)));1552/// #1553/// entity.modify_component(|foo: &mut Foo| {1554/// foo.0 = true;1555/// });1556/// #1557/// # assert_eq!(entity.get::<Foo>(), Some(&Foo(true)));1558/// ```1559///1560/// # Panics1561///1562/// If the entity has been despawned while this `EntityWorldMut` is still alive.1563#[inline]1564pub fn modify_component<T: Component, R>(&mut self, f: impl FnOnce(&mut T) -> R) -> Option<R> {1565self.assert_not_despawned();15661567let result = self1568.world1569.modify_component(self.entity, f)1570.expect("entity access must be valid")?;15711572self.update_location();15731574Some(result)1575}15761577/// Temporarily removes a [`Component`] `T` from this [`Entity`] and runs the1578/// provided closure on it, returning the result if `T` was available.1579/// This will trigger the `Remove` and `Replace` component hooks without1580/// causing an archetype move.1581///1582/// This is most useful with immutable components, where removal and reinsertion1583/// is the only way to modify a value.1584///1585/// If you do not need to ensure the above hooks are triggered, and your component1586/// is mutable, prefer using [`get_mut`](EntityWorldMut::get_mut).1587///1588/// # Panics1589///1590/// If the entity has been despawned while this `EntityWorldMut` is still alive.1591#[inline]1592pub fn modify_component_by_id<R>(1593&mut self,1594component_id: ComponentId,1595f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,1596) -> Option<R> {1597self.assert_not_despawned();15981599let result = self1600.world1601.modify_component_by_id(self.entity, component_id, f)1602.expect("entity access must be valid")?;16031604self.update_location();16051606Some(result)1607}16081609/// Gets mutable access to the component of type `T` for the current entity.1610/// Returns `None` if the entity does not have a component of type `T`.1611///1612/// # Safety1613///1614/// - `T` must be a mutable component1615#[inline]1616pub unsafe fn get_mut_assume_mutable<T: Component>(&mut self) -> Option<Mut<'_, T>> {1617self.as_mutable().into_mut_assume_mutable()1618}16191620/// Consumes `self` and gets mutable access to the component of type `T`1621/// with the world `'w` lifetime for the current entity.1622/// Returns `None` if the entity does not have a component of type `T`.1623///1624/// # Panics1625///1626/// If the entity has been despawned while this `EntityWorldMut` is still alive.1627#[inline]1628pub fn into_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {1629// SAFETY: consuming `self` implies exclusive access1630unsafe { self.into_unsafe_entity_cell().get_mut() }1631}16321633/// Consumes `self` and gets mutable access to the component of type `T`1634/// with the world `'w` lifetime for the current entity.1635/// Returns `None` if the entity does not have a component of type `T`.1636///1637/// # Panics1638///1639/// If the entity has been despawned while this `EntityWorldMut` is still alive.1640///1641/// # Safety1642///1643/// - `T` must be a mutable component1644#[inline]1645pub unsafe fn into_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {1646// SAFETY: consuming `self` implies exclusive access1647unsafe { self.into_unsafe_entity_cell().get_mut_assume_mutable() }1648}16491650/// Gets a reference to the resource of the given type1651///1652/// # Panics1653///1654/// Panics if the resource does not exist.1655/// Use [`get_resource`](EntityWorldMut::get_resource) instead if you want to handle this case.1656#[inline]1657#[track_caller]1658pub fn resource<R: Resource>(&self) -> &R {1659self.world.resource::<R>()1660}16611662/// Gets a mutable reference to the resource of the given type1663///1664/// # Panics1665///1666/// Panics if the resource does not exist.1667/// Use [`get_resource_mut`](World::get_resource_mut) instead if you want to handle this case.1668///1669/// If you want to instead insert a value if the resource does not exist,1670/// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).1671#[inline]1672#[track_caller]1673pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {1674self.world.resource_mut::<R>()1675}16761677/// Gets a reference to the resource of the given type if it exists1678#[inline]1679pub fn get_resource<R: Resource>(&self) -> Option<&R> {1680self.world.get_resource()1681}16821683/// Gets a mutable reference to the resource of the given type if it exists1684#[inline]1685pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {1686self.world.get_resource_mut()1687}16881689/// Temporarily removes the requested resource from the [`World`], runs custom user code,1690/// then re-adds the resource before returning.1691///1692/// # Panics1693///1694/// Panics if the resource does not exist.1695/// Use [`try_resource_scope`](Self::try_resource_scope) instead if you want to handle this case.1696///1697/// See [`World::resource_scope`] for further details.1698#[track_caller]1699pub fn resource_scope<R: Resource, U>(1700&mut self,1701f: impl FnOnce(&mut EntityWorldMut, Mut<R>) -> U,1702) -> U {1703let id = self.id();1704self.world_scope(|world| {1705world.resource_scope(|world, res| {1706// Acquiring a new EntityWorldMut here and using that instead of `self` is fine because1707// the outer `world_scope` will handle updating our location if it gets changed by the user code1708let mut this = world.entity_mut(id);1709f(&mut this, res)1710})1711})1712}17131714/// Temporarily removes the requested resource from the [`World`] if it exists, runs custom user code,1715/// then re-adds the resource before returning. Returns `None` if the resource does not exist in the [`World`].1716///1717/// See [`World::try_resource_scope`] for further details.1718pub fn try_resource_scope<R: Resource, U>(1719&mut self,1720f: impl FnOnce(&mut EntityWorldMut, Mut<R>) -> U,1721) -> Option<U> {1722let id = self.id();1723self.world_scope(|world| {1724world.try_resource_scope(|world, res| {1725// Acquiring a new EntityWorldMut here and using that instead of `self` is fine because1726// the outer `world_scope` will handle updating our location if it gets changed by the user code1727let mut this = world.entity_mut(id);1728f(&mut this, res)1729})1730})1731}17321733/// Retrieves the change ticks for the given component. This can be useful for implementing change1734/// detection in custom runtimes.1735///1736/// # Panics1737///1738/// If the entity has been despawned while this `EntityWorldMut` is still alive.1739#[inline]1740pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {1741self.as_readonly().get_change_ticks::<T>()1742}17431744/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change1745/// detection in custom runtimes.1746///1747/// **You should prefer to use the typed API [`EntityWorldMut::get_change_ticks`] where possible and only1748/// use this in cases where the actual component types are not known at1749/// compile time.**1750///1751/// # Panics1752///1753/// If the entity has been despawned while this `EntityWorldMut` is still alive.1754#[inline]1755pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {1756self.as_readonly().get_change_ticks_by_id(component_id)1757}17581759/// Returns [untyped read-only reference(s)](Ptr) to component(s) for the1760/// current entity, based on the given [`ComponentId`]s.1761///1762/// **You should prefer to use the typed API [`EntityWorldMut::get`] where1763/// possible and only use this in cases where the actual component types1764/// are not known at compile time.**1765///1766/// Unlike [`EntityWorldMut::get`], this returns untyped reference(s) to1767/// component(s), and it's the job of the caller to ensure the correct1768/// type(s) are dereferenced (if necessary).1769///1770/// # Errors1771///1772/// Returns [`EntityComponentError::MissingComponent`] if the entity does1773/// not have a component.1774///1775/// # Examples1776///1777/// For examples on how to use this method, see [`EntityRef::get_by_id`].1778///1779/// # Panics1780///1781/// If the entity has been despawned while this `EntityWorldMut` is still alive.1782#[inline]1783pub fn get_by_id<F: DynamicComponentFetch>(1784&self,1785component_ids: F,1786) -> Result<F::Ref<'_>, EntityComponentError> {1787self.as_readonly().get_by_id(component_ids)1788}17891790/// Consumes `self` and returns [untyped read-only reference(s)](Ptr) to1791/// component(s) with lifetime `'w` for the current entity, based on the1792/// given [`ComponentId`]s.1793///1794/// **You should prefer to use the typed API [`EntityWorldMut::into_borrow`]1795/// where possible and only use this in cases where the actual component1796/// types are not known at compile time.**1797///1798/// Unlike [`EntityWorldMut::into_borrow`], this returns untyped reference(s) to1799/// component(s), and it's the job of the caller to ensure the correct1800/// type(s) are dereferenced (if necessary).1801///1802/// # Errors1803///1804/// Returns [`EntityComponentError::MissingComponent`] if the entity does1805/// not have a component.1806///1807/// # Examples1808///1809/// For examples on how to use this method, see [`EntityRef::get_by_id`].1810///1811/// # Panics1812///1813/// If the entity has been despawned while this `EntityWorldMut` is still alive.1814#[inline]1815pub fn into_borrow_by_id<F: DynamicComponentFetch>(1816self,1817component_ids: F,1818) -> Result<F::Ref<'w>, EntityComponentError> {1819self.into_readonly().get_by_id(component_ids)1820}18211822/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for1823/// the current entity, based on the given [`ComponentId`]s.1824///1825/// **You should prefer to use the typed API [`EntityWorldMut::get_mut`] where1826/// possible and only use this in cases where the actual component types1827/// are not known at compile time.**1828///1829/// Unlike [`EntityWorldMut::get_mut`], this returns untyped reference(s) to1830/// component(s), and it's the job of the caller to ensure the correct1831/// type(s) are dereferenced (if necessary).1832///1833/// # Errors1834///1835/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1836/// not have a component.1837/// - Returns [`EntityComponentError::AliasedMutability`] if a component1838/// is requested multiple times.1839///1840/// # Examples1841///1842/// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].1843///1844/// # Panics1845///1846/// If the entity has been despawned while this `EntityWorldMut` is still alive.1847#[inline]1848pub fn get_mut_by_id<F: DynamicComponentFetch>(1849&mut self,1850component_ids: F,1851) -> Result<F::Mut<'_>, EntityComponentError> {1852self.as_mutable().into_mut_by_id(component_ids)1853}18541855/// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for1856/// the current entity, based on the given [`ComponentId`]s.1857/// Assumes the given [`ComponentId`]s refer to mutable components.1858///1859/// **You should prefer to use the typed API [`EntityWorldMut::get_mut_assume_mutable`] where1860/// possible and only use this in cases where the actual component types1861/// are not known at compile time.**1862///1863/// Unlike [`EntityWorldMut::get_mut_assume_mutable`], this returns untyped reference(s) to1864/// component(s), and it's the job of the caller to ensure the correct1865/// type(s) are dereferenced (if necessary).1866///1867/// # Errors1868///1869/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1870/// not have a component.1871/// - Returns [`EntityComponentError::AliasedMutability`] if a component1872/// is requested multiple times.1873///1874/// # Panics1875///1876/// If the entity has been despawned while this `EntityWorldMut` is still alive.1877///1878/// # Safety1879/// It is the callers responsibility to ensure that1880/// - the provided [`ComponentId`]s must refer to mutable components.1881#[inline]1882pub unsafe fn get_mut_assume_mutable_by_id<F: DynamicComponentFetch>(1883&mut self,1884component_ids: F,1885) -> Result<F::Mut<'_>, EntityComponentError> {1886self.as_mutable()1887.into_mut_assume_mutable_by_id(component_ids)1888}18891890/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)1891/// to component(s) with lifetime `'w` for the current entity, based on the1892/// given [`ComponentId`]s.1893///1894/// **You should prefer to use the typed API [`EntityWorldMut::into_mut`] where1895/// possible and only use this in cases where the actual component types1896/// are not known at compile time.**1897///1898/// Unlike [`EntityWorldMut::into_mut`], this returns untyped reference(s) to1899/// component(s), and it's the job of the caller to ensure the correct1900/// type(s) are dereferenced (if necessary).1901///1902/// # Errors1903///1904/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1905/// not have a component.1906/// - Returns [`EntityComponentError::AliasedMutability`] if a component1907/// is requested multiple times.1908///1909/// # Examples1910///1911/// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].1912///1913/// # Panics1914///1915/// If the entity has been despawned while this `EntityWorldMut` is still alive.1916#[inline]1917pub fn into_mut_by_id<F: DynamicComponentFetch>(1918self,1919component_ids: F,1920) -> Result<F::Mut<'w>, EntityComponentError> {1921self.into_mutable().into_mut_by_id(component_ids)1922}19231924/// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)1925/// to component(s) with lifetime `'w` for the current entity, based on the1926/// given [`ComponentId`]s.1927/// Assumes the given [`ComponentId`]s refer to mutable components.1928///1929/// **You should prefer to use the typed API [`EntityWorldMut::into_mut_assume_mutable`] where1930/// possible and only use this in cases where the actual component types1931/// are not known at compile time.**1932///1933/// Unlike [`EntityWorldMut::into_mut_assume_mutable`], this returns untyped reference(s) to1934/// component(s), and it's the job of the caller to ensure the correct1935/// type(s) are dereferenced (if necessary).1936///1937/// # Errors1938///1939/// - Returns [`EntityComponentError::MissingComponent`] if the entity does1940/// not have a component.1941/// - Returns [`EntityComponentError::AliasedMutability`] if a component1942/// is requested multiple times.1943///1944/// # Panics1945///1946/// If the entity has been despawned while this `EntityWorldMut` is still alive.1947///1948/// # Safety1949/// It is the callers responsibility to ensure that1950/// - the provided [`ComponentId`]s must refer to mutable components.1951#[inline]1952pub unsafe fn into_mut_assume_mutable_by_id<F: DynamicComponentFetch>(1953self,1954component_ids: F,1955) -> Result<F::Mut<'w>, EntityComponentError> {1956self.into_mutable()1957.into_mut_assume_mutable_by_id(component_ids)1958}19591960/// Adds a [`Bundle`] of components to the entity.1961///1962/// This will overwrite any previous value(s) of the same component type.1963///1964/// # Panics1965///1966/// If the entity has been despawned while this `EntityWorldMut` is still alive.1967#[track_caller]1968pub fn insert<T: Bundle>(&mut self, bundle: T) -> &mut Self {1969move_as_ptr!(bundle);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 {1998move_as_ptr!(bundle);1999self.insert_with_caller(2000bundle,2001InsertMode::Replace,2002MaybeLocation::caller(),2003relationship_hook_mode,2004)2005}20062007/// Adds a [`Bundle`] of components to the entity without overwriting.2008///2009/// This will leave any previous value(s) of the same component type2010/// unchanged.2011///2012/// # Panics2013///2014/// If the entity has been despawned while this `EntityWorldMut` is still alive.2015#[track_caller]2016pub fn insert_if_new<T: Bundle>(&mut self, bundle: T) -> &mut Self {2017move_as_ptr!(bundle);2018self.insert_with_caller(2019bundle,2020InsertMode::Keep,2021MaybeLocation::caller(),2022RelationshipHookMode::Run,2023)2024}20252026/// Adds a [`Bundle`] of components to the entity.2027#[inline]2028pub(crate) fn insert_with_caller<T: Bundle>(2029&mut self,2030bundle: MovingPtr<'_, T>,2031mode: InsertMode,2032caller: MaybeLocation,2033relationship_hook_mode: RelationshipHookMode,2034) -> &mut Self {2035let location = self.location();2036let change_tick = self.world.change_tick();2037let mut bundle_inserter =2038BundleInserter::new::<T>(self.world, location.archetype_id, change_tick);2039// SAFETY:2040// - `location` matches current entity and thus must currently exist in the source2041// archetype for this inserter and its location within the archetype.2042// - `T` matches the type used to create the `BundleInserter`.2043// - `apply_effect` is called exactly once after this function.2044// - The value pointed at by `bundle` is not accessed for anything other than `apply_effect`2045// and the caller ensures that the value is not accessed or dropped after this function2046// returns.2047let (bundle, location) = bundle.partial_move(|bundle| unsafe {2048bundle_inserter.insert(2049self.entity,2050location,2051bundle,2052mode,2053caller,2054relationship_hook_mode,2055)2056});2057self.location = Some(location);2058self.world.flush();2059self.update_location();2060// SAFETY:2061// - This is called exactly once after the `BundleInsert::insert` call before returning to safe code.2062// - `bundle` points to the same `B` that `BundleInsert::insert` was called on.2063unsafe { T::apply_effect(bundle, self) };2064self2065}20662067/// Inserts a dynamic [`Component`] into the entity.2068///2069/// This will overwrite any previous value(s) of the same component type.2070///2071/// You should prefer to use the typed API [`EntityWorldMut::insert`] where possible.2072///2073/// # Safety2074///2075/// - [`ComponentId`] must be from the same world as [`EntityWorldMut`]2076/// - [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]2077///2078/// # Panics2079///2080/// If the entity has been despawned while this `EntityWorldMut` is still alive.2081#[track_caller]2082pub unsafe fn insert_by_id(2083&mut self,2084component_id: ComponentId,2085component: OwningPtr<'_>,2086) -> &mut Self {2087self.insert_by_id_with_caller(2088component_id,2089component,2090InsertMode::Replace,2091MaybeLocation::caller(),2092RelationshipHookMode::Run,2093)2094}20952096/// # Safety2097///2098/// - [`ComponentId`] must be from the same world as [`EntityWorldMut`]2099/// - [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]2100#[inline]2101pub(crate) unsafe fn insert_by_id_with_caller(2102&mut self,2103component_id: ComponentId,2104component: OwningPtr<'_>,2105mode: InsertMode,2106caller: MaybeLocation,2107relationship_hook_insert_mode: RelationshipHookMode,2108) -> &mut Self {2109let location = self.location();2110let change_tick = self.world.change_tick();2111let bundle_id = self.world.bundles.init_component_info(2112&mut self.world.storages,2113&self.world.components,2114component_id,2115);2116let storage_type = self.world.bundles.get_storage_unchecked(bundle_id);21172118let bundle_inserter =2119BundleInserter::new_with_id(self.world, location.archetype_id, bundle_id, change_tick);21202121self.location = Some(insert_dynamic_bundle(2122bundle_inserter,2123self.entity,2124location,2125Some(component).into_iter(),2126Some(storage_type).iter().cloned(),2127mode,2128caller,2129relationship_hook_insert_mode,2130));2131self.world.flush();2132self.update_location();2133self2134}21352136/// Inserts a dynamic [`Bundle`] into the entity.2137///2138/// This will overwrite any previous value(s) of the same component type.2139///2140/// You should prefer to use the typed API [`EntityWorldMut::insert`] where possible.2141/// If your [`Bundle`] only has one component, use the cached API [`EntityWorldMut::insert_by_id`].2142///2143/// If possible, pass a sorted slice of `ComponentId` to maximize caching potential.2144///2145/// # Safety2146/// - Each [`ComponentId`] must be from the same world as [`EntityWorldMut`]2147/// - Each [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]2148///2149/// # Panics2150///2151/// If the entity has been despawned while this `EntityWorldMut` is still alive.2152#[track_caller]2153pub unsafe fn insert_by_ids<'a, I: Iterator<Item = OwningPtr<'a>>>(2154&mut self,2155component_ids: &[ComponentId],2156iter_components: I,2157) -> &mut Self {2158self.insert_by_ids_internal(component_ids, iter_components, RelationshipHookMode::Run)2159}21602161#[track_caller]2162pub(crate) unsafe fn insert_by_ids_internal<'a, I: Iterator<Item = OwningPtr<'a>>>(2163&mut self,2164component_ids: &[ComponentId],2165iter_components: I,2166relationship_hook_insert_mode: RelationshipHookMode,2167) -> &mut Self {2168let location = self.location();2169let change_tick = self.world.change_tick();2170let bundle_id = self.world.bundles.init_dynamic_info(2171&mut self.world.storages,2172&self.world.components,2173component_ids,2174);2175let mut storage_types =2176core::mem::take(self.world.bundles.get_storages_unchecked(bundle_id));2177let bundle_inserter =2178BundleInserter::new_with_id(self.world, location.archetype_id, bundle_id, change_tick);21792180self.location = Some(insert_dynamic_bundle(2181bundle_inserter,2182self.entity,2183location,2184iter_components,2185(*storage_types).iter().cloned(),2186InsertMode::Replace,2187MaybeLocation::caller(),2188relationship_hook_insert_mode,2189));2190*self.world.bundles.get_storages_unchecked(bundle_id) = core::mem::take(&mut storage_types);2191self.world.flush();2192self.update_location();2193self2194}21952196/// Removes all components in the [`Bundle`] from the entity and returns their previous values.2197///2198/// **Note:** If the entity does not have every component in the bundle, this method will not2199/// remove any of them.2200///2201/// # Panics2202///2203/// If the entity has been despawned while this `EntityWorldMut` is still alive.2204#[must_use]2205#[track_caller]2206pub fn take<T: Bundle + BundleFromComponents>(&mut self) -> Option<T> {2207let location = self.location();2208let entity = self.entity;22092210let mut remover =2211// SAFETY: The archetype id must be valid since this entity is in it.2212unsafe { BundleRemover::new::<T>(self.world, location.archetype_id, true) }?;2213// SAFETY: The passed location has the sane archetype as the remover, since they came from the same location.2214let (new_location, result) = unsafe {2215remover.remove(2216entity,2217location,2218MaybeLocation::caller(),2219|sets, table, components, bundle_components| {2220let mut bundle_components = bundle_components.iter().copied();2221(2222false,2223T::from_components(&mut (sets, table), &mut |(sets, table)| {2224let component_id = bundle_components.next().unwrap();2225// SAFETY: the component existed to be removed, so its id must be valid.2226let component_info = components.get_info_unchecked(component_id);2227match component_info.storage_type() {2228StorageType::Table => {2229table2230.as_mut()2231// SAFETY: The table must be valid if the component is in it.2232.debug_checked_unwrap()2233// SAFETY: The remover is cleaning this up.2234.take_component(component_id, location.table_row)2235}2236StorageType::SparseSet => sets2237.get_mut(component_id)2238.unwrap()2239.remove_and_forget(entity)2240.unwrap(),2241}2242}),2243)2244},2245)2246};2247self.location = Some(new_location);22482249self.world.flush();2250self.update_location();2251Some(result)2252}22532254/// Removes any components in the [`Bundle`] from the entity.2255///2256/// See [`EntityCommands::remove`](crate::system::EntityCommands::remove) for more details.2257///2258/// # Panics2259///2260/// If the entity has been despawned while this `EntityWorldMut` is still alive.2261#[track_caller]2262pub fn remove<T: Bundle>(&mut self) -> &mut Self {2263self.remove_with_caller::<T>(MaybeLocation::caller())2264}22652266#[inline]2267pub(crate) fn remove_with_caller<T: Bundle>(&mut self, caller: MaybeLocation) -> &mut Self {2268let location = self.location();22692270let Some(mut remover) =2271// SAFETY: The archetype id must be valid since this entity is in it.2272(unsafe { BundleRemover::new::<T>(self.world, location.archetype_id, false) })2273else {2274return self;2275};2276// SAFETY: The remover archetype came from the passed location and the removal can not fail.2277let new_location = unsafe {2278remover.remove(2279self.entity,2280location,2281caller,2282BundleRemover::empty_pre_remove,2283)2284}2285.0;22862287self.location = Some(new_location);2288self.world.flush();2289self.update_location();2290self2291}22922293/// Removes all components in the [`Bundle`] and remove all required components for each component in the bundle2294///2295/// # Panics2296///2297/// If the entity has been despawned while this `EntityWorldMut` is still alive.2298#[track_caller]2299pub fn remove_with_requires<T: Bundle>(&mut self) -> &mut Self {2300self.remove_with_requires_with_caller::<T>(MaybeLocation::caller())2301}23022303pub(crate) fn remove_with_requires_with_caller<T: Bundle>(2304&mut self,2305caller: MaybeLocation,2306) -> &mut Self {2307let location = self.location();2308let bundle_id = self.world.register_contributed_bundle_info::<T>();23092310// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.2311let Some(mut remover) = (unsafe {2312BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)2313}) else {2314return self;2315};2316// SAFETY: The remover archetype came from the passed location and the removal can not fail.2317let new_location = unsafe {2318remover.remove(2319self.entity,2320location,2321caller,2322BundleRemover::empty_pre_remove,2323)2324}2325.0;23262327self.location = Some(new_location);2328self.world.flush();2329self.update_location();2330self2331}23322333/// Removes any components except those in the [`Bundle`] (and its Required Components) from the entity.2334///2335/// See [`EntityCommands::retain`](crate::system::EntityCommands::retain) for more details.2336///2337/// # Panics2338///2339/// If the entity has been despawned while this `EntityWorldMut` is still alive.2340#[track_caller]2341pub fn retain<T: Bundle>(&mut self) -> &mut Self {2342self.retain_with_caller::<T>(MaybeLocation::caller())2343}23442345#[inline]2346pub(crate) fn retain_with_caller<T: Bundle>(&mut self, caller: MaybeLocation) -> &mut Self {2347let old_location = self.location();2348let retained_bundle = self.world.register_bundle_info::<T>();2349let archetypes = &mut self.world.archetypes;23502351// SAFETY: `retained_bundle` exists as we just registered it.2352let retained_bundle_info = unsafe { self.world.bundles.get_unchecked(retained_bundle) };2353let old_archetype = &mut archetypes[old_location.archetype_id];23542355// PERF: this could be stored in an Archetype Edge2356let to_remove = &old_archetype2357.iter_components()2358.filter(|c| !retained_bundle_info.contributed_components().contains(c))2359.collect::<Vec<_>>();2360let remove_bundle = self.world.bundles.init_dynamic_info(2361&mut self.world.storages,2362&self.world.components,2363to_remove,2364);23652366// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.2367let Some(mut remover) = (unsafe {2368BundleRemover::new_with_id(self.world, old_location.archetype_id, remove_bundle, false)2369}) else {2370return self;2371};2372// SAFETY: The remover archetype came from the passed location and the removal can not fail.2373let new_location = unsafe {2374remover.remove(2375self.entity,2376old_location,2377caller,2378BundleRemover::empty_pre_remove,2379)2380}2381.0;23822383self.location = Some(new_location);2384self.world.flush();2385self.update_location();2386self2387}23882389/// Removes a dynamic [`Component`] from the entity if it exists.2390///2391/// You should prefer to use the typed API [`EntityWorldMut::remove`] where possible.2392///2393/// # Panics2394///2395/// Panics if the provided [`ComponentId`] does not exist in the [`World`] or if the2396/// entity has been despawned while this `EntityWorldMut` is still alive.2397#[track_caller]2398pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {2399self.remove_by_id_with_caller(component_id, MaybeLocation::caller())2400}24012402#[inline]2403pub(crate) fn remove_by_id_with_caller(2404&mut self,2405component_id: ComponentId,2406caller: MaybeLocation,2407) -> &mut Self {2408let location = self.location();2409let components = &mut self.world.components;24102411let bundle_id = self.world.bundles.init_component_info(2412&mut self.world.storages,2413components,2414component_id,2415);24162417// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.2418let Some(mut remover) = (unsafe {2419BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)2420}) else {2421return self;2422};2423// SAFETY: The remover archetype came from the passed location and the removal can not fail.2424let new_location = unsafe {2425remover.remove(2426self.entity,2427location,2428caller,2429BundleRemover::empty_pre_remove,2430)2431}2432.0;24332434self.location = Some(new_location);2435self.world.flush();2436self.update_location();2437self2438}24392440/// Removes a dynamic bundle from the entity if it exists.2441///2442/// You should prefer to use the typed API [`EntityWorldMut::remove`] where possible.2443///2444/// # Panics2445///2446/// Panics if any of the provided [`ComponentId`]s do not exist in the [`World`] or if the2447/// entity has been despawned while this `EntityWorldMut` is still alive.2448#[track_caller]2449pub fn remove_by_ids(&mut self, component_ids: &[ComponentId]) -> &mut Self {2450self.remove_by_ids_with_caller(2451component_ids,2452MaybeLocation::caller(),2453RelationshipHookMode::Run,2454BundleRemover::empty_pre_remove,2455)2456}24572458#[inline]2459pub(crate) fn remove_by_ids_with_caller<T: 'static>(2460&mut self,2461component_ids: &[ComponentId],2462caller: MaybeLocation,2463relationship_hook_mode: RelationshipHookMode,2464pre_remove: impl FnOnce(2465&mut SparseSets,2466Option<&mut Table>,2467&Components,2468&[ComponentId],2469) -> (bool, T),2470) -> &mut Self {2471let location = self.location();2472let components = &mut self.world.components;24732474let bundle_id = self.world.bundles.init_dynamic_info(2475&mut self.world.storages,2476components,2477component_ids,2478);24792480// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.2481let Some(mut remover) = (unsafe {2482BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)2483}) else {2484return self;2485};2486remover.relationship_hook_mode = relationship_hook_mode;2487// SAFETY: The remover archetype came from the passed location and the removal can not fail.2488let new_location = unsafe { remover.remove(self.entity, location, caller, pre_remove) }.0;24892490self.location = Some(new_location);2491self.world.flush();2492self.update_location();2493self2494}24952496/// Removes all components associated with the entity.2497///2498/// # Panics2499///2500/// If the entity has been despawned while this `EntityWorldMut` is still alive.2501#[track_caller]2502pub fn clear(&mut self) -> &mut Self {2503self.clear_with_caller(MaybeLocation::caller())2504}25052506#[inline]2507pub(crate) fn clear_with_caller(&mut self, caller: MaybeLocation) -> &mut Self {2508let location = self.location();2509// PERF: this should not be necessary2510let component_ids: Vec<ComponentId> = self.archetype().components().to_vec();2511let components = &mut self.world.components;25122513let bundle_id = self.world.bundles.init_dynamic_info(2514&mut self.world.storages,2515components,2516component_ids.as_slice(),2517);25182519// SAFETY: We just created the bundle, and the archetype is valid, since we are in it.2520let Some(mut remover) = (unsafe {2521BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)2522}) else {2523return self;2524};2525// SAFETY: The remover archetype came from the passed location and the removal can not fail.2526let new_location = unsafe {2527remover.remove(2528self.entity,2529location,2530caller,2531BundleRemover::empty_pre_remove,2532)2533}2534.0;25352536self.location = Some(new_location);2537self.world.flush();2538self.update_location();2539self2540}25412542/// Despawns the current entity.2543///2544/// See [`World::despawn`] for more details.2545///2546/// # Note2547///2548/// This will also despawn any [`Children`](crate::hierarchy::Children) entities, and any other [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured2549/// to despawn descendants. This results in "recursive despawn" behavior.2550///2551/// # Panics2552///2553/// If the entity has been despawned while this `EntityWorldMut` is still alive.2554#[track_caller]2555pub fn despawn(self) {2556self.despawn_with_caller(MaybeLocation::caller());2557}25582559pub(crate) fn despawn_with_caller(self, caller: MaybeLocation) {2560let location = self.location();2561let world = self.world;2562let archetype = &world.archetypes[location.archetype_id];25632564// SAFETY: Archetype cannot be mutably aliased by DeferredWorld2565let (archetype, mut deferred_world) = unsafe {2566let archetype: *const Archetype = archetype;2567let world = world.as_unsafe_world_cell();2568(&*archetype, world.into_deferred())2569};25702571// SAFETY: All components in the archetype exist in world2572unsafe {2573if archetype.has_despawn_observer() {2574// SAFETY: the DESPAWN event_key corresponds to the Despawn event's type2575deferred_world.trigger_raw(2576DESPAWN,2577&mut Despawn {2578entity: self.entity,2579},2580&mut EntityComponentsTrigger {2581components: archetype.components(),2582},2583caller,2584);2585}2586deferred_world.trigger_on_despawn(2587archetype,2588self.entity,2589archetype.iter_components(),2590caller,2591);2592if archetype.has_replace_observer() {2593// SAFETY: the REPLACE event_key corresponds to the Replace event's type2594deferred_world.trigger_raw(2595REPLACE,2596&mut Replace {2597entity: self.entity,2598},2599&mut EntityComponentsTrigger {2600components: archetype.components(),2601},2602caller,2603);2604}2605deferred_world.trigger_on_replace(2606archetype,2607self.entity,2608archetype.iter_components(),2609caller,2610RelationshipHookMode::Run,2611);2612if archetype.has_remove_observer() {2613// SAFETY: the REMOVE event_key corresponds to the Remove event's type2614deferred_world.trigger_raw(2615REMOVE,2616&mut Remove {2617entity: self.entity,2618},2619&mut EntityComponentsTrigger {2620components: archetype.components(),2621},2622caller,2623);2624}2625deferred_world.trigger_on_remove(2626archetype,2627self.entity,2628archetype.iter_components(),2629caller,2630);2631}26322633for component_id in archetype.iter_components() {2634world.removed_components.write(component_id, self.entity);2635}26362637// Observers and on_remove hooks may reserve new entities, which2638// requires a flush before Entities::free may be called.2639world.flush_entities();26402641let location = world2642.entities2643.free(self.entity)2644.flatten()2645.expect("entity should exist at this point.");2646let table_row;2647let moved_entity;2648let change_tick = world.change_tick();26492650{2651let archetype = &mut world.archetypes[location.archetype_id];2652let remove_result = archetype.swap_remove(location.archetype_row);2653if let Some(swapped_entity) = remove_result.swapped_entity {2654let swapped_location = world.entities.get(swapped_entity).unwrap();2655// SAFETY: swapped_entity is valid and the swapped entity's components are2656// moved to the new location immediately after.2657unsafe {2658world.entities.set(2659swapped_entity.index(),2660Some(EntityLocation {2661archetype_id: swapped_location.archetype_id,2662archetype_row: location.archetype_row,2663table_id: swapped_location.table_id,2664table_row: swapped_location.table_row,2665}),2666);2667world2668.entities2669.mark_spawn_despawn(swapped_entity.index(), caller, change_tick);2670}2671}2672table_row = remove_result.table_row;26732674for component_id in archetype.sparse_set_components() {2675// set must have existed for the component to be added.2676let sparse_set = world.storages.sparse_sets.get_mut(component_id).unwrap();2677sparse_set.remove(self.entity);2678}2679// SAFETY: table rows stored in archetypes always exist2680moved_entity = unsafe {2681world.storages.tables[archetype.table_id()].swap_remove_unchecked(table_row)2682};2683};26842685if let Some(moved_entity) = moved_entity {2686let moved_location = world.entities.get(moved_entity).unwrap();2687// SAFETY: `moved_entity` is valid and the provided `EntityLocation` accurately reflects2688// the current location of the entity and its component data.2689unsafe {2690world.entities.set(2691moved_entity.index(),2692Some(EntityLocation {2693archetype_id: moved_location.archetype_id,2694archetype_row: moved_location.archetype_row,2695table_id: moved_location.table_id,2696table_row,2697}),2698);2699world2700.entities2701.mark_spawn_despawn(moved_entity.index(), caller, change_tick);2702}2703world.archetypes[moved_location.archetype_id]2704.set_entity_table_row(moved_location.archetype_row, table_row);2705}2706world.flush();2707}27082709/// Ensures any commands triggered by the actions of Self are applied, equivalent to [`World::flush`]2710pub fn flush(self) -> Entity {2711self.world.flush();2712self.entity2713}27142715/// Gets read-only access to the world that the current entity belongs to.2716#[inline]2717pub fn world(&self) -> &World {2718self.world2719}27202721/// Returns this entity's world.2722///2723/// See [`EntityWorldMut::world_scope`] or [`EntityWorldMut::into_world_mut`] for a safe alternative.2724///2725/// # Safety2726/// Caller must not modify the world in a way that changes the current entity's location2727/// If the caller _does_ do something that could change the location, `self.update_location()`2728/// must be called before using any other methods on this [`EntityWorldMut`].2729#[inline]2730pub unsafe fn world_mut(&mut self) -> &mut World {2731self.world2732}27332734/// Returns this entity's [`World`], consuming itself.2735#[inline]2736pub fn into_world_mut(self) -> &'w mut World {2737self.world2738}27392740/// Gives mutable access to this entity's [`World`] in a temporary scope.2741/// This is a safe alternative to using [`EntityWorldMut::world_mut`].2742///2743/// # Examples2744///2745/// ```2746/// # use bevy_ecs::prelude::*;2747/// #[derive(Resource, Default, Clone, Copy)]2748/// struct R(u32);2749///2750/// # let mut world = World::new();2751/// # world.init_resource::<R>();2752/// # let mut entity = world.spawn_empty();2753/// // This closure gives us temporary access to the world.2754/// let new_r = entity.world_scope(|world: &mut World| {2755/// // Mutate the world while we have access to it.2756/// let mut r = world.resource_mut::<R>();2757/// r.0 += 1;2758///2759/// // Return a value from the world before giving it back to the `EntityWorldMut`.2760/// *r2761/// });2762/// # assert_eq!(new_r.0, 1);2763/// ```2764pub fn world_scope<U>(&mut self, f: impl FnOnce(&mut World) -> U) -> U {2765struct Guard<'w, 'a> {2766entity_mut: &'a mut EntityWorldMut<'w>,2767}27682769impl Drop for Guard<'_, '_> {2770#[inline]2771fn drop(&mut self) {2772self.entity_mut.update_location();2773}2774}27752776// When `guard` is dropped at the end of this scope,2777// it will update the cached `EntityLocation` for this instance.2778// This will run even in case the closure `f` unwinds.2779let guard = Guard { entity_mut: self };2780f(guard.entity_mut.world)2781}27822783/// Updates the internal entity location to match the current location in the internal2784/// [`World`].2785///2786/// This is *only* required when using the unsafe function [`EntityWorldMut::world_mut`],2787/// which enables the location to change.2788pub fn update_location(&mut self) {2789self.location = self.world.entities().get(self.entity);2790}27912792/// Returns if the entity has been despawned.2793///2794/// Normally it shouldn't be needed to explicitly check if the entity has been despawned2795/// between commands as this shouldn't happen. However, for some special cases where it2796/// is known that a hook or an observer might despawn the entity while a [`EntityWorldMut`]2797/// reference is still held, this method can be used to check if the entity is still alive2798/// to avoid panicking when calling further methods.2799#[inline]2800pub fn is_despawned(&self) -> bool {2801self.location.is_none()2802}28032804/// Gets an Entry into the world for this entity and component for in-place manipulation.2805///2806/// The type parameter specifies which component to get.2807///2808/// # Examples2809///2810/// ```2811/// # use bevy_ecs::prelude::*;2812/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]2813/// struct Comp(u32);2814///2815/// # let mut world = World::new();2816/// let mut entity = world.spawn_empty();2817/// entity.entry().or_insert_with(|| Comp(4));2818/// # let entity_id = entity.id();2819/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 4);2820///2821/// # let mut entity = world.get_entity_mut(entity_id).unwrap();2822/// entity.entry::<Comp>().and_modify(|mut c| c.0 += 1);2823/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 5);2824/// ```2825///2826/// # Panics2827///2828/// If the entity has been despawned while this `EntityWorldMut` is still alive.2829pub fn entry<'a, T: Component>(&'a mut self) -> ComponentEntry<'w, 'a, T> {2830if self.contains::<T>() {2831ComponentEntry::Occupied(OccupiedComponentEntry {2832entity_world: self,2833_marker: PhantomData,2834})2835} else {2836ComponentEntry::Vacant(VacantComponentEntry {2837entity_world: self,2838_marker: PhantomData,2839})2840}2841}28422843/// Creates an [`Observer`] watching for an [`EntityEvent`] of type `E` whose [`EntityEvent::event_target`]2844/// targets this entity.2845///2846/// # Panics2847///2848/// If the entity has been despawned while this `EntityWorldMut` is still alive.2849///2850/// Panics if the given system is an exclusive system.2851#[track_caller]2852pub fn observe<E: EntityEvent, B: Bundle, M>(2853&mut self,2854observer: impl IntoObserverSystem<E, B, M>,2855) -> &mut Self {2856self.observe_with_caller(observer, MaybeLocation::caller())2857}28582859pub(crate) fn observe_with_caller<E: EntityEvent, B: Bundle, M>(2860&mut self,2861observer: impl IntoObserverSystem<E, B, M>,2862caller: MaybeLocation,2863) -> &mut Self {2864self.assert_not_despawned();2865let bundle = Observer::new(observer).with_entity(self.entity);2866move_as_ptr!(bundle);2867self.world.spawn_with_caller(bundle, caller);2868self.world.flush();2869self.update_location();2870self2871}28722873/// Clones parts of an entity (components, observers, etc.) onto another entity,2874/// configured through [`EntityClonerBuilder`].2875///2876/// The other entity will receive all the components of the original that implement2877/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are2878/// [denied](EntityClonerBuilder::deny) in the `config`.2879///2880/// # Example2881///2882/// ```2883/// # use bevy_ecs::prelude::*;2884/// # #[derive(Component, Clone, PartialEq, Debug)]2885/// # struct ComponentA;2886/// # #[derive(Component, Clone, PartialEq, Debug)]2887/// # struct ComponentB;2888/// # let mut world = World::new();2889/// # let entity = world.spawn((ComponentA, ComponentB)).id();2890/// # let target = world.spawn_empty().id();2891/// // Clone all components except ComponentA onto the target.2892/// world.entity_mut(entity).clone_with_opt_out(target, |builder| {2893/// builder.deny::<ComponentA>();2894/// });2895/// # assert_eq!(world.get::<ComponentA>(target), None);2896/// # assert_eq!(world.get::<ComponentB>(target), Some(&ComponentB));2897/// ```2898///2899/// See [`EntityClonerBuilder<OptOut>`] for more options.2900///2901/// # Panics2902///2903/// - If this entity has been despawned while this `EntityWorldMut` is still alive.2904/// - If the target entity does not exist.2905pub fn clone_with_opt_out(2906&mut self,2907target: Entity,2908config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,2909) -> &mut Self {2910self.assert_not_despawned();29112912let mut builder = EntityCloner::build_opt_out(self.world);2913config(&mut builder);2914builder.clone_entity(self.entity, target);29152916self.world.flush();2917self.update_location();2918self2919}29202921/// Clones parts of an entity (components, observers, etc.) onto another entity,2922/// configured through [`EntityClonerBuilder`].2923///2924/// The other entity will receive only the components of the original that implement2925/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are2926/// [allowed](EntityClonerBuilder::allow) in the `config`.2927///2928/// # Example2929///2930/// ```2931/// # use bevy_ecs::prelude::*;2932/// # #[derive(Component, Clone, PartialEq, Debug)]2933/// # struct ComponentA;2934/// # #[derive(Component, Clone, PartialEq, Debug)]2935/// # struct ComponentB;2936/// # let mut world = World::new();2937/// # let entity = world.spawn((ComponentA, ComponentB)).id();2938/// # let target = world.spawn_empty().id();2939/// // Clone only ComponentA onto the target.2940/// world.entity_mut(entity).clone_with_opt_in(target, |builder| {2941/// builder.allow::<ComponentA>();2942/// });2943/// # assert_eq!(world.get::<ComponentA>(target), Some(&ComponentA));2944/// # assert_eq!(world.get::<ComponentB>(target), None);2945/// ```2946///2947/// See [`EntityClonerBuilder<OptIn>`] for more options.2948///2949/// # Panics2950///2951/// - If this entity has been despawned while this `EntityWorldMut` is still alive.2952/// - If the target entity does not exist.2953pub fn clone_with_opt_in(2954&mut self,2955target: Entity,2956config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,2957) -> &mut Self {2958self.assert_not_despawned();29592960let mut builder = EntityCloner::build_opt_in(self.world);2961config(&mut builder);2962builder.clone_entity(self.entity, target);29632964self.world.flush();2965self.update_location();2966self2967}29682969/// Spawns a clone of this entity and returns the [`Entity`] of the clone.2970///2971/// The clone will receive all the components of the original that implement2972/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).2973///2974/// To configure cloning behavior (such as only cloning certain components),2975/// use [`EntityWorldMut::clone_and_spawn_with_opt_out`]/2976/// [`opt_in`](`EntityWorldMut::clone_and_spawn_with_opt_in`).2977///2978/// # Panics2979///2980/// If this entity has been despawned while this `EntityWorldMut` is still alive.2981pub fn clone_and_spawn(&mut self) -> Entity {2982self.clone_and_spawn_with_opt_out(|_| {})2983}29842985/// Spawns a clone of this entity and allows configuring cloning behavior2986/// using [`EntityClonerBuilder`], returning the [`Entity`] of the clone.2987///2988/// The clone will receive all the components of the original that implement2989/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are2990/// [denied](EntityClonerBuilder::deny) in the `config`.2991///2992/// # Example2993///2994/// ```2995/// # use bevy_ecs::prelude::*;2996/// # let mut world = World::new();2997/// # let entity = world.spawn((ComponentA, ComponentB)).id();2998/// # #[derive(Component, Clone, PartialEq, Debug)]2999/// # struct ComponentA;3000/// # #[derive(Component, Clone, PartialEq, Debug)]3001/// # struct ComponentB;3002/// // Create a clone of an entity but without ComponentA.3003/// let entity_clone = world.entity_mut(entity).clone_and_spawn_with_opt_out(|builder| {3004/// builder.deny::<ComponentA>();3005/// });3006/// # assert_eq!(world.get::<ComponentA>(entity_clone), None);3007/// # assert_eq!(world.get::<ComponentB>(entity_clone), Some(&ComponentB));3008/// ```3009///3010/// See [`EntityClonerBuilder<OptOut>`] for more options.3011///3012/// # Panics3013///3014/// If this entity has been despawned while this `EntityWorldMut` is still alive.3015pub fn clone_and_spawn_with_opt_out(3016&mut self,3017config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,3018) -> Entity {3019self.assert_not_despawned();30203021let entity_clone = self.world.entities.reserve_entity();3022self.world.flush();30233024let mut builder = EntityCloner::build_opt_out(self.world);3025config(&mut builder);3026builder.clone_entity(self.entity, entity_clone);30273028self.world.flush();3029self.update_location();3030entity_clone3031}30323033/// Spawns a clone of this entity and allows configuring cloning behavior3034/// using [`EntityClonerBuilder`], returning the [`Entity`] of the clone.3035///3036/// The clone will receive only the components of the original that implement3037/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are3038/// [allowed](EntityClonerBuilder::allow) in the `config`.3039///3040/// # Example3041///3042/// ```3043/// # use bevy_ecs::prelude::*;3044/// # let mut world = World::new();3045/// # let entity = world.spawn((ComponentA, ComponentB)).id();3046/// # #[derive(Component, Clone, PartialEq, Debug)]3047/// # struct ComponentA;3048/// # #[derive(Component, Clone, PartialEq, Debug)]3049/// # struct ComponentB;3050/// // Create a clone of an entity but only with ComponentA.3051/// let entity_clone = world.entity_mut(entity).clone_and_spawn_with_opt_in(|builder| {3052/// builder.allow::<ComponentA>();3053/// });3054/// # assert_eq!(world.get::<ComponentA>(entity_clone), Some(&ComponentA));3055/// # assert_eq!(world.get::<ComponentB>(entity_clone), None);3056/// ```3057///3058/// See [`EntityClonerBuilder<OptIn>`] for more options.3059///3060/// # Panics3061///3062/// If this entity has been despawned while this `EntityWorldMut` is still alive.3063pub fn clone_and_spawn_with_opt_in(3064&mut self,3065config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,3066) -> Entity {3067self.assert_not_despawned();30683069let entity_clone = self.world.entities.reserve_entity();3070self.world.flush();30713072let mut builder = EntityCloner::build_opt_in(self.world);3073config(&mut builder);3074builder.clone_entity(self.entity, entity_clone);30753076self.world.flush();3077self.update_location();3078entity_clone3079}30803081/// Clones the specified components of this entity and inserts them into another entity.3082///3083/// Components can only be cloned if they implement3084/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).3085///3086/// # Panics3087///3088/// - If this entity has been despawned while this `EntityWorldMut` is still alive.3089/// - If the target entity does not exist.3090pub fn clone_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {3091self.assert_not_despawned();30923093EntityCloner::build_opt_in(self.world)3094.allow::<B>()3095.clone_entity(self.entity, target);30963097self.world.flush();3098self.update_location();3099self3100}31013102/// Clones the specified components of this entity and inserts them into another entity,3103/// then removes the components from this entity.3104///3105/// Components can only be cloned if they implement3106/// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).3107///3108/// # Panics3109///3110/// - If this entity has been despawned while this `EntityWorldMut` is still alive.3111/// - If the target entity does not exist.3112pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {3113self.assert_not_despawned();31143115EntityCloner::build_opt_in(self.world)3116.allow::<B>()3117.move_components(true)3118.clone_entity(self.entity, target);31193120self.world.flush();3121self.update_location();3122self3123}31243125/// Returns the source code location from which this entity has last been spawned.3126pub fn spawned_by(&self) -> MaybeLocation {3127self.world()3128.entities()3129.entity_get_spawned_or_despawned_by(self.entity)3130.map(|location| location.unwrap())3131}31323133/// Returns the [`Tick`] at which this entity has last been spawned.3134pub fn spawn_tick(&self) -> Tick {3135self.assert_not_despawned();31363137// SAFETY: entity being alive was asserted3138unsafe {3139self.world()3140.entities()3141.entity_get_spawned_or_despawned_unchecked(self.entity)3142.13143}3144}31453146/// Reborrows this entity in a temporary scope.3147/// This is useful for executing a function that requires a `EntityWorldMut`3148/// but you do not want to move out the entity ownership.3149pub fn reborrow_scope<U>(&mut self, f: impl FnOnce(EntityWorldMut) -> U) -> U {3150let Self {3151entity, location, ..3152} = *self;3153self.world_scope(move |world| {3154f(EntityWorldMut {3155world,3156entity,3157location,3158})3159})3160}31613162/// Deprecated. Use [`World::trigger`] instead.3163#[track_caller]3164#[deprecated(3165since = "0.17.0",3166note = "Use World::trigger with an EntityEvent instead."3167)]3168pub fn trigger<'t>(&mut self, event: impl EntityEvent<Trigger<'t>: Default>) -> &mut Self {3169log::warn!("EntityWorldMut::trigger is deprecated and no longer triggers the event for the current EntityWorldMut entity. Use World::trigger instead with an EntityEvent.");3170self.world_scope(|world| {3171world.trigger(event);3172});3173self3174}3175}31763177/// A view into a single entity and component in a world, which may either be vacant or occupied.3178///3179/// This `enum` can only be constructed from the [`entry`] method on [`EntityWorldMut`].3180///3181/// [`entry`]: EntityWorldMut::entry3182pub enum ComponentEntry<'w, 'a, T: Component> {3183/// An occupied entry.3184Occupied(OccupiedComponentEntry<'w, 'a, T>),3185/// A vacant entry.3186Vacant(VacantComponentEntry<'w, 'a, T>),3187}31883189impl<'w, 'a, T: Component<Mutability = Mutable>> ComponentEntry<'w, 'a, T> {3190/// Provides in-place mutable access to an occupied entry.3191///3192/// # Examples3193///3194/// ```3195/// # use bevy_ecs::prelude::*;3196/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3197/// struct Comp(u32);3198///3199/// # let mut world = World::new();3200/// let mut entity = world.spawn(Comp(0));3201///3202/// entity.entry::<Comp>().and_modify(|mut c| c.0 += 1);3203/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 1);3204/// ```3205#[inline]3206pub fn and_modify<F: FnOnce(Mut<'_, T>)>(self, f: F) -> Self {3207match self {3208ComponentEntry::Occupied(mut entry) => {3209f(entry.get_mut());3210ComponentEntry::Occupied(entry)3211}3212ComponentEntry::Vacant(entry) => ComponentEntry::Vacant(entry),3213}3214}3215}32163217impl<'w, 'a, T: Component> ComponentEntry<'w, 'a, T> {3218/// Replaces the component of the entry, and returns an [`OccupiedComponentEntry`].3219///3220/// # Examples3221///3222/// ```3223/// # use bevy_ecs::prelude::*;3224/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3225/// struct Comp(u32);3226///3227/// # let mut world = World::new();3228/// let mut entity = world.spawn_empty();3229///3230/// let entry = entity.entry().insert_entry(Comp(4));3231/// assert_eq!(entry.get(), &Comp(4));3232///3233/// let entry = entity.entry().insert_entry(Comp(2));3234/// assert_eq!(entry.get(), &Comp(2));3235/// ```3236#[inline]3237pub fn insert_entry(self, component: T) -> OccupiedComponentEntry<'w, 'a, T> {3238match self {3239ComponentEntry::Occupied(mut entry) => {3240entry.insert(component);3241entry3242}3243ComponentEntry::Vacant(entry) => entry.insert(component),3244}3245}32463247/// Ensures the entry has this component by inserting the given default if empty, and3248/// returns a mutable reference to this component in the entry.3249///3250/// # Examples3251///3252/// ```3253/// # use bevy_ecs::prelude::*;3254/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3255/// struct Comp(u32);3256///3257/// # let mut world = World::new();3258/// let mut entity = world.spawn_empty();3259///3260/// entity.entry().or_insert(Comp(4));3261/// # let entity_id = entity.id();3262/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 4);3263///3264/// # let mut entity = world.get_entity_mut(entity_id).unwrap();3265/// entity.entry().or_insert(Comp(15)).into_mut().0 *= 2;3266/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 8);3267/// ```3268#[inline]3269pub fn or_insert(self, default: T) -> OccupiedComponentEntry<'w, 'a, T> {3270match self {3271ComponentEntry::Occupied(entry) => entry,3272ComponentEntry::Vacant(entry) => entry.insert(default),3273}3274}32753276/// Ensures the entry has this component by inserting the result of the default function if3277/// empty, and 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().or_insert_with(|| Comp(4));3290/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 4);3291/// ```3292#[inline]3293pub fn or_insert_with<F: FnOnce() -> T>(self, default: F) -> OccupiedComponentEntry<'w, 'a, T> {3294match self {3295ComponentEntry::Occupied(entry) => entry,3296ComponentEntry::Vacant(entry) => entry.insert(default()),3297}3298}3299}33003301impl<'w, 'a, T: Component + Default> ComponentEntry<'w, 'a, T> {3302/// Ensures the entry has this component by inserting the default value if empty, and3303/// returns a mutable reference to this component in the entry.3304///3305/// # Examples3306///3307/// ```3308/// # use bevy_ecs::prelude::*;3309/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3310/// struct Comp(u32);3311///3312/// # let mut world = World::new();3313/// let mut entity = world.spawn_empty();3314///3315/// entity.entry::<Comp>().or_default();3316/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 0);3317/// ```3318#[inline]3319pub fn or_default(self) -> OccupiedComponentEntry<'w, 'a, T> {3320match self {3321ComponentEntry::Occupied(entry) => entry,3322ComponentEntry::Vacant(entry) => entry.insert(Default::default()),3323}3324}3325}33263327/// A view into an occupied entry in a [`EntityWorldMut`]. It is part of the [`OccupiedComponentEntry`] enum.3328///3329/// The contained entity must have the component type parameter if we have this struct.3330pub struct OccupiedComponentEntry<'w, 'a, T: Component> {3331entity_world: &'a mut EntityWorldMut<'w>,3332_marker: PhantomData<T>,3333}33343335impl<'w, 'a, T: Component> OccupiedComponentEntry<'w, 'a, T> {3336/// Gets a reference to the component in the entry.3337///3338/// # Examples3339///3340/// ```3341/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3342/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3343/// struct Comp(u32);3344///3345/// # let mut world = World::new();3346/// let mut entity = world.spawn(Comp(5));3347///3348/// if let ComponentEntry::Occupied(o) = entity.entry::<Comp>() {3349/// assert_eq!(o.get().0, 5);3350/// }3351/// ```3352#[inline]3353pub fn get(&self) -> &T {3354// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.3355self.entity_world.get::<T>().unwrap()3356}33573358/// Replaces the component of the entry.3359///3360/// # Examples3361///3362/// ```3363/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3364/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3365/// struct Comp(u32);3366///3367/// # let mut world = World::new();3368/// let mut entity = world.spawn(Comp(5));3369///3370/// if let ComponentEntry::Occupied(mut o) = entity.entry::<Comp>() {3371/// o.insert(Comp(10));3372/// }3373///3374/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 10);3375/// ```3376#[inline]3377pub fn insert(&mut self, component: T) {3378self.entity_world.insert(component);3379}33803381/// Removes the component from the entry and returns it.3382///3383/// # Examples3384///3385/// ```3386/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3387/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3388/// struct Comp(u32);3389///3390/// # let mut world = World::new();3391/// let mut entity = world.spawn(Comp(5));3392///3393/// if let ComponentEntry::Occupied(o) = entity.entry::<Comp>() {3394/// assert_eq!(o.take(), Comp(5));3395/// }3396///3397/// assert_eq!(world.query::<&Comp>().iter(&world).len(), 0);3398/// ```3399#[inline]3400pub fn take(self) -> T {3401// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.3402self.entity_world.take().unwrap()3403}3404}34053406impl<'w, 'a, T: Component<Mutability = Mutable>> OccupiedComponentEntry<'w, 'a, T> {3407/// Gets a mutable reference to the component in the entry.3408///3409/// If you need a reference to the [`OccupiedComponentEntry`] which may outlive the destruction of3410/// the [`OccupiedComponentEntry`] value, see [`into_mut`].3411///3412/// [`into_mut`]: Self::into_mut3413///3414/// # Examples3415///3416/// ```3417/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3418/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3419/// struct Comp(u32);3420///3421/// # let mut world = World::new();3422/// let mut entity = world.spawn(Comp(5));3423///3424/// if let ComponentEntry::Occupied(mut o) = entity.entry::<Comp>() {3425/// o.get_mut().0 += 10;3426/// assert_eq!(o.get().0, 15);3427///3428/// // We can use the same Entry multiple times.3429/// o.get_mut().0 += 23430/// }3431///3432/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 17);3433/// ```3434#[inline]3435pub fn get_mut(&mut self) -> Mut<'_, T> {3436// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.3437self.entity_world.get_mut::<T>().unwrap()3438}34393440/// Converts the [`OccupiedComponentEntry`] into a mutable reference to the value in the entry with3441/// a lifetime bound to the `EntityWorldMut`.3442///3443/// If you need multiple references to the [`OccupiedComponentEntry`], see [`get_mut`].3444///3445/// [`get_mut`]: Self::get_mut3446///3447/// # Examples3448///3449/// ```3450/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3451/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3452/// struct Comp(u32);3453///3454/// # let mut world = World::new();3455/// let mut entity = world.spawn(Comp(5));3456///3457/// if let ComponentEntry::Occupied(o) = entity.entry::<Comp>() {3458/// o.into_mut().0 += 10;3459/// }3460///3461/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 15);3462/// ```3463#[inline]3464pub fn into_mut(self) -> Mut<'a, T> {3465// This shouldn't panic because if we have an OccupiedComponentEntry the component must exist.3466self.entity_world.get_mut().unwrap()3467}3468}34693470/// A view into a vacant entry in a [`EntityWorldMut`]. It is part of the [`ComponentEntry`] enum.3471pub struct VacantComponentEntry<'w, 'a, T: Component> {3472entity_world: &'a mut EntityWorldMut<'w>,3473_marker: PhantomData<T>,3474}34753476impl<'w, 'a, T: Component> VacantComponentEntry<'w, 'a, T> {3477/// Inserts the component into the [`VacantComponentEntry`] and returns an [`OccupiedComponentEntry`].3478///3479/// # Examples3480///3481/// ```3482/// # use bevy_ecs::{prelude::*, world::ComponentEntry};3483/// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]3484/// struct Comp(u32);3485///3486/// # let mut world = World::new();3487/// let mut entity = world.spawn_empty();3488///3489/// if let ComponentEntry::Vacant(v) = entity.entry::<Comp>() {3490/// v.insert(Comp(10));3491/// }3492///3493/// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 10);3494/// ```3495#[inline]3496pub fn insert(self, component: T) -> OccupiedComponentEntry<'w, 'a, T> {3497self.entity_world.insert(component);3498OccupiedComponentEntry {3499entity_world: self.entity_world,3500_marker: PhantomData,3501}3502}3503}35043505/// Provides read-only access to a single entity and some of its components defined by the contained [`Access`].3506///3507/// To define the access when used as a [`QueryData`](crate::query::QueryData),3508/// use a [`QueryBuilder`](crate::query::QueryBuilder) or [`QueryParamBuilder`](crate::system::QueryParamBuilder).3509/// The [`FilteredEntityRef`] must be the entire [`QueryData`](crate::query::QueryData), and not nested inside a tuple with other data.3510///3511/// ```3512/// # use bevy_ecs::{prelude::*, world::FilteredEntityRef};3513/// #3514/// # #[derive(Component)]3515/// # struct A;3516/// #3517/// # let mut world = World::new();3518/// # world.spawn(A);3519/// #3520/// // This gives the `FilteredEntityRef` access to `&A`.3521/// let mut query = QueryBuilder::<FilteredEntityRef>::new(&mut world)3522/// .data::<&A>()3523/// .build();3524///3525/// let filtered_entity: FilteredEntityRef = query.single(&mut world).unwrap();3526/// let component: &A = filtered_entity.get().unwrap();3527/// ```3528#[derive(Clone, Copy)]3529pub struct FilteredEntityRef<'w, 's> {3530entity: UnsafeEntityCell<'w>,3531access: &'s Access,3532}35333534impl<'w, 's> FilteredEntityRef<'w, 's> {3535/// # Safety3536/// - No `&mut World` can exist from the underlying `UnsafeWorldCell`3537/// - If `access` takes read access to a component no mutable reference to that3538/// component can exist at the same time as the returned [`FilteredEntityMut`]3539/// - If `access` takes any access for a component `entity` must have that component.3540#[inline]3541pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {3542Self { entity, access }3543}35443545/// Returns the [ID](Entity) of the current entity.3546#[inline]3547#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]3548pub fn id(&self) -> Entity {3549self.entity.id()3550}35513552/// Gets metadata indicating the location where the current entity is stored.3553#[inline]3554pub fn location(&self) -> EntityLocation {3555self.entity.location()3556}35573558/// Returns the archetype that the current entity belongs to.3559#[inline]3560pub fn archetype(&self) -> &Archetype {3561self.entity.archetype()3562}35633564/// Returns a reference to the underlying [`Access`].3565#[inline]3566pub fn access(&self) -> &Access {3567self.access3568}35693570/// Returns `true` if the current entity has a component of type `T`.3571/// Otherwise, this returns `false`.3572///3573/// ## Notes3574///3575/// If you do not know the concrete type of a component, consider using3576/// [`Self::contains_id`] or [`Self::contains_type_id`].3577#[inline]3578pub fn contains<T: Component>(&self) -> bool {3579self.contains_type_id(TypeId::of::<T>())3580}35813582/// Returns `true` if the current entity has a component identified by `component_id`.3583/// Otherwise, this returns false.3584///3585/// ## Notes3586///3587/// - If you know the concrete type of the component, you should prefer [`Self::contains`].3588/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using3589/// [`Self::contains_type_id`].3590#[inline]3591pub fn contains_id(&self, component_id: ComponentId) -> bool {3592self.entity.contains_id(component_id)3593}35943595/// Returns `true` if the current entity has a component with the type identified by `type_id`.3596/// Otherwise, this returns false.3597///3598/// ## Notes3599///3600/// - If you know the concrete type of the component, you should prefer [`Self::contains`].3601/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].3602#[inline]3603pub fn contains_type_id(&self, type_id: TypeId) -> bool {3604self.entity.contains_type_id(type_id)3605}36063607/// Gets access to the component of type `T` for the current entity.3608/// Returns `None` if the entity does not have a component of type `T`.3609#[inline]3610pub fn get<T: Component>(&self) -> Option<&'w T> {3611let id = self3612.entity3613.world()3614.components()3615.get_valid_id(TypeId::of::<T>())?;3616self.access3617.has_component_read(id)3618// SAFETY: We have read access3619.then(|| unsafe { self.entity.get() })3620.flatten()3621}36223623/// Gets access to the component of type `T` for the current entity,3624/// including change detection information as a [`Ref`].3625///3626/// Returns `None` if the entity does not have a component of type `T`.3627#[inline]3628pub fn get_ref<T: Component>(&self) -> Option<Ref<'w, T>> {3629let id = self3630.entity3631.world()3632.components()3633.get_valid_id(TypeId::of::<T>())?;3634self.access3635.has_component_read(id)3636// SAFETY: We have read access3637.then(|| unsafe { self.entity.get_ref() })3638.flatten()3639}36403641/// Retrieves the change ticks for the given component. This can be useful for implementing change3642/// detection in custom runtimes.3643#[inline]3644pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {3645let id = self3646.entity3647.world()3648.components()3649.get_valid_id(TypeId::of::<T>())?;3650self.access3651.has_component_read(id)3652// SAFETY: We have read access3653.then(|| unsafe { self.entity.get_change_ticks::<T>() })3654.flatten()3655}36563657/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change3658/// detection in custom runtimes.3659///3660/// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only3661/// use this in cases where the actual component types are not known at3662/// compile time.**3663#[inline]3664pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {3665self.access3666.has_component_read(component_id)3667// SAFETY: We have read access3668.then(|| unsafe { self.entity.get_change_ticks_by_id(component_id) })3669.flatten()3670}36713672/// Gets the component of the given [`ComponentId`] from the entity.3673///3674/// **You should prefer to use the typed API [`Self::get`] where possible and only3675/// use this in cases where the actual component types are not known at3676/// compile time.**3677///3678/// Unlike [`FilteredEntityRef::get`], this returns a raw pointer to the component,3679/// which is only valid while the [`FilteredEntityRef`] is alive.3680#[inline]3681pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'w>> {3682self.access3683.has_component_read(component_id)3684// SAFETY: We have read access3685.then(|| unsafe { self.entity.get_by_id(component_id) })3686.flatten()3687}36883689/// Returns the source code location from which this entity has been spawned.3690pub fn spawned_by(&self) -> MaybeLocation {3691self.entity.spawned_by()3692}36933694/// Returns the [`Tick`] at which this entity has been spawned.3695pub fn spawn_tick(&self) -> Tick {3696self.entity.spawn_tick()3697}3698}36993700impl<'w, 's> From<FilteredEntityMut<'w, 's>> for FilteredEntityRef<'w, 's> {3701#[inline]3702fn from(entity: FilteredEntityMut<'w, 's>) -> Self {3703// SAFETY:3704// - `FilteredEntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.3705unsafe { FilteredEntityRef::new(entity.entity, entity.access) }3706}3707}37083709impl<'w, 's> From<&'w FilteredEntityMut<'_, 's>> for FilteredEntityRef<'w, 's> {3710#[inline]3711fn from(entity: &'w FilteredEntityMut<'_, 's>) -> Self {3712// SAFETY:3713// - `FilteredEntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.3714unsafe { FilteredEntityRef::new(entity.entity, entity.access) }3715}3716}37173718impl<'a> From<EntityRef<'a>> for FilteredEntityRef<'a, 'static> {3719fn from(entity: EntityRef<'a>) -> Self {3720// SAFETY:3721// - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`.3722unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }3723}3724}37253726impl<'a> From<&'a EntityRef<'_>> for FilteredEntityRef<'a, 'static> {3727fn from(entity: &'a EntityRef<'_>) -> Self {3728// SAFETY:3729// - `EntityRef` guarantees exclusive access to all components in the new `FilteredEntityRef`.3730unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }3731}3732}37333734impl<'a> From<EntityMut<'a>> for FilteredEntityRef<'a, 'static> {3735fn from(entity: EntityMut<'a>) -> Self {3736// SAFETY:3737// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.3738unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }3739}3740}37413742impl<'a> From<&'a EntityMut<'_>> for FilteredEntityRef<'a, 'static> {3743fn from(entity: &'a EntityMut<'_>) -> Self {3744// SAFETY:3745// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityRef`.3746unsafe { FilteredEntityRef::new(entity.cell, const { &Access::new_read_all() }) }3747}3748}37493750impl<'a> From<EntityWorldMut<'a>> for FilteredEntityRef<'a, 'static> {3751fn from(entity: EntityWorldMut<'a>) -> Self {3752// SAFETY:3753// - `EntityWorldMut` guarantees exclusive access to the entire world.3754unsafe {3755FilteredEntityRef::new(3756entity.into_unsafe_entity_cell(),3757const { &Access::new_read_all() },3758)3759}3760}3761}37623763impl<'a> From<&'a EntityWorldMut<'_>> for FilteredEntityRef<'a, 'static> {3764fn from(entity: &'a EntityWorldMut<'_>) -> Self {3765// SAFETY:3766// - `EntityWorldMut` guarantees exclusive access to the entire world.3767unsafe {3768FilteredEntityRef::new(3769entity.as_unsafe_entity_cell_readonly(),3770const { &Access::new_read_all() },3771)3772}3773}3774}37753776impl<'w, 's, B: Bundle> From<&'w EntityRefExcept<'_, 's, B>> for FilteredEntityRef<'w, 's> {3777fn from(value: &'w EntityRefExcept<'_, 's, B>) -> Self {3778// SAFETY:3779// - The FilteredEntityRef has the same component access as the given EntityRefExcept.3780unsafe { FilteredEntityRef::new(value.entity, value.access) }3781}3782}37833784impl PartialEq for FilteredEntityRef<'_, '_> {3785fn eq(&self, other: &Self) -> bool {3786self.entity() == other.entity()3787}3788}37893790impl Eq for FilteredEntityRef<'_, '_> {}37913792impl PartialOrd for FilteredEntityRef<'_, '_> {3793/// [`FilteredEntityRef`]'s comparison trait implementations match the underlying [`Entity`],3794/// and cannot discern between different worlds.3795fn partial_cmp(&self, other: &Self) -> Option<Ordering> {3796Some(self.cmp(other))3797}3798}37993800impl Ord for FilteredEntityRef<'_, '_> {3801fn cmp(&self, other: &Self) -> Ordering {3802self.entity().cmp(&other.entity())3803}3804}38053806impl Hash for FilteredEntityRef<'_, '_> {3807fn hash<H: Hasher>(&self, state: &mut H) {3808self.entity().hash(state);3809}3810}38113812impl ContainsEntity for FilteredEntityRef<'_, '_> {3813fn entity(&self) -> Entity {3814self.id()3815}3816}38173818// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.3819unsafe impl EntityEquivalent for FilteredEntityRef<'_, '_> {}38203821/// Provides mutable access to a single entity and some of its components defined by the contained [`Access`].3822///3823/// To define the access when used as a [`QueryData`](crate::query::QueryData),3824/// use a [`QueryBuilder`](crate::query::QueryBuilder) or [`QueryParamBuilder`](crate::system::QueryParamBuilder).3825/// The `FilteredEntityMut` must be the entire `QueryData`, and not nested inside a tuple with other data.3826///3827/// ```3828/// # use bevy_ecs::{prelude::*, world::FilteredEntityMut};3829/// #3830/// # #[derive(Component)]3831/// # struct A;3832/// #3833/// # let mut world = World::new();3834/// # world.spawn(A);3835/// #3836/// // This gives the `FilteredEntityMut` access to `&mut A`.3837/// let mut query = QueryBuilder::<FilteredEntityMut>::new(&mut world)3838/// .data::<&mut A>()3839/// .build();3840///3841/// let mut filtered_entity: FilteredEntityMut = query.single_mut(&mut world).unwrap();3842/// let component: Mut<A> = filtered_entity.get_mut().unwrap();3843/// ```3844pub struct FilteredEntityMut<'w, 's> {3845entity: UnsafeEntityCell<'w>,3846access: &'s Access,3847}38483849impl<'w, 's> FilteredEntityMut<'w, 's> {3850/// # Safety3851/// - No `&mut World` can exist from the underlying `UnsafeWorldCell`3852/// - If `access` takes read access to a component no mutable reference to that3853/// component can exist at the same time as the returned [`FilteredEntityMut`]3854/// - If `access` takes write access to a component, no reference to that component3855/// may exist at the same time as the returned [`FilteredEntityMut`]3856/// - If `access` takes any access for a component `entity` must have that component.3857#[inline]3858pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {3859Self { entity, access }3860}38613862/// Returns a new instance with a shorter lifetime.3863/// This is useful if you have `&mut FilteredEntityMut`, but you need `FilteredEntityMut`.3864pub fn reborrow(&mut self) -> FilteredEntityMut<'_, 's> {3865// SAFETY: We have exclusive access to the entire entity and its components.3866unsafe { Self::new(self.entity, self.access) }3867}38683869/// Gets read-only access to all of the entity's components.3870#[inline]3871pub fn as_readonly(&self) -> FilteredEntityRef<'_, 's> {3872FilteredEntityRef::from(self)3873}38743875/// Returns the [ID](Entity) of the current entity.3876#[inline]3877#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]3878pub fn id(&self) -> Entity {3879self.entity.id()3880}38813882/// Gets metadata indicating the location where the current entity is stored.3883#[inline]3884pub fn location(&self) -> EntityLocation {3885self.entity.location()3886}38873888/// Returns the archetype that the current entity belongs to.3889#[inline]3890pub fn archetype(&self) -> &Archetype {3891self.entity.archetype()3892}38933894/// Returns a reference to the underlying [`Access`].3895#[inline]3896pub fn access(&self) -> &Access {3897self.access3898}38993900/// Returns `true` if the current entity has a component of type `T`.3901/// Otherwise, this returns `false`.3902///3903/// ## Notes3904///3905/// If you do not know the concrete type of a component, consider using3906/// [`Self::contains_id`] or [`Self::contains_type_id`].3907#[inline]3908pub fn contains<T: Component>(&self) -> bool {3909self.contains_type_id(TypeId::of::<T>())3910}39113912/// Returns `true` if the current entity has a component identified by `component_id`.3913/// Otherwise, this returns false.3914///3915/// ## Notes3916///3917/// - If you know the concrete type of the component, you should prefer [`Self::contains`].3918/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using3919/// [`Self::contains_type_id`].3920#[inline]3921pub fn contains_id(&self, component_id: ComponentId) -> bool {3922self.entity.contains_id(component_id)3923}39243925/// Returns `true` if the current entity has a component with the type identified by `type_id`.3926/// Otherwise, this returns false.3927///3928/// ## Notes3929///3930/// - If you know the concrete type of the component, you should prefer [`Self::contains`].3931/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].3932#[inline]3933pub fn contains_type_id(&self, type_id: TypeId) -> bool {3934self.entity.contains_type_id(type_id)3935}39363937/// Gets access to the component of type `T` for the current entity.3938/// Returns `None` if the entity does not have a component of type `T`.3939#[inline]3940pub fn get<T: Component>(&self) -> Option<&'_ T> {3941self.as_readonly().get()3942}39433944/// Gets access to the component of type `T` for the current entity,3945/// including change detection information as a [`Ref`].3946///3947/// Returns `None` if the entity does not have a component of type `T`.3948#[inline]3949pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {3950self.as_readonly().get_ref()3951}39523953/// Gets mutable access to the component of type `T` for the current entity.3954/// Returns `None` if the entity does not have a component of type `T`.3955#[inline]3956pub fn get_mut<T: Component<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {3957let id = self3958.entity3959.world()3960.components()3961.get_valid_id(TypeId::of::<T>())?;3962self.access3963.has_component_write(id)3964// SAFETY: We have write access3965.then(|| unsafe { self.entity.get_mut() })3966.flatten()3967}39683969/// Consumes self and gets mutable access to the component of type `T`3970/// with the world `'w` lifetime for the current entity.3971/// Returns `None` if the entity does not have a component of type `T`.3972#[inline]3973pub fn into_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {3974// SAFETY:3975// - We have write access3976// - The bound `T: Component<Mutability = Mutable>` ensures the component is mutable3977unsafe { self.into_mut_assume_mutable() }3978}39793980/// Consumes self and gets mutable access to the component of type `T`3981/// with the world `'w` lifetime for the current entity.3982/// Returns `None` if the entity does not have a component of type `T`.3983///3984/// # Safety3985///3986/// - `T` must be a mutable component3987#[inline]3988pub unsafe fn into_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {3989let id = self3990.entity3991.world()3992.components()3993.get_valid_id(TypeId::of::<T>())?;3994self.access3995.has_component_write(id)3996// SAFETY:3997// - We have write access3998// - Caller ensures `T` is a mutable component3999.then(|| unsafe { self.entity.get_mut_assume_mutable() })4000.flatten()4001}40024003/// Retrieves the change ticks for the given component. This can be useful for implementing change4004/// detection in custom runtimes.4005#[inline]4006pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {4007self.as_readonly().get_change_ticks::<T>()4008}40094010/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change4011/// detection in custom runtimes.4012///4013/// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only4014/// use this in cases where the actual component types are not known at4015/// compile time.**4016#[inline]4017pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {4018self.as_readonly().get_change_ticks_by_id(component_id)4019}40204021/// Gets the component of the given [`ComponentId`] from the entity.4022///4023/// **You should prefer to use the typed API [`Self::get`] where possible and only4024/// use this in cases where the actual component types are not known at4025/// compile time.**4026///4027/// Unlike [`FilteredEntityMut::get`], this returns a raw pointer to the component,4028/// which is only valid while the [`FilteredEntityMut`] is alive.4029#[inline]4030pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'_>> {4031self.as_readonly().get_by_id(component_id)4032}40334034/// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.4035///4036/// **You should prefer to use the typed API [`Self::get_mut`] where possible and only4037/// use this in cases where the actual component types are not known at4038/// compile time.**4039///4040/// Unlike [`FilteredEntityMut::get_mut`], this returns a raw pointer to the component,4041/// which is only valid while the [`FilteredEntityMut`] is alive.4042#[inline]4043pub fn get_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {4044self.access4045.has_component_write(component_id)4046// SAFETY: We have write access4047.then(|| unsafe { self.entity.get_mut_by_id(component_id).ok() })4048.flatten()4049}40504051/// Returns the source code location from which this entity has last been spawned.4052pub fn spawned_by(&self) -> MaybeLocation {4053self.entity.spawned_by()4054}40554056/// Returns the [`Tick`] at which this entity has been spawned.4057pub fn spawn_tick(&self) -> Tick {4058self.entity.spawn_tick()4059}4060}40614062impl<'a> From<EntityMut<'a>> for FilteredEntityMut<'a, 'static> {4063fn from(entity: EntityMut<'a>) -> Self {4064// SAFETY:4065// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityMut`.4066unsafe { FilteredEntityMut::new(entity.cell, const { &Access::new_write_all() }) }4067}4068}40694070impl<'a> From<&'a mut EntityMut<'_>> for FilteredEntityMut<'a, 'static> {4071fn from(entity: &'a mut EntityMut<'_>) -> Self {4072// SAFETY:4073// - `EntityMut` guarantees exclusive access to all components in the new `FilteredEntityMut`.4074unsafe { FilteredEntityMut::new(entity.cell, const { &Access::new_write_all() }) }4075}4076}40774078impl<'a> From<EntityWorldMut<'a>> for FilteredEntityMut<'a, 'static> {4079fn from(entity: EntityWorldMut<'a>) -> Self {4080// SAFETY:4081// - `EntityWorldMut` guarantees exclusive access to the entire world.4082unsafe {4083FilteredEntityMut::new(4084entity.into_unsafe_entity_cell(),4085const { &Access::new_write_all() },4086)4087}4088}4089}40904091impl<'a> From<&'a mut EntityWorldMut<'_>> for FilteredEntityMut<'a, 'static> {4092fn from(entity: &'a mut EntityWorldMut<'_>) -> Self {4093// SAFETY:4094// - `EntityWorldMut` guarantees exclusive access to the entire world.4095unsafe {4096FilteredEntityMut::new(4097entity.as_unsafe_entity_cell(),4098const { &Access::new_write_all() },4099)4100}4101}4102}41034104impl<'w, 's, B: Bundle> From<&'w EntityMutExcept<'_, 's, B>> for FilteredEntityMut<'w, 's> {4105fn from(value: &'w EntityMutExcept<'_, 's, B>) -> Self {4106// SAFETY:4107// - The FilteredEntityMut has the same component access as the given EntityMutExcept.4108unsafe { FilteredEntityMut::new(value.entity, value.access) }4109}4110}41114112impl PartialEq for FilteredEntityMut<'_, '_> {4113fn eq(&self, other: &Self) -> bool {4114self.entity() == other.entity()4115}4116}41174118impl Eq for FilteredEntityMut<'_, '_> {}41194120impl PartialOrd for FilteredEntityMut<'_, '_> {4121/// [`FilteredEntityMut`]'s comparison trait implementations match the underlying [`Entity`],4122/// and cannot discern between different worlds.4123fn partial_cmp(&self, other: &Self) -> Option<Ordering> {4124Some(self.cmp(other))4125}4126}41274128impl Ord for FilteredEntityMut<'_, '_> {4129fn cmp(&self, other: &Self) -> Ordering {4130self.entity().cmp(&other.entity())4131}4132}41334134impl Hash for FilteredEntityMut<'_, '_> {4135fn hash<H: Hasher>(&self, state: &mut H) {4136self.entity().hash(state);4137}4138}41394140impl ContainsEntity for FilteredEntityMut<'_, '_> {4141fn entity(&self) -> Entity {4142self.id()4143}4144}41454146// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.4147unsafe impl EntityEquivalent for FilteredEntityMut<'_, '_> {}41484149/// Error type returned by [`TryFrom`] conversions from filtered entity types4150/// ([`FilteredEntityRef`]/[`FilteredEntityMut`]) to full-access entity types4151/// ([`EntityRef`]/[`EntityMut`]).4152#[derive(Error, Debug)]4153pub enum TryFromFilteredError {4154/// Error indicating that the filtered entity does not have read access to4155/// all components.4156#[error("Conversion failed, filtered entity ref does not have read access to all components")]4157MissingReadAllAccess,4158/// Error indicating that the filtered entity does not have write access to4159/// all components.4160#[error("Conversion failed, filtered entity ref does not have write access to all components")]4161MissingWriteAllAccess,4162}41634164/// Provides read-only access to a single entity and all its components, save4165/// for an explicitly-enumerated set.4166pub struct EntityRefExcept<'w, 's, B>4167where4168B: Bundle,4169{4170entity: UnsafeEntityCell<'w>,4171access: &'s Access,4172phantom: PhantomData<B>,4173}41744175impl<'w, 's, B> EntityRefExcept<'w, 's, B>4176where4177B: Bundle,4178{4179/// # Safety4180/// Other users of `UnsafeEntityCell` must only have mutable access to the components in `B`.4181pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {4182Self {4183entity,4184access,4185phantom: PhantomData,4186}4187}41884189/// Returns the [ID](Entity) of the current entity.4190#[inline]4191#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]4192pub fn id(&self) -> Entity {4193self.entity.id()4194}41954196/// Gets access to the component of type `C` for the current entity. Returns4197/// `None` if the component doesn't have a component of that type or if the4198/// type is one of the excluded components.4199#[inline]4200pub fn get<C>(&self) -> Option<&'w C>4201where4202C: Component,4203{4204let components = self.entity.world().components();4205let id = components.valid_component_id::<C>()?;4206if bundle_contains_component::<B>(components, id) {4207None4208} else {4209// SAFETY: We have read access for all components that weren't4210// covered by the `contains` check above.4211unsafe { self.entity.get() }4212}4213}42144215/// Gets access to the component of type `C` for the current entity,4216/// including change detection information. Returns `None` if the component4217/// doesn't have a component of that type or if the type is one of the4218/// excluded components.4219#[inline]4220pub fn get_ref<C>(&self) -> Option<Ref<'w, C>>4221where4222C: Component,4223{4224let components = self.entity.world().components();4225let id = components.valid_component_id::<C>()?;4226if bundle_contains_component::<B>(components, id) {4227None4228} else {4229// SAFETY: We have read access for all components that weren't4230// covered by the `contains` check above.4231unsafe { self.entity.get_ref() }4232}4233}42344235/// Returns the source code location from which this entity has been spawned.4236pub fn spawned_by(&self) -> MaybeLocation {4237self.entity.spawned_by()4238}42394240/// Returns the [`Tick`] at which this entity has been spawned.4241pub fn spawn_tick(&self) -> Tick {4242self.entity.spawn_tick()4243}42444245/// Gets the component of the given [`ComponentId`] from the entity.4246///4247/// **You should prefer to use the typed API [`Self::get`] where possible and only4248/// use this in cases where the actual component types are not known at4249/// compile time.**4250///4251/// Unlike [`EntityRefExcept::get`], this returns a raw pointer to the component,4252/// which is only valid while the [`EntityRefExcept`] is alive.4253#[inline]4254pub fn get_by_id(&self, component_id: ComponentId) -> Option<Ptr<'w>> {4255let components = self.entity.world().components();4256(!bundle_contains_component::<B>(components, component_id))4257.then(|| {4258// SAFETY: We have read access for this component4259unsafe { self.entity.get_by_id(component_id) }4260})4261.flatten()4262}42634264/// Returns `true` if the current entity has a component of type `T`.4265/// Otherwise, this returns `false`.4266///4267/// ## Notes4268///4269/// If you do not know the concrete type of a component, consider using4270/// [`Self::contains_id`] or [`Self::contains_type_id`].4271#[inline]4272pub fn contains<T: Component>(&self) -> bool {4273self.contains_type_id(TypeId::of::<T>())4274}42754276/// Returns `true` if the current entity has a component identified by `component_id`.4277/// Otherwise, this returns false.4278///4279/// ## Notes4280///4281/// - If you know the concrete type of the component, you should prefer [`Self::contains`].4282/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using4283/// [`Self::contains_type_id`].4284#[inline]4285pub fn contains_id(&self, component_id: ComponentId) -> bool {4286self.entity.contains_id(component_id)4287}42884289/// Returns `true` if the current entity has a component with the type identified by `type_id`.4290/// Otherwise, this returns false.4291///4292/// ## Notes4293///4294/// - If you know the concrete type of the component, you should prefer [`Self::contains`].4295/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].4296#[inline]4297pub fn contains_type_id(&self, type_id: TypeId) -> bool {4298self.entity.contains_type_id(type_id)4299}43004301/// Retrieves the change ticks for the given component. This can be useful for implementing change4302/// detection in custom runtimes.4303#[inline]4304pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {4305let component_id = self4306.entity4307.world()4308.components()4309.get_valid_id(TypeId::of::<T>())?;4310let components = self.entity.world().components();4311(!bundle_contains_component::<B>(components, component_id))4312.then(|| {4313// SAFETY: We have read access4314unsafe { self.entity.get_change_ticks::<T>() }4315})4316.flatten()4317}43184319/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change4320/// detection in custom runtimes.4321///4322/// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only4323/// use this in cases where the actual component types are not known at4324/// compile time.**4325#[inline]4326pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {4327let components = self.entity.world().components();4328(!bundle_contains_component::<B>(components, component_id))4329.then(|| {4330// SAFETY: We have read access4331unsafe { self.entity.get_change_ticks_by_id(component_id) }4332})4333.flatten()4334}4335}43364337impl<'w, 's, B> From<&'w EntityMutExcept<'_, 's, B>> for EntityRefExcept<'w, 's, B>4338where4339B: Bundle,4340{4341fn from(entity: &'w EntityMutExcept<'_, 's, B>) -> Self {4342// SAFETY: All accesses that `EntityRefExcept` provides are also4343// accesses that `EntityMutExcept` provides.4344unsafe { EntityRefExcept::new(entity.entity, entity.access) }4345}4346}43474348impl<B: Bundle> Clone for EntityRefExcept<'_, '_, B> {4349fn clone(&self) -> Self {4350*self4351}4352}43534354impl<B: Bundle> Copy for EntityRefExcept<'_, '_, B> {}43554356impl<B: Bundle> PartialEq for EntityRefExcept<'_, '_, B> {4357fn eq(&self, other: &Self) -> bool {4358self.entity() == other.entity()4359}4360}43614362impl<B: Bundle> Eq for EntityRefExcept<'_, '_, B> {}43634364impl<B: Bundle> PartialOrd for EntityRefExcept<'_, '_, B> {4365/// [`EntityRefExcept`]'s comparison trait implementations match the underlying [`Entity`],4366/// and cannot discern between different worlds.4367fn partial_cmp(&self, other: &Self) -> Option<Ordering> {4368Some(self.cmp(other))4369}4370}43714372impl<B: Bundle> Ord for EntityRefExcept<'_, '_, B> {4373fn cmp(&self, other: &Self) -> Ordering {4374self.entity().cmp(&other.entity())4375}4376}43774378impl<B: Bundle> Hash for EntityRefExcept<'_, '_, B> {4379fn hash<H: Hasher>(&self, state: &mut H) {4380self.entity().hash(state);4381}4382}43834384impl<B: Bundle> ContainsEntity for EntityRefExcept<'_, '_, B> {4385fn entity(&self) -> Entity {4386self.id()4387}4388}43894390// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.4391unsafe impl<B: Bundle> EntityEquivalent for EntityRefExcept<'_, '_, B> {}43924393/// Provides mutable access to all components of an entity, with the exception4394/// of an explicit set.4395///4396/// This is a rather niche type that should only be used if you need access to4397/// *all* components of an entity, while still allowing you to consult other4398/// queries that might match entities that this query also matches. If you don't4399/// need access to all components, prefer a standard query with a4400/// [`Without`](`crate::query::Without`) filter.4401pub struct EntityMutExcept<'w, 's, B>4402where4403B: Bundle,4404{4405entity: UnsafeEntityCell<'w>,4406access: &'s Access,4407phantom: PhantomData<B>,4408}44094410impl<'w, 's, B> EntityMutExcept<'w, 's, B>4411where4412B: Bundle,4413{4414/// # Safety4415/// Other users of `UnsafeEntityCell` must not have access to any components not in `B`.4416pub(crate) unsafe fn new(entity: UnsafeEntityCell<'w>, access: &'s Access) -> Self {4417Self {4418entity,4419access,4420phantom: PhantomData,4421}4422}44234424/// Returns the [ID](Entity) of the current entity.4425#[inline]4426#[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]4427pub fn id(&self) -> Entity {4428self.entity.id()4429}44304431/// Returns a new instance with a shorter lifetime.4432///4433/// This is useful if you have `&mut EntityMutExcept`, but you need4434/// `EntityMutExcept`.4435pub fn reborrow(&mut self) -> EntityMutExcept<'_, 's, B> {4436// SAFETY: We have exclusive access to the entire entity and the4437// applicable components.4438unsafe { Self::new(self.entity, self.access) }4439}44404441/// Gets read-only access to all of the entity's components, except for the4442/// ones in `CL`.4443#[inline]4444pub fn as_readonly(&self) -> EntityRefExcept<'_, 's, B> {4445EntityRefExcept::from(self)4446}44474448/// Gets access to the component of type `C` for the current entity. Returns4449/// `None` if the component doesn't have a component of that type or if the4450/// type is one of the excluded components.4451#[inline]4452pub fn get<C>(&self) -> Option<&'_ C>4453where4454C: Component,4455{4456self.as_readonly().get()4457}44584459/// Gets access to the component of type `C` for the current entity,4460/// including change detection information. Returns `None` if the component4461/// doesn't have a component of that type or if the type is one of the4462/// excluded components.4463#[inline]4464pub fn get_ref<C>(&self) -> Option<Ref<'_, C>>4465where4466C: Component,4467{4468self.as_readonly().get_ref()4469}44704471/// Gets mutable access to the component of type `C` for the current entity.4472/// Returns `None` if the component doesn't have a component of that type or4473/// if the type is one of the excluded components.4474#[inline]4475pub fn get_mut<C>(&mut self) -> Option<Mut<'_, C>>4476where4477C: Component<Mutability = Mutable>,4478{4479let components = self.entity.world().components();4480let id = components.valid_component_id::<C>()?;4481if bundle_contains_component::<B>(components, id) {4482None4483} else {4484// SAFETY: We have write access for all components that weren't4485// covered by the `contains` check above.4486unsafe { self.entity.get_mut() }4487}4488}44894490/// Returns the source code location from which this entity has been spawned.4491pub fn spawned_by(&self) -> MaybeLocation {4492self.entity.spawned_by()4493}44944495/// Returns the [`Tick`] at which this entity has been spawned.4496pub fn spawn_tick(&self) -> Tick {4497self.entity.spawn_tick()4498}44994500/// Returns `true` if the current entity has a component of type `T`.4501/// Otherwise, this returns `false`.4502///4503/// ## Notes4504///4505/// If you do not know the concrete type of a component, consider using4506/// [`Self::contains_id`] or [`Self::contains_type_id`].4507#[inline]4508pub fn contains<T: Component>(&self) -> bool {4509self.contains_type_id(TypeId::of::<T>())4510}45114512/// Returns `true` if the current entity has a component identified by `component_id`.4513/// Otherwise, this returns false.4514///4515/// ## Notes4516///4517/// - If you know the concrete type of the component, you should prefer [`Self::contains`].4518/// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using4519/// [`Self::contains_type_id`].4520#[inline]4521pub fn contains_id(&self, component_id: ComponentId) -> bool {4522self.entity.contains_id(component_id)4523}45244525/// Returns `true` if the current entity has a component with the type identified by `type_id`.4526/// Otherwise, this returns false.4527///4528/// ## Notes4529///4530/// - If you know the concrete type of the component, you should prefer [`Self::contains`].4531/// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].4532#[inline]4533pub fn contains_type_id(&self, type_id: TypeId) -> bool {4534self.entity.contains_type_id(type_id)4535}45364537/// Gets the component of the given [`ComponentId`] from the entity.4538///4539/// **You should prefer to use the typed API [`Self::get`] where possible and only4540/// use this in cases where the actual component types are not known at4541/// compile time.**4542///4543/// Unlike [`EntityMutExcept::get`], this returns a raw pointer to the component,4544/// which is only valid while the [`EntityMutExcept`] is alive.4545#[inline]4546pub fn get_by_id(&'w self, component_id: ComponentId) -> Option<Ptr<'w>> {4547self.as_readonly().get_by_id(component_id)4548}45494550/// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.4551///4552/// **You should prefer to use the typed API [`Self::get_mut`] where possible and only4553/// use this in cases where the actual component types are not known at4554/// compile time.**4555///4556/// Unlike [`EntityMutExcept::get_mut`], this returns a raw pointer to the component,4557/// which is only valid while the [`EntityMutExcept`] is alive.4558#[inline]4559pub fn get_mut_by_id<F: DynamicComponentFetch>(4560&mut self,4561component_id: ComponentId,4562) -> Option<MutUntyped<'_>> {4563let components = self.entity.world().components();4564(!bundle_contains_component::<B>(components, component_id))4565.then(|| {4566// SAFETY: We have write access4567unsafe { self.entity.get_mut_by_id(component_id).ok() }4568})4569.flatten()4570}4571}45724573impl<B: Bundle> PartialEq for EntityMutExcept<'_, '_, B> {4574fn eq(&self, other: &Self) -> bool {4575self.entity() == other.entity()4576}4577}45784579impl<B: Bundle> Eq for EntityMutExcept<'_, '_, B> {}45804581impl<B: Bundle> PartialOrd for EntityMutExcept<'_, '_, B> {4582/// [`EntityMutExcept`]'s comparison trait implementations match the underlying [`Entity`],4583/// and cannot discern between different worlds.4584fn partial_cmp(&self, other: &Self) -> Option<Ordering> {4585Some(self.cmp(other))4586}4587}45884589impl<B: Bundle> Ord for EntityMutExcept<'_, '_, B> {4590fn cmp(&self, other: &Self) -> Ordering {4591self.entity().cmp(&other.entity())4592}4593}45944595impl<B: Bundle> Hash for EntityMutExcept<'_, '_, B> {4596fn hash<H: Hasher>(&self, state: &mut H) {4597self.entity().hash(state);4598}4599}46004601impl<B: Bundle> ContainsEntity for EntityMutExcept<'_, '_, B> {4602fn entity(&self) -> Entity {4603self.id()4604}4605}46064607// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.4608unsafe impl<B: Bundle> EntityEquivalent for EntityMutExcept<'_, '_, B> {}46094610fn bundle_contains_component<B>(components: &Components, query_id: ComponentId) -> bool4611where4612B: Bundle,4613{4614let mut found = false;4615B::get_component_ids(components, &mut |maybe_id| {4616if let Some(id) = maybe_id {4617found = found || id == query_id;4618}4619});4620found4621}46224623/// Inserts a dynamic [`Bundle`] into the entity.4624///4625/// # Safety4626///4627/// - [`OwningPtr`] and [`StorageType`] iterators must correspond to the4628/// [`BundleInfo`](crate::bundle::BundleInfo) used to construct [`BundleInserter`]4629/// - [`Entity`] must correspond to [`EntityLocation`]4630unsafe fn insert_dynamic_bundle<4631'a,4632I: Iterator<Item = OwningPtr<'a>>,4633S: Iterator<Item = StorageType>,4634>(4635mut bundle_inserter: BundleInserter<'_>,4636entity: Entity,4637location: EntityLocation,4638components: I,4639storage_types: S,4640mode: InsertMode,4641caller: MaybeLocation,4642relationship_hook_insert_mode: RelationshipHookMode,4643) -> EntityLocation {4644struct DynamicInsertBundle<'a, I: Iterator<Item = (StorageType, OwningPtr<'a>)>> {4645components: I,4646}46474648impl<'a, I: Iterator<Item = (StorageType, OwningPtr<'a>)>> DynamicBundle4649for DynamicInsertBundle<'a, I>4650{4651type Effect = ();4652unsafe fn get_components(4653mut ptr: MovingPtr<'_, Self>,4654func: &mut impl FnMut(StorageType, OwningPtr<'_>),4655) {4656(&mut ptr.components).for_each(|(t, ptr)| func(t, ptr));4657}46584659unsafe fn apply_effect(4660_ptr: MovingPtr<'_, MaybeUninit<Self>>,4661_entity: &mut EntityWorldMut,4662) {4663}4664}46654666let bundle = DynamicInsertBundle {4667components: storage_types.zip(components),4668};46694670move_as_ptr!(bundle);46714672// SAFETY:4673// - `location` matches `entity`. and thus must currently exist in the source4674// archetype for this inserter and its location within the archetype.4675// - The caller must ensure that the iterators and storage types match up with the `BundleInserter`4676// - `apply_effect` is never called on this bundle.4677// - `bundle` is not used or dropped after this point.4678unsafe {4679bundle_inserter.insert(4680entity,4681location,4682bundle,4683mode,4684caller,4685relationship_hook_insert_mode,4686)4687}4688}46894690/// Types that can be used to fetch components from an entity dynamically by4691/// [`ComponentId`]s.4692///4693/// Provided implementations are:4694/// - [`ComponentId`]: Returns a single untyped reference.4695/// - `[ComponentId; N]` and `&[ComponentId; N]`: Returns a same-sized array of untyped references.4696/// - `&[ComponentId]`: Returns a [`Vec`] of untyped references.4697/// - [`&HashSet<ComponentId>`](HashSet): Returns a [`HashMap`] of IDs to untyped references.4698///4699/// # Performance4700///4701/// - The slice and array implementations perform an aliased mutability check in4702/// [`DynamicComponentFetch::fetch_mut`] that is `O(N^2)`.4703/// - The [`HashSet`] implementation performs no such check as the type itself4704/// guarantees unique IDs.4705/// - The single [`ComponentId`] implementation performs no such check as only4706/// one reference is returned.4707///4708/// # Safety4709///4710/// Implementor must ensure that:4711/// - No aliased mutability is caused by the returned references.4712/// - [`DynamicComponentFetch::fetch_ref`] returns only read-only references.4713pub unsafe trait DynamicComponentFetch {4714/// The read-only reference type returned by [`DynamicComponentFetch::fetch_ref`].4715type Ref<'w>;47164717/// The mutable reference type returned by [`DynamicComponentFetch::fetch_mut`].4718type Mut<'w>;47194720/// Returns untyped read-only reference(s) to the component(s) with the4721/// given [`ComponentId`]s, as determined by `self`.4722///4723/// # Safety4724///4725/// It is the caller's responsibility to ensure that:4726/// - The given [`UnsafeEntityCell`] has read-only access to the fetched components.4727/// - No other mutable references to the fetched components exist at the same time.4728///4729/// # Errors4730///4731/// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.4732unsafe fn fetch_ref(4733self,4734cell: UnsafeEntityCell<'_>,4735) -> Result<Self::Ref<'_>, EntityComponentError>;47364737/// Returns untyped mutable reference(s) to the component(s) with the4738/// given [`ComponentId`]s, as determined by `self`.4739///4740/// # Safety4741///4742/// It is the caller's responsibility to ensure that:4743/// - The given [`UnsafeEntityCell`] has mutable access to the fetched components.4744/// - No other references to the fetched components exist at the same time.4745///4746/// # Errors4747///4748/// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.4749/// - Returns [`EntityComponentError::AliasedMutability`] if a component is requested multiple times.4750unsafe fn fetch_mut(4751self,4752cell: UnsafeEntityCell<'_>,4753) -> Result<Self::Mut<'_>, EntityComponentError>;47544755/// Returns untyped mutable reference(s) to the component(s) with the4756/// given [`ComponentId`]s, as determined by `self`.4757/// Assumes all [`ComponentId`]s refer to mutable components.4758///4759/// # Safety4760///4761/// It is the caller's responsibility to ensure that:4762/// - The given [`UnsafeEntityCell`] has mutable access to the fetched components.4763/// - No other references to the fetched components exist at the same time.4764/// - The requested components are all mutable.4765///4766/// # Errors4767///4768/// - Returns [`EntityComponentError::MissingComponent`] if a component is missing from the entity.4769/// - Returns [`EntityComponentError::AliasedMutability`] if a component is requested multiple times.4770unsafe fn fetch_mut_assume_mutable(4771self,4772cell: UnsafeEntityCell<'_>,4773) -> Result<Self::Mut<'_>, EntityComponentError>;4774}47754776// SAFETY:4777// - No aliased mutability is caused because a single reference is returned.4778// - No mutable references are returned by `fetch_ref`.4779unsafe impl DynamicComponentFetch for ComponentId {4780type Ref<'w> = Ptr<'w>;4781type Mut<'w> = MutUntyped<'w>;47824783unsafe fn fetch_ref(4784self,4785cell: UnsafeEntityCell<'_>,4786) -> Result<Self::Ref<'_>, EntityComponentError> {4787// SAFETY: caller ensures that the cell has read access to the component.4788unsafe { cell.get_by_id(self) }.ok_or(EntityComponentError::MissingComponent(self))4789}47904791unsafe fn fetch_mut(4792self,4793cell: UnsafeEntityCell<'_>,4794) -> Result<Self::Mut<'_>, EntityComponentError> {4795// SAFETY: caller ensures that the cell has mutable access to the component.4796unsafe { cell.get_mut_by_id(self) }4797.map_err(|_| EntityComponentError::MissingComponent(self))4798}47994800unsafe fn fetch_mut_assume_mutable(4801self,4802cell: UnsafeEntityCell<'_>,4803) -> Result<Self::Mut<'_>, EntityComponentError> {4804// SAFETY: caller ensures that the cell has mutable access to the component.4805unsafe { cell.get_mut_assume_mutable_by_id(self) }4806.map_err(|_| EntityComponentError::MissingComponent(self))4807}4808}48094810// SAFETY:4811// - No aliased mutability is caused because the array is checked for duplicates.4812// - No mutable references are returned by `fetch_ref`.4813unsafe impl<const N: usize> DynamicComponentFetch for [ComponentId; N] {4814type Ref<'w> = [Ptr<'w>; N];4815type Mut<'w> = [MutUntyped<'w>; N];48164817unsafe fn fetch_ref(4818self,4819cell: UnsafeEntityCell<'_>,4820) -> Result<Self::Ref<'_>, EntityComponentError> {4821<&Self>::fetch_ref(&self, cell)4822}48234824unsafe fn fetch_mut(4825self,4826cell: UnsafeEntityCell<'_>,4827) -> Result<Self::Mut<'_>, EntityComponentError> {4828<&Self>::fetch_mut(&self, cell)4829}48304831unsafe fn fetch_mut_assume_mutable(4832self,4833cell: UnsafeEntityCell<'_>,4834) -> Result<Self::Mut<'_>, EntityComponentError> {4835<&Self>::fetch_mut_assume_mutable(&self, cell)4836}4837}48384839// SAFETY:4840// - No aliased mutability is caused because the array is checked for duplicates.4841// - No mutable references are returned by `fetch_ref`.4842unsafe impl<const N: usize> DynamicComponentFetch for &'_ [ComponentId; N] {4843type Ref<'w> = [Ptr<'w>; N];4844type Mut<'w> = [MutUntyped<'w>; N];48454846unsafe fn fetch_ref(4847self,4848cell: UnsafeEntityCell<'_>,4849) -> Result<Self::Ref<'_>, EntityComponentError> {4850let mut ptrs = [const { MaybeUninit::uninit() }; N];4851for (ptr, &id) in core::iter::zip(&mut ptrs, self) {4852*ptr = MaybeUninit::new(4853// SAFETY: caller ensures that the cell has read access to the component.4854unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,4855);4856}48574858// SAFETY: Each ptr was initialized in the loop above.4859let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });48604861Ok(ptrs)4862}48634864unsafe fn fetch_mut(4865self,4866cell: UnsafeEntityCell<'_>,4867) -> Result<Self::Mut<'_>, EntityComponentError> {4868// Check for duplicate component IDs.4869for i in 0..self.len() {4870for j in 0..i {4871if self[i] == self[j] {4872return Err(EntityComponentError::AliasedMutability(self[i]));4873}4874}4875}48764877let mut ptrs = [const { MaybeUninit::uninit() }; N];4878for (ptr, &id) in core::iter::zip(&mut ptrs, self) {4879*ptr = MaybeUninit::new(4880// SAFETY: caller ensures that the cell has mutable access to the component.4881unsafe { cell.get_mut_by_id(id) }4882.map_err(|_| EntityComponentError::MissingComponent(id))?,4883);4884}48854886// SAFETY: Each ptr was initialized in the loop above.4887let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });48884889Ok(ptrs)4890}48914892unsafe fn fetch_mut_assume_mutable(4893self,4894cell: UnsafeEntityCell<'_>,4895) -> Result<Self::Mut<'_>, EntityComponentError> {4896// Check for duplicate component IDs.4897for i in 0..self.len() {4898for j in 0..i {4899if self[i] == self[j] {4900return Err(EntityComponentError::AliasedMutability(self[i]));4901}4902}4903}49044905let mut ptrs = [const { MaybeUninit::uninit() }; N];4906for (ptr, &id) in core::iter::zip(&mut ptrs, self) {4907*ptr = MaybeUninit::new(4908// SAFETY: caller ensures that the cell has mutable access to the component.4909unsafe { cell.get_mut_assume_mutable_by_id(id) }4910.map_err(|_| EntityComponentError::MissingComponent(id))?,4911);4912}49134914// SAFETY: Each ptr was initialized in the loop above.4915let ptrs = ptrs.map(|ptr| unsafe { MaybeUninit::assume_init(ptr) });49164917Ok(ptrs)4918}4919}49204921// SAFETY:4922// - No aliased mutability is caused because the slice is checked for duplicates.4923// - No mutable references are returned by `fetch_ref`.4924unsafe impl DynamicComponentFetch for &'_ [ComponentId] {4925type Ref<'w> = Vec<Ptr<'w>>;4926type Mut<'w> = Vec<MutUntyped<'w>>;49274928unsafe fn fetch_ref(4929self,4930cell: UnsafeEntityCell<'_>,4931) -> Result<Self::Ref<'_>, EntityComponentError> {4932let mut ptrs = Vec::with_capacity(self.len());4933for &id in self {4934ptrs.push(4935// SAFETY: caller ensures that the cell has read access to the component.4936unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,4937);4938}4939Ok(ptrs)4940}49414942unsafe fn fetch_mut(4943self,4944cell: UnsafeEntityCell<'_>,4945) -> Result<Self::Mut<'_>, EntityComponentError> {4946// Check for duplicate component IDs.4947for i in 0..self.len() {4948for j in 0..i {4949if self[i] == self[j] {4950return Err(EntityComponentError::AliasedMutability(self[i]));4951}4952}4953}49544955let mut ptrs = Vec::with_capacity(self.len());4956for &id in self {4957ptrs.push(4958// SAFETY: caller ensures that the cell has mutable access to the component.4959unsafe { cell.get_mut_by_id(id) }4960.map_err(|_| EntityComponentError::MissingComponent(id))?,4961);4962}4963Ok(ptrs)4964}49654966unsafe fn fetch_mut_assume_mutable(4967self,4968cell: UnsafeEntityCell<'_>,4969) -> Result<Self::Mut<'_>, EntityComponentError> {4970// Check for duplicate component IDs.4971for i in 0..self.len() {4972for j in 0..i {4973if self[i] == self[j] {4974return Err(EntityComponentError::AliasedMutability(self[i]));4975}4976}4977}49784979let mut ptrs = Vec::with_capacity(self.len());4980for &id in self {4981ptrs.push(4982// SAFETY: caller ensures that the cell has mutable access to the component.4983unsafe { cell.get_mut_assume_mutable_by_id(id) }4984.map_err(|_| EntityComponentError::MissingComponent(id))?,4985);4986}4987Ok(ptrs)4988}4989}49904991// SAFETY:4992// - No aliased mutability is caused because `HashSet` guarantees unique elements.4993// - No mutable references are returned by `fetch_ref`.4994unsafe impl DynamicComponentFetch for &'_ HashSet<ComponentId> {4995type Ref<'w> = HashMap<ComponentId, Ptr<'w>>;4996type Mut<'w> = HashMap<ComponentId, MutUntyped<'w>>;49974998unsafe fn fetch_ref(4999self,5000cell: UnsafeEntityCell<'_>,5001) -> Result<Self::Ref<'_>, EntityComponentError> {5002let mut ptrs = HashMap::with_capacity_and_hasher(self.len(), Default::default());5003for &id in self {5004ptrs.insert(5005id,5006// SAFETY: caller ensures that the cell has read access to the component.5007unsafe { cell.get_by_id(id) }.ok_or(EntityComponentError::MissingComponent(id))?,5008);5009}5010Ok(ptrs)5011}50125013unsafe fn fetch_mut(5014self,5015cell: UnsafeEntityCell<'_>,5016) -> Result<Self::Mut<'_>, EntityComponentError> {5017let mut ptrs = HashMap::with_capacity_and_hasher(self.len(), Default::default());5018for &id in self {5019ptrs.insert(5020id,5021// SAFETY: caller ensures that the cell has mutable access to the component.5022unsafe { cell.get_mut_by_id(id) }5023.map_err(|_| EntityComponentError::MissingComponent(id))?,5024);5025}5026Ok(ptrs)5027}50285029unsafe fn fetch_mut_assume_mutable(5030self,5031cell: UnsafeEntityCell<'_>,5032) -> Result<Self::Mut<'_>, EntityComponentError> {5033let mut ptrs = HashMap::with_capacity_and_hasher(self.len(), Default::default());5034for &id in self {5035ptrs.insert(5036id,5037// SAFETY: caller ensures that the cell has mutable access to the component.5038unsafe { cell.get_mut_assume_mutable_by_id(id) }5039.map_err(|_| EntityComponentError::MissingComponent(id))?,5040);5041}5042Ok(ptrs)5043}5044}50455046#[cfg(test)]5047mod tests {5048use alloc::{vec, vec::Vec};5049use bevy_ptr::{OwningPtr, Ptr};5050use core::panic::AssertUnwindSafe;5051use std::sync::OnceLock;50525053use crate::component::Tick;5054use crate::lifecycle::HookContext;5055use crate::{5056change_detection::{MaybeLocation, MutUntyped},5057component::ComponentId,5058prelude::*,5059system::{assert_is_system, RunSystemOnce as _},5060world::{error::EntityComponentError, DeferredWorld, FilteredEntityMut, FilteredEntityRef},5061};50625063use super::{EntityMutExcept, EntityRefExcept};50645065#[derive(Component, Clone, Copy, Debug, PartialEq)]5066struct TestComponent(u32);50675068#[derive(Component, Clone, Copy, Debug, PartialEq)]5069#[component(storage = "SparseSet")]5070struct TestComponent2(u32);50715072#[test]5073fn entity_ref_get_by_id() {5074let mut world = World::new();5075let entity = world.spawn(TestComponent(42)).id();5076let component_id = world5077.components()5078.get_valid_id(core::any::TypeId::of::<TestComponent>())5079.unwrap();50805081let entity = world.entity(entity);5082let test_component = entity.get_by_id(component_id).unwrap();5083// SAFETY: points to a valid `TestComponent`5084let test_component = unsafe { test_component.deref::<TestComponent>() };50855086assert_eq!(test_component.0, 42);5087}50885089#[test]5090fn entity_mut_get_by_id() {5091let mut world = World::new();5092let entity = world.spawn(TestComponent(42)).id();5093let component_id = world5094.components()5095.get_valid_id(core::any::TypeId::of::<TestComponent>())5096.unwrap();50975098let mut entity_mut = world.entity_mut(entity);5099let mut test_component = entity_mut.get_mut_by_id(component_id).unwrap();5100{5101test_component.set_changed();5102let test_component =5103// SAFETY: `test_component` has unique access of the `EntityWorldMut` and is not used afterwards5104unsafe { test_component.into_inner().deref_mut::<TestComponent>() };5105test_component.0 = 43;5106}51075108let entity = world.entity(entity);5109let test_component = entity.get_by_id(component_id).unwrap();5110// SAFETY: `TestComponent` is the correct component type5111let test_component = unsafe { test_component.deref::<TestComponent>() };51125113assert_eq!(test_component.0, 43);5114}51155116#[test]5117fn entity_ref_get_by_id_invalid_component_id() {5118let invalid_component_id = ComponentId::new(usize::MAX);51195120let mut world = World::new();5121let entity = world.spawn_empty().id();5122let entity = world.entity(entity);5123assert!(entity.get_by_id(invalid_component_id).is_err());5124}51255126#[test]5127fn entity_mut_get_by_id_invalid_component_id() {5128let invalid_component_id = ComponentId::new(usize::MAX);51295130let mut world = World::new();5131let mut entity = world.spawn_empty();5132assert!(entity.get_by_id(invalid_component_id).is_err());5133assert!(entity.get_mut_by_id(invalid_component_id).is_err());5134}51355136#[derive(Resource)]5137struct R(usize);51385139#[test]5140fn entity_mut_resource_scope() {5141// Keep in sync with the `resource_scope` test in lib.rs5142let mut world = World::new();5143let mut entity = world.spawn_empty();51445145assert!(entity.try_resource_scope::<R, _>(|_, _| {}).is_none());5146entity.world_scope(|world| world.insert_resource(R(0)));5147entity.resource_scope(|entity: &mut EntityWorldMut, mut value: Mut<R>| {5148value.0 += 1;5149assert!(!entity.world().contains_resource::<R>());5150});5151assert_eq!(entity.resource::<R>().0, 1);5152}51535154#[test]5155fn entity_mut_resource_scope_panic() {5156let mut world = World::new();5157world.insert_resource(R(0));51585159let mut entity = world.spawn_empty();5160let old_location = entity.location();5161let result = std::panic::catch_unwind(AssertUnwindSafe(|| {5162entity.resource_scope(|entity: &mut EntityWorldMut, _: Mut<R>| {5163// Change the entity's `EntityLocation`.5164entity.insert(TestComponent(0));51655166// Ensure that the entity location still gets updated even in case of a panic.5167panic!("this should get caught by the outer scope")5168});5169}));5170assert!(result.is_err());51715172// Ensure that the location has been properly updated.5173assert_ne!(entity.location(), old_location);5174}51755176// regression test for https://github.com/bevyengine/bevy/pull/73875177#[test]5178fn entity_mut_world_scope_panic() {5179let mut world = World::new();51805181let mut entity = world.spawn_empty();5182let old_location = entity.location();5183let id = entity.id();5184let res = std::panic::catch_unwind(AssertUnwindSafe(|| {5185entity.world_scope(|w| {5186// Change the entity's `EntityLocation`, which invalidates the original `EntityWorldMut`.5187// This will get updated at the end of the scope.5188w.entity_mut(id).insert(TestComponent(0));51895190// Ensure that the entity location still gets updated even in case of a panic.5191panic!("this should get caught by the outer scope")5192});5193}));5194assert!(res.is_err());51955196// Ensure that the location has been properly updated.5197assert_ne!(entity.location(), old_location);5198}51995200#[test]5201fn entity_mut_reborrow_scope_panic() {5202let mut world = World::new();52035204let mut entity = world.spawn_empty();5205let old_location = entity.location();5206let res = std::panic::catch_unwind(AssertUnwindSafe(|| {5207entity.reborrow_scope(|mut entity| {5208// Change the entity's `EntityLocation`, which invalidates the original `EntityWorldMut`.5209// This will get updated at the end of the scope.5210entity.insert(TestComponent(0));52115212// Ensure that the entity location still gets updated even in case of a panic.5213panic!("this should get caught by the outer scope")5214});5215}));5216assert!(res.is_err());52175218// Ensure that the location has been properly updated.5219assert_ne!(entity.location(), old_location);5220}52215222// regression test for https://github.com/bevyengine/bevy/pull/78055223#[test]5224fn removing_sparse_updates_archetype_row() {5225#[derive(Component, PartialEq, Debug)]5226struct Dense(u8);52275228#[derive(Component)]5229#[component(storage = "SparseSet")]5230struct Sparse;52315232let mut world = World::new();5233let e1 = world.spawn((Dense(0), Sparse)).id();5234let e2 = world.spawn((Dense(1), Sparse)).id();52355236world.entity_mut(e1).remove::<Sparse>();5237assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));5238}52395240// regression test for https://github.com/bevyengine/bevy/pull/78055241#[test]5242fn removing_dense_updates_table_row() {5243#[derive(Component, PartialEq, Debug)]5244struct Dense(u8);52455246#[derive(Component)]5247#[component(storage = "SparseSet")]5248struct Sparse;52495250let mut world = World::new();5251let e1 = world.spawn((Dense(0), Sparse)).id();5252let e2 = world.spawn((Dense(1), Sparse)).id();52535254world.entity_mut(e1).remove::<Dense>();5255assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));5256}52575258// Test that calling retain with `()` removes all components.5259#[test]5260fn retain_nothing() {5261#[derive(Component)]5262struct Marker<const N: usize>;52635264let mut world = World::new();5265let ent = world.spawn((Marker::<1>, Marker::<2>, Marker::<3>)).id();52665267world.entity_mut(ent).retain::<()>();5268assert_eq!(world.entity(ent).archetype().components().len(), 0);5269}52705271// Test removing some components with `retain`, including components not on the entity.5272#[test]5273fn retain_some_components() {5274#[derive(Component)]5275struct Marker<const N: usize>;52765277let mut world = World::new();5278let ent = world.spawn((Marker::<1>, Marker::<2>, Marker::<3>)).id();52795280world.entity_mut(ent).retain::<(Marker<2>, Marker<4>)>();5281// Check that marker 2 was retained.5282assert!(world.entity(ent).get::<Marker<2>>().is_some());5283// Check that only marker 2 was retained.5284assert_eq!(world.entity(ent).archetype().components().len(), 1);5285}52865287// regression test for https://github.com/bevyengine/bevy/pull/78055288#[test]5289fn inserting_sparse_updates_archetype_row() {5290#[derive(Component, PartialEq, Debug)]5291struct Dense(u8);52925293#[derive(Component)]5294#[component(storage = "SparseSet")]5295struct Sparse;52965297let mut world = World::new();5298let e1 = world.spawn(Dense(0)).id();5299let e2 = world.spawn(Dense(1)).id();53005301world.entity_mut(e1).insert(Sparse);5302assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));5303}53045305// regression test for https://github.com/bevyengine/bevy/pull/78055306#[test]5307fn inserting_dense_updates_archetype_row() {5308#[derive(Component, PartialEq, Debug)]5309struct Dense(u8);53105311#[derive(Component)]5312struct Dense2;53135314#[derive(Component)]5315#[component(storage = "SparseSet")]5316struct Sparse;53175318let mut world = World::new();5319let e1 = world.spawn(Dense(0)).id();5320let e2 = world.spawn(Dense(1)).id();53215322world.entity_mut(e1).insert(Sparse).remove::<Sparse>();53235324// archetype with [e2, e1]5325// table with [e1, e2]53265327world.entity_mut(e2).insert(Dense2);53285329assert_eq!(world.entity(e1).get::<Dense>().unwrap(), &Dense(0));5330}53315332#[test]5333fn inserting_dense_updates_table_row() {5334#[derive(Component, PartialEq, Debug)]5335struct Dense(u8);53365337#[derive(Component)]5338struct Dense2;53395340#[derive(Component)]5341#[component(storage = "SparseSet")]5342struct Sparse;53435344let mut world = World::new();5345let e1 = world.spawn(Dense(0)).id();5346let e2 = world.spawn(Dense(1)).id();53475348world.entity_mut(e1).insert(Sparse).remove::<Sparse>();53495350// archetype with [e2, e1]5351// table with [e1, e2]53525353world.entity_mut(e1).insert(Dense2);53545355assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));5356}53575358// regression test for https://github.com/bevyengine/bevy/pull/78055359#[test]5360fn despawning_entity_updates_archetype_row() {5361#[derive(Component, PartialEq, Debug)]5362struct Dense(u8);53635364#[derive(Component)]5365#[component(storage = "SparseSet")]5366struct Sparse;53675368let mut world = World::new();5369let e1 = world.spawn(Dense(0)).id();5370let e2 = world.spawn(Dense(1)).id();53715372world.entity_mut(e1).insert(Sparse).remove::<Sparse>();53735374// archetype with [e2, e1]5375// table with [e1, e2]53765377world.entity_mut(e2).despawn();53785379assert_eq!(world.entity(e1).get::<Dense>().unwrap(), &Dense(0));5380}53815382// regression test for https://github.com/bevyengine/bevy/pull/78055383#[test]5384fn despawning_entity_updates_table_row() {5385#[derive(Component, PartialEq, Debug)]5386struct Dense(u8);53875388#[derive(Component)]5389#[component(storage = "SparseSet")]5390struct Sparse;53915392let mut world = World::new();5393let e1 = world.spawn(Dense(0)).id();5394let e2 = world.spawn(Dense(1)).id();53955396world.entity_mut(e1).insert(Sparse).remove::<Sparse>();53975398// archetype with [e2, e1]5399// table with [e1, e2]54005401world.entity_mut(e1).despawn();54025403assert_eq!(world.entity(e2).get::<Dense>().unwrap(), &Dense(1));5404}54055406#[test]5407fn entity_mut_insert_by_id() {5408let mut world = World::new();5409let test_component_id = world.register_component::<TestComponent>();54105411let mut entity = world.spawn_empty();5412OwningPtr::make(TestComponent(42), |ptr| {5413// SAFETY: `ptr` matches the component id5414unsafe { entity.insert_by_id(test_component_id, ptr) };5415});54165417let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();54185419assert_eq!(components, vec![&TestComponent(42)]);54205421// Compare with `insert_bundle_by_id`54225423let mut entity = world.spawn_empty();5424OwningPtr::make(TestComponent(84), |ptr| {5425// SAFETY: `ptr` matches the component id5426unsafe { entity.insert_by_ids(&[test_component_id], vec![ptr].into_iter()) };5427});54285429let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();54305431assert_eq!(components, vec![&TestComponent(42), &TestComponent(84)]);5432}54335434#[test]5435fn entity_mut_insert_bundle_by_id() {5436let mut world = World::new();5437let test_component_id = world.register_component::<TestComponent>();5438let test_component_2_id = world.register_component::<TestComponent2>();54395440let component_ids = [test_component_id, test_component_2_id];5441let test_component_value = TestComponent(42);5442let test_component_2_value = TestComponent2(84);54435444let mut entity = world.spawn_empty();5445OwningPtr::make(test_component_value, |ptr1| {5446OwningPtr::make(test_component_2_value, |ptr2| {5447// SAFETY: `ptr1` and `ptr2` match the component ids5448unsafe { entity.insert_by_ids(&component_ids, vec![ptr1, ptr2].into_iter()) };5449});5450});54515452let dynamic_components: Vec<_> = world5453.query::<(&TestComponent, &TestComponent2)>()5454.iter(&world)5455.collect();54565457assert_eq!(5458dynamic_components,5459vec![(&TestComponent(42), &TestComponent2(84))]5460);54615462// Compare with `World` generated using static type equivalents5463let mut static_world = World::new();54645465static_world.spawn((test_component_value, test_component_2_value));5466let static_components: Vec<_> = static_world5467.query::<(&TestComponent, &TestComponent2)>()5468.iter(&static_world)5469.collect();54705471assert_eq!(dynamic_components, static_components);5472}54735474#[test]5475fn entity_mut_remove_by_id() {5476let mut world = World::new();5477let test_component_id = world.register_component::<TestComponent>();54785479let mut entity = world.spawn(TestComponent(42));5480entity.remove_by_id(test_component_id);54815482let components: Vec<_> = world.query::<&TestComponent>().iter(&world).collect();54835484assert_eq!(components, vec![] as Vec<&TestComponent>);54855486// remove non-existent component does not panic5487world.spawn_empty().remove_by_id(test_component_id);5488}54895490/// Tests that components can be accessed through an `EntityRefExcept`.5491#[test]5492fn entity_ref_except() {5493let mut world = World::new();5494world.register_component::<TestComponent>();5495world.register_component::<TestComponent2>();54965497world.spawn(TestComponent(0)).insert(TestComponent2(0));54985499let mut query = world.query::<EntityRefExcept<TestComponent>>();55005501let mut found = false;5502for entity_ref in query.iter_mut(&mut world) {5503found = true;5504assert!(entity_ref.get::<TestComponent>().is_none());5505assert!(entity_ref.get_ref::<TestComponent>().is_none());5506assert!(matches!(5507entity_ref.get::<TestComponent2>(),5508Some(TestComponent2(0))5509));5510}55115512assert!(found);5513}55145515// Test that a single query can't both contain a mutable reference to a5516// component C and an `EntityRefExcept` that doesn't include C among its5517// exclusions.5518#[test]5519#[should_panic]5520fn entity_ref_except_conflicts_with_self() {5521let mut world = World::new();5522world.spawn(TestComponent(0)).insert(TestComponent2(0));55235524// This should panic, because we have a mutable borrow on5525// `TestComponent` but have a simultaneous indirect immutable borrow on5526// that component via `EntityRefExcept`.5527world.run_system_once(system).unwrap();55285529fn system(_: Query<(&mut TestComponent, EntityRefExcept<TestComponent2>)>) {}5530}55315532// Test that an `EntityRefExcept` that doesn't include a component C among5533// its exclusions can't coexist with a mutable query for that component.5534#[test]5535#[should_panic]5536fn entity_ref_except_conflicts_with_other() {5537let mut world = World::new();5538world.spawn(TestComponent(0)).insert(TestComponent2(0));55395540// This should panic, because we have a mutable borrow on5541// `TestComponent` but have a simultaneous indirect immutable borrow on5542// that component via `EntityRefExcept`.5543world.run_system_once(system).unwrap();55445545fn system(_: Query<&mut TestComponent>, _: Query<EntityRefExcept<TestComponent2>>) {}5546}55475548// Test that an `EntityRefExcept` with an exception for some component C can5549// coexist with a query for that component C.5550#[test]5551fn entity_ref_except_doesnt_conflict() {5552let mut world = World::new();5553world.spawn(TestComponent(0)).insert(TestComponent2(0));55545555world.run_system_once(system).unwrap();55565557fn system(_: Query<&mut TestComponent>, query: Query<EntityRefExcept<TestComponent>>) {5558for entity_ref in query.iter() {5559assert!(matches!(5560entity_ref.get::<TestComponent2>(),5561Some(TestComponent2(0))5562));5563}5564}5565}55665567/// Tests that components can be mutably accessed through an5568/// `EntityMutExcept`.5569#[test]5570fn entity_mut_except() {5571let mut world = World::new();5572world.spawn(TestComponent(0)).insert(TestComponent2(0));55735574let mut query = world.query::<EntityMutExcept<TestComponent>>();55755576let mut found = false;5577for mut entity_mut in query.iter_mut(&mut world) {5578found = true;5579assert!(entity_mut.get::<TestComponent>().is_none());5580assert!(entity_mut.get_ref::<TestComponent>().is_none());5581assert!(entity_mut.get_mut::<TestComponent>().is_none());5582assert!(matches!(5583entity_mut.get::<TestComponent2>(),5584Some(TestComponent2(0))5585));5586}55875588assert!(found);5589}55905591// Test that a single query can't both contain a mutable reference to a5592// component C and an `EntityMutExcept` that doesn't include C among its5593// exclusions.5594#[test]5595#[should_panic]5596fn entity_mut_except_conflicts_with_self() {5597let mut world = World::new();5598world.spawn(TestComponent(0)).insert(TestComponent2(0));55995600// This should panic, because we have a mutable borrow on5601// `TestComponent` but have a simultaneous indirect immutable borrow on5602// that component via `EntityRefExcept`.5603world.run_system_once(system).unwrap();56045605fn system(_: Query<(&mut TestComponent, EntityMutExcept<TestComponent2>)>) {}5606}56075608// Test that an `EntityMutExcept` that doesn't include a component C among5609// its exclusions can't coexist with a query for that component.5610#[test]5611#[should_panic]5612fn entity_mut_except_conflicts_with_other() {5613let mut world = World::new();5614world.spawn(TestComponent(0)).insert(TestComponent2(0));56155616// This should panic, because we have a mutable borrow on5617// `TestComponent` but have a simultaneous indirect immutable borrow on5618// that component via `EntityRefExcept`.5619world.run_system_once(system).unwrap();56205621fn system(_: Query<&mut TestComponent>, mut query: Query<EntityMutExcept<TestComponent2>>) {5622for mut entity_mut in query.iter_mut() {5623assert!(entity_mut5624.get_mut::<TestComponent2>()5625.is_some_and(|component| component.0 == 0));5626}5627}5628}56295630// Test that an `EntityMutExcept` with an exception for some component C can5631// coexist with a query for that component C.5632#[test]5633fn entity_mut_except_doesnt_conflict() {5634let mut world = World::new();5635world.spawn(TestComponent(0)).insert(TestComponent2(0));56365637world.run_system_once(system).unwrap();56385639fn system(_: Query<&mut TestComponent>, mut query: Query<EntityMutExcept<TestComponent>>) {5640for mut entity_mut in query.iter_mut() {5641assert!(entity_mut5642.get_mut::<TestComponent2>()5643.is_some_and(|component| component.0 == 0));5644}5645}5646}56475648#[test]5649fn entity_mut_except_registers_components() {5650// Checks for a bug where `EntityMutExcept` would not register the component and5651// would therefore not include an exception, causing it to conflict with the later query.5652fn system1(_query: Query<EntityMutExcept<TestComponent>>, _: Query<&mut TestComponent>) {}5653let mut world = World::new();5654world.run_system_once(system1).unwrap();56555656fn system2(_: Query<&mut TestComponent>, _query: Query<EntityMutExcept<TestComponent>>) {}5657let mut world = World::new();5658world.run_system_once(system2).unwrap();5659}56605661#[derive(Component)]5662struct A;56635664#[test]5665fn disjoint_access() {5666fn disjoint_readonly(_: Query<EntityMut, With<A>>, _: Query<EntityRef, Without<A>>) {}56675668fn disjoint_mutable(_: Query<EntityMut, With<A>>, _: Query<EntityMut, Without<A>>) {}56695670assert_is_system(disjoint_readonly);5671assert_is_system(disjoint_mutable);5672}56735674#[test]5675fn ref_compatible() {5676fn borrow_system(_: Query<(EntityRef, &A)>, _: Query<&A>) {}56775678assert_is_system(borrow_system);5679}56805681#[test]5682fn ref_compatible_with_resource() {5683fn borrow_system(_: Query<EntityRef>, _: Res<R>) {}56845685assert_is_system(borrow_system);5686}56875688#[test]5689fn ref_compatible_with_resource_mut() {5690fn borrow_system(_: Query<EntityRef>, _: ResMut<R>) {}56915692assert_is_system(borrow_system);5693}56945695#[test]5696#[should_panic]5697fn ref_incompatible_with_mutable_component() {5698fn incompatible_system(_: Query<(EntityRef, &mut A)>) {}56995700assert_is_system(incompatible_system);5701}57025703#[test]5704#[should_panic]5705fn ref_incompatible_with_mutable_query() {5706fn incompatible_system(_: Query<EntityRef>, _: Query<&mut A>) {}57075708assert_is_system(incompatible_system);5709}57105711#[test]5712fn mut_compatible_with_entity() {5713fn borrow_mut_system(_: Query<(Entity, EntityMut)>) {}57145715assert_is_system(borrow_mut_system);5716}57175718#[test]5719fn mut_compatible_with_resource() {5720fn borrow_mut_system(_: Res<R>, _: Query<EntityMut>) {}57215722assert_is_system(borrow_mut_system);5723}57245725#[test]5726fn mut_compatible_with_resource_mut() {5727fn borrow_mut_system(_: ResMut<R>, _: Query<EntityMut>) {}57285729assert_is_system(borrow_mut_system);5730}57315732#[test]5733#[should_panic]5734fn mut_incompatible_with_read_only_component() {5735fn incompatible_system(_: Query<(EntityMut, &A)>) {}57365737assert_is_system(incompatible_system);5738}57395740#[test]5741#[should_panic]5742fn mut_incompatible_with_mutable_component() {5743fn incompatible_system(_: Query<(EntityMut, &mut A)>) {}57445745assert_is_system(incompatible_system);5746}57475748#[test]5749#[should_panic]5750fn mut_incompatible_with_read_only_query() {5751fn incompatible_system(_: Query<EntityMut>, _: Query<&A>) {}57525753assert_is_system(incompatible_system);5754}57555756#[test]5757#[should_panic]5758fn mut_incompatible_with_mutable_query() {5759fn incompatible_system(_: Query<EntityMut>, _: Query<&mut A>) {}57605761assert_is_system(incompatible_system);5762}57635764#[test]5765fn filtered_entity_ref_normal() {5766let mut world = World::new();5767let a_id = world.register_component::<A>();57685769let e: FilteredEntityRef = world.spawn(A).into();57705771assert!(e.get::<A>().is_some());5772assert!(e.get_ref::<A>().is_some());5773assert!(e.get_change_ticks::<A>().is_some());5774assert!(e.get_by_id(a_id).is_some());5775assert!(e.get_change_ticks_by_id(a_id).is_some());5776}57775778#[test]5779fn filtered_entity_ref_missing() {5780let mut world = World::new();5781let a_id = world.register_component::<A>();57825783let e: FilteredEntityRef = world.spawn(()).into();57845785assert!(e.get::<A>().is_none());5786assert!(e.get_ref::<A>().is_none());5787assert!(e.get_change_ticks::<A>().is_none());5788assert!(e.get_by_id(a_id).is_none());5789assert!(e.get_change_ticks_by_id(a_id).is_none());5790}57915792#[test]5793fn filtered_entity_mut_normal() {5794let mut world = World::new();5795let a_id = world.register_component::<A>();57965797let mut e: FilteredEntityMut = world.spawn(A).into();57985799assert!(e.get::<A>().is_some());5800assert!(e.get_ref::<A>().is_some());5801assert!(e.get_mut::<A>().is_some());5802assert!(e.get_change_ticks::<A>().is_some());5803assert!(e.get_by_id(a_id).is_some());5804assert!(e.get_mut_by_id(a_id).is_some());5805assert!(e.get_change_ticks_by_id(a_id).is_some());5806}58075808#[test]5809fn filtered_entity_mut_missing() {5810let mut world = World::new();5811let a_id = world.register_component::<A>();58125813let mut e: FilteredEntityMut = world.spawn(()).into();58145815assert!(e.get::<A>().is_none());5816assert!(e.get_ref::<A>().is_none());5817assert!(e.get_mut::<A>().is_none());5818assert!(e.get_change_ticks::<A>().is_none());5819assert!(e.get_by_id(a_id).is_none());5820assert!(e.get_mut_by_id(a_id).is_none());5821assert!(e.get_change_ticks_by_id(a_id).is_none());5822}58235824#[derive(Component, PartialEq, Eq, Debug)]5825struct X(usize);58265827#[derive(Component, PartialEq, Eq, Debug)]5828struct Y(usize);58295830#[test]5831fn get_components() {5832let mut world = World::default();5833let e1 = world.spawn((X(7), Y(10))).id();5834let e2 = world.spawn(X(8)).id();5835let e3 = world.spawn_empty().id();58365837assert_eq!(5838Some((&X(7), &Y(10))),5839world.entity(e1).get_components::<(&X, &Y)>()5840);5841assert_eq!(None, world.entity(e2).get_components::<(&X, &Y)>());5842assert_eq!(None, world.entity(e3).get_components::<(&X, &Y)>());5843}58445845#[test]5846fn get_by_id_array() {5847let mut world = World::default();5848let e1 = world.spawn((X(7), Y(10))).id();5849let e2 = world.spawn(X(8)).id();5850let e3 = world.spawn_empty().id();58515852let x_id = world.register_component::<X>();5853let y_id = world.register_component::<Y>();58545855assert_eq!(5856Ok((&X(7), &Y(10))),5857world5858.entity(e1)5859.get_by_id([x_id, y_id])5860.map(|[x_ptr, y_ptr]| {5861// SAFETY: components match the id they were fetched with5862(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5863})5864);5865assert_eq!(5866Err(EntityComponentError::MissingComponent(y_id)),5867world5868.entity(e2)5869.get_by_id([x_id, y_id])5870.map(|[x_ptr, y_ptr]| {5871// SAFETY: components match the id they were fetched with5872(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5873})5874);5875assert_eq!(5876Err(EntityComponentError::MissingComponent(x_id)),5877world5878.entity(e3)5879.get_by_id([x_id, y_id])5880.map(|[x_ptr, y_ptr]| {5881// SAFETY: components match the id they were fetched with5882(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5883})5884);5885}58865887#[test]5888fn get_by_id_vec() {5889let mut world = World::default();5890let e1 = world.spawn((X(7), Y(10))).id();5891let e2 = world.spawn(X(8)).id();5892let e3 = world.spawn_empty().id();58935894let x_id = world.register_component::<X>();5895let y_id = world.register_component::<Y>();58965897assert_eq!(5898Ok((&X(7), &Y(10))),5899world5900.entity(e1)5901.get_by_id(&[x_id, y_id] as &[ComponentId])5902.map(|ptrs| {5903let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {5904panic!("get_by_id(slice) didn't return 2 elements")5905};59065907// SAFETY: components match the id they were fetched with5908(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5909})5910);5911assert_eq!(5912Err(EntityComponentError::MissingComponent(y_id)),5913world5914.entity(e2)5915.get_by_id(&[x_id, y_id] as &[ComponentId])5916.map(|ptrs| {5917let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {5918panic!("get_by_id(slice) didn't return 2 elements")5919};59205921// SAFETY: components match the id they were fetched with5922(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5923})5924);5925assert_eq!(5926Err(EntityComponentError::MissingComponent(x_id)),5927world5928.entity(e3)5929.get_by_id(&[x_id, y_id] as &[ComponentId])5930.map(|ptrs| {5931let Ok([x_ptr, y_ptr]): Result<[Ptr; 2], _> = ptrs.try_into() else {5932panic!("get_by_id(slice) didn't return 2 elements")5933};59345935// SAFETY: components match the id they were fetched with5936(unsafe { x_ptr.deref::<X>() }, unsafe { y_ptr.deref::<Y>() })5937})5938);5939}59405941#[test]5942fn get_mut_by_id_array() {5943let mut world = World::default();5944let e1 = world.spawn((X(7), Y(10))).id();5945let e2 = world.spawn(X(8)).id();5946let e3 = world.spawn_empty().id();59475948let x_id = world.register_component::<X>();5949let y_id = world.register_component::<Y>();59505951assert_eq!(5952Ok((&mut X(7), &mut Y(10))),5953world5954.entity_mut(e1)5955.get_mut_by_id([x_id, y_id])5956.map(|[x_ptr, y_ptr]| {5957// SAFETY: components match the id they were fetched with5958(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {5959y_ptr.into_inner().deref_mut::<Y>()5960})5961})5962);5963assert_eq!(5964Err(EntityComponentError::MissingComponent(y_id)),5965world5966.entity_mut(e2)5967.get_mut_by_id([x_id, y_id])5968.map(|[x_ptr, y_ptr]| {5969// SAFETY: components match the id they were fetched with5970(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {5971y_ptr.into_inner().deref_mut::<Y>()5972})5973})5974);5975assert_eq!(5976Err(EntityComponentError::MissingComponent(x_id)),5977world5978.entity_mut(e3)5979.get_mut_by_id([x_id, y_id])5980.map(|[x_ptr, y_ptr]| {5981// SAFETY: components match the id they were fetched with5982(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {5983y_ptr.into_inner().deref_mut::<Y>()5984})5985})5986);59875988assert_eq!(5989Err(EntityComponentError::AliasedMutability(x_id)),5990world5991.entity_mut(e1)5992.get_mut_by_id([x_id, x_id])5993.map(|_| { unreachable!() })5994);5995assert_eq!(5996Err(EntityComponentError::AliasedMutability(x_id)),5997world5998.entity_mut(e3)5999.get_mut_by_id([x_id, x_id])6000.map(|_| { unreachable!() })6001);6002}60036004#[test]6005fn get_mut_by_id_vec() {6006let mut world = World::default();6007let e1 = world.spawn((X(7), Y(10))).id();6008let e2 = world.spawn(X(8)).id();6009let e3 = world.spawn_empty().id();60106011let x_id = world.register_component::<X>();6012let y_id = world.register_component::<Y>();60136014assert_eq!(6015Ok((&mut X(7), &mut Y(10))),6016world6017.entity_mut(e1)6018.get_mut_by_id(&[x_id, y_id] as &[ComponentId])6019.map(|ptrs| {6020let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {6021panic!("get_mut_by_id(slice) didn't return 2 elements")6022};60236024// SAFETY: components match the id they were fetched with6025(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {6026y_ptr.into_inner().deref_mut::<Y>()6027})6028})6029);6030assert_eq!(6031Err(EntityComponentError::MissingComponent(y_id)),6032world6033.entity_mut(e2)6034.get_mut_by_id(&[x_id, y_id] as &[ComponentId])6035.map(|ptrs| {6036let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {6037panic!("get_mut_by_id(slice) didn't return 2 elements")6038};60396040// SAFETY: components match the id they were fetched with6041(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {6042y_ptr.into_inner().deref_mut::<Y>()6043})6044})6045);6046assert_eq!(6047Err(EntityComponentError::MissingComponent(x_id)),6048world6049.entity_mut(e3)6050.get_mut_by_id(&[x_id, y_id] as &[ComponentId])6051.map(|ptrs| {6052let Ok([x_ptr, y_ptr]): Result<[MutUntyped; 2], _> = ptrs.try_into() else {6053panic!("get_mut_by_id(slice) didn't return 2 elements")6054};60556056// SAFETY: components match the id they were fetched with6057(unsafe { x_ptr.into_inner().deref_mut::<X>() }, unsafe {6058y_ptr.into_inner().deref_mut::<Y>()6059})6060})6061);60626063assert_eq!(6064Err(EntityComponentError::AliasedMutability(x_id)),6065world6066.entity_mut(e1)6067.get_mut_by_id(&[x_id, x_id])6068.map(|_| { unreachable!() })6069);6070assert_eq!(6071Err(EntityComponentError::AliasedMutability(x_id)),6072world6073.entity_mut(e3)6074.get_mut_by_id(&[x_id, x_id])6075.map(|_| { unreachable!() })6076);6077}60786079#[test]6080fn get_mut_by_id_unchecked() {6081let mut world = World::default();6082let e1 = world.spawn((X(7), Y(10))).id();6083let x_id = world.register_component::<X>();6084let y_id = world.register_component::<Y>();60856086let e1_mut = &world.get_entity_mut([e1]).unwrap()[0];6087// SAFETY: The entity e1 contains component X.6088let x_ptr = unsafe { e1_mut.get_mut_by_id_unchecked(x_id) }.unwrap();6089// SAFETY: The entity e1 contains component Y, with components X and Y being mutually independent.6090let y_ptr = unsafe { e1_mut.get_mut_by_id_unchecked(y_id) }.unwrap();60916092// SAFETY: components match the id they were fetched with6093let x_component = unsafe { x_ptr.into_inner().deref_mut::<X>() };6094x_component.0 += 1;6095// SAFETY: components match the id they were fetched with6096let y_component = unsafe { y_ptr.into_inner().deref_mut::<Y>() };6097y_component.0 -= 1;60986099assert_eq!((&mut X(8), &mut Y(9)), (x_component, y_component));6100}61016102#[derive(EntityEvent)]6103struct TestEvent(Entity);61046105#[test]6106fn adding_observer_updates_location() {6107let mut world = World::new();6108let entity = world6109.spawn_empty()6110.observe(|event: On<TestEvent>, mut commands: Commands| {6111commands6112.entity(event.event_target())6113.insert(TestComponent(0));6114})6115.id();61166117// this should not be needed, but is currently required to tease out the bug6118world.flush();61196120let mut a = world.entity_mut(entity);6121// SAFETY: this _intentionally_ doesn't update the location, to ensure that we're actually testing6122// that observe() updates location6123unsafe { a.world_mut().trigger(TestEvent(entity)) }6124a.observe(|_: On<TestEvent>| {}); // this flushes commands implicitly by spawning6125let location = a.location();6126assert_eq!(world.entities().get(entity), Some(location));6127}61286129#[test]6130#[should_panic]6131fn location_on_despawned_entity_panics() {6132let mut world = World::new();6133world.add_observer(|add: On<Add, TestComponent>, mut commands: Commands| {6134commands.entity(add.entity).despawn();6135});6136let entity = world.spawn_empty().id();6137let mut a = world.entity_mut(entity);6138a.insert(TestComponent(0));6139a.location();6140}61416142#[derive(Resource)]6143struct TestFlush(usize);61446145fn count_flush(world: &mut World) {6146world.resource_mut::<TestFlush>().0 += 1;6147}61486149#[test]6150fn archetype_modifications_trigger_flush() {6151let mut world = World::new();6152world.insert_resource(TestFlush(0));6153world.add_observer(|_: On<Add, TestComponent>, mut commands: Commands| {6154commands.queue(count_flush);6155});6156world.add_observer(|_: On<Remove, TestComponent>, mut commands: Commands| {6157commands.queue(count_flush);6158});6159world.commands().queue(count_flush);6160let entity = world.spawn_empty().id();6161assert_eq!(world.resource::<TestFlush>().0, 1);6162world.commands().queue(count_flush);6163world.flush_commands();6164let mut a = world.entity_mut(entity);6165assert_eq!(a.world().resource::<TestFlush>().0, 2);6166a.insert(TestComponent(0));6167assert_eq!(a.world().resource::<TestFlush>().0, 3);6168a.remove::<TestComponent>();6169assert_eq!(a.world().resource::<TestFlush>().0, 4);6170a.insert(TestComponent(0));6171assert_eq!(a.world().resource::<TestFlush>().0, 5);6172let _ = a.take::<TestComponent>();6173assert_eq!(a.world().resource::<TestFlush>().0, 6);6174a.insert(TestComponent(0));6175assert_eq!(a.world().resource::<TestFlush>().0, 7);6176a.retain::<()>();6177assert_eq!(a.world().resource::<TestFlush>().0, 8);6178a.insert(TestComponent(0));6179assert_eq!(a.world().resource::<TestFlush>().0, 9);6180a.clear();6181assert_eq!(a.world().resource::<TestFlush>().0, 10);6182a.insert(TestComponent(0));6183assert_eq!(a.world().resource::<TestFlush>().0, 11);6184a.despawn();6185assert_eq!(world.resource::<TestFlush>().0, 12);6186}61876188#[derive(Resource)]6189struct TestVec(Vec<&'static str>);61906191#[derive(Component)]6192#[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)]6193struct OrdA;61946195fn ord_a_hook_on_add(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {6196world.resource_mut::<TestVec>().0.push("OrdA hook on_add");6197world.commands().entity(entity).insert(OrdB);6198}61996200fn ord_a_hook_on_insert(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {6201world6202.resource_mut::<TestVec>()6203.06204.push("OrdA hook on_insert");6205world.commands().entity(entity).remove::<OrdA>();6206world.commands().entity(entity).remove::<OrdB>();6207}62086209fn ord_a_hook_on_replace(mut world: DeferredWorld, _: HookContext) {6210world6211.resource_mut::<TestVec>()6212.06213.push("OrdA hook on_replace");6214}62156216fn ord_a_hook_on_remove(mut world: DeferredWorld, _: HookContext) {6217world6218.resource_mut::<TestVec>()6219.06220.push("OrdA hook on_remove");6221}62226223fn ord_a_observer_on_add(_event: On<Add, OrdA>, mut res: ResMut<TestVec>) {6224res.0.push("OrdA observer on_add");6225}62266227fn ord_a_observer_on_insert(_event: On<Insert, OrdA>, mut res: ResMut<TestVec>) {6228res.0.push("OrdA observer on_insert");6229}62306231fn ord_a_observer_on_replace(_event: On<Replace, OrdA>, mut res: ResMut<TestVec>) {6232res.0.push("OrdA observer on_replace");6233}62346235fn ord_a_observer_on_remove(_event: On<Remove, OrdA>, mut res: ResMut<TestVec>) {6236res.0.push("OrdA observer on_remove");6237}62386239#[derive(Component)]6240#[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)]6241struct OrdB;62426243fn ord_b_hook_on_add(mut world: DeferredWorld, _: HookContext) {6244world.resource_mut::<TestVec>().0.push("OrdB hook on_add");6245world.commands().queue(|world: &mut World| {6246world6247.resource_mut::<TestVec>()6248.06249.push("OrdB command on_add");6250});6251}62526253fn ord_b_hook_on_insert(mut world: DeferredWorld, _: HookContext) {6254world6255.resource_mut::<TestVec>()6256.06257.push("OrdB hook on_insert");6258}62596260fn ord_b_hook_on_replace(mut world: DeferredWorld, _: HookContext) {6261world6262.resource_mut::<TestVec>()6263.06264.push("OrdB hook on_replace");6265}62666267fn ord_b_hook_on_remove(mut world: DeferredWorld, _: HookContext) {6268world6269.resource_mut::<TestVec>()6270.06271.push("OrdB hook on_remove");6272}62736274fn ord_b_observer_on_add(_event: On<Add, OrdB>, mut res: ResMut<TestVec>) {6275res.0.push("OrdB observer on_add");6276}62776278fn ord_b_observer_on_insert(_event: On<Insert, OrdB>, mut res: ResMut<TestVec>) {6279res.0.push("OrdB observer on_insert");6280}62816282fn ord_b_observer_on_replace(_event: On<Replace, OrdB>, mut res: ResMut<TestVec>) {6283res.0.push("OrdB observer on_replace");6284}62856286fn ord_b_observer_on_remove(_event: On<Remove, OrdB>, mut res: ResMut<TestVec>) {6287res.0.push("OrdB observer on_remove");6288}62896290#[test]6291fn command_ordering_is_correct() {6292let mut world = World::new();6293world.insert_resource(TestVec(Vec::new()));6294world.add_observer(ord_a_observer_on_add);6295world.add_observer(ord_a_observer_on_insert);6296world.add_observer(ord_a_observer_on_replace);6297world.add_observer(ord_a_observer_on_remove);6298world.add_observer(ord_b_observer_on_add);6299world.add_observer(ord_b_observer_on_insert);6300world.add_observer(ord_b_observer_on_replace);6301world.add_observer(ord_b_observer_on_remove);6302let _entity = world.spawn(OrdA).id();6303let expected = [6304"OrdA hook on_add", // adds command to insert OrdB6305"OrdA observer on_add",6306"OrdA hook on_insert", // adds command to despawn entity6307"OrdA observer on_insert",6308"OrdB hook on_add", // adds command to just add to this log6309"OrdB observer on_add",6310"OrdB hook on_insert",6311"OrdB observer on_insert",6312"OrdB command on_add", // command added by OrdB hook on_add, needs to run before despawn command6313"OrdA observer on_replace", // start of despawn6314"OrdA hook on_replace",6315"OrdA observer on_remove",6316"OrdA hook on_remove",6317"OrdB observer on_replace",6318"OrdB hook on_replace",6319"OrdB observer on_remove",6320"OrdB hook on_remove",6321];6322world.flush();6323assert_eq!(world.resource_mut::<TestVec>().0.as_slice(), &expected[..]);6324}63256326#[test]6327fn entity_world_mut_clone_and_move_components() {6328#[derive(Component, Clone, PartialEq, Debug)]6329struct A;63306331#[derive(Component, Clone, PartialEq, Debug)]6332struct B;63336334#[derive(Component, Clone, PartialEq, Debug)]6335struct C(u32);63366337let mut world = World::new();6338let entity_a = world.spawn((A, B, C(5))).id();6339let entity_b = world.spawn((A, C(4))).id();63406341world.entity_mut(entity_a).clone_components::<B>(entity_b);6342assert_eq!(world.entity(entity_a).get::<B>(), Some(&B));6343assert_eq!(world.entity(entity_b).get::<B>(), Some(&B));63446345world.entity_mut(entity_a).move_components::<C>(entity_b);6346assert_eq!(world.entity(entity_a).get::<C>(), None);6347assert_eq!(world.entity(entity_b).get::<C>(), Some(&C(5)));63486349assert_eq!(world.entity(entity_a).get::<A>(), Some(&A));6350assert_eq!(world.entity(entity_b).get::<A>(), Some(&A));6351}63526353#[test]6354fn entity_world_mut_clone_with_move_and_require() {6355#[derive(Component, Clone, PartialEq, Debug)]6356#[require(B(3))]6357struct A;63586359#[derive(Component, Clone, PartialEq, Debug, Default)]6360#[require(C(3))]6361struct B(u32);63626363#[derive(Component, Clone, PartialEq, Debug, Default)]6364#[require(D)]6365struct C(u32);63666367#[derive(Component, Clone, PartialEq, Debug, Default)]6368struct D;63696370let mut world = World::new();6371let entity_a = world.spawn((A, B(5))).id();6372let entity_b = world.spawn_empty().id();63736374world6375.entity_mut(entity_a)6376.clone_with_opt_in(entity_b, |builder| {6377builder6378.move_components(true)6379.allow::<C>()6380.without_required_components(|builder| {6381builder.allow::<A>();6382});6383});63846385assert_eq!(world.entity(entity_a).get::<A>(), None);6386assert_eq!(world.entity(entity_b).get::<A>(), Some(&A));63876388assert_eq!(world.entity(entity_a).get::<B>(), Some(&B(5)));6389assert_eq!(world.entity(entity_b).get::<B>(), Some(&B(3)));63906391assert_eq!(world.entity(entity_a).get::<C>(), None);6392assert_eq!(world.entity(entity_b).get::<C>(), Some(&C(3)));63936394assert_eq!(world.entity(entity_a).get::<D>(), None);6395assert_eq!(world.entity(entity_b).get::<D>(), Some(&D));6396}63976398#[test]6399fn update_despawned_by_after_observers() {6400let mut world = World::new();64016402#[derive(Component)]6403#[component(on_remove = get_tracked)]6404struct C;64056406static TRACKED: OnceLock<(MaybeLocation, Tick)> = OnceLock::new();6407fn get_tracked(world: DeferredWorld, HookContext { entity, .. }: HookContext) {6408TRACKED.get_or_init(|| {6409let by = world6410.entities6411.entity_get_spawned_or_despawned_by(entity)6412.map(|l| l.unwrap());6413let at = world6414.entities6415.entity_get_spawn_or_despawn_tick(entity)6416.unwrap();6417(by, at)6418});6419}64206421#[track_caller]6422fn caller_spawn(world: &mut World) -> (Entity, MaybeLocation, Tick) {6423let caller = MaybeLocation::caller();6424(world.spawn(C).id(), caller, world.change_tick())6425}6426let (entity, spawner, spawn_tick) = caller_spawn(&mut world);64276428assert_eq!(6429spawner,6430world6431.entities()6432.entity_get_spawned_or_despawned_by(entity)6433.map(|l| l.unwrap())6434);64356436#[track_caller]6437fn caller_despawn(world: &mut World, entity: Entity) -> (MaybeLocation, Tick) {6438world.despawn(entity);6439(MaybeLocation::caller(), world.change_tick())6440}6441let (despawner, despawn_tick) = caller_despawn(&mut world, entity);64426443assert_eq!((spawner, spawn_tick), *TRACKED.get().unwrap());6444assert_eq!(6445despawner,6446world6447.entities()6448.entity_get_spawned_or_despawned_by(entity)6449.map(|l| l.unwrap())6450);6451assert_eq!(6452despawn_tick,6453world6454.entities()6455.entity_get_spawn_or_despawn_tick(entity)6456.unwrap()6457);6458}64596460#[test]6461fn with_component_activates_hooks() {6462use core::sync::atomic::{AtomicBool, AtomicU8, Ordering};64636464#[derive(Component, PartialEq, Eq, Debug)]6465#[component(immutable)]6466struct Foo(bool);64676468static EXPECTED_VALUE: AtomicBool = AtomicBool::new(false);64696470static ADD_COUNT: AtomicU8 = AtomicU8::new(0);6471static REMOVE_COUNT: AtomicU8 = AtomicU8::new(0);6472static REPLACE_COUNT: AtomicU8 = AtomicU8::new(0);6473static INSERT_COUNT: AtomicU8 = AtomicU8::new(0);64746475let mut world = World::default();64766477world.register_component::<Foo>();6478world6479.register_component_hooks::<Foo>()6480.on_add(|world, context| {6481ADD_COUNT.fetch_add(1, Ordering::Relaxed);64826483assert_eq!(6484world.get(context.entity),6485Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))6486);6487})6488.on_remove(|world, context| {6489REMOVE_COUNT.fetch_add(1, Ordering::Relaxed);64906491assert_eq!(6492world.get(context.entity),6493Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))6494);6495})6496.on_replace(|world, context| {6497REPLACE_COUNT.fetch_add(1, Ordering::Relaxed);64986499assert_eq!(6500world.get(context.entity),6501Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))6502);6503})6504.on_insert(|world, context| {6505INSERT_COUNT.fetch_add(1, Ordering::Relaxed);65066507assert_eq!(6508world.get(context.entity),6509Some(&Foo(EXPECTED_VALUE.load(Ordering::Relaxed)))6510);6511});65126513let entity = world.spawn(Foo(false)).id();65146515assert_eq!(ADD_COUNT.load(Ordering::Relaxed), 1);6516assert_eq!(REMOVE_COUNT.load(Ordering::Relaxed), 0);6517assert_eq!(REPLACE_COUNT.load(Ordering::Relaxed), 0);6518assert_eq!(INSERT_COUNT.load(Ordering::Relaxed), 1);65196520let mut entity = world.entity_mut(entity);65216522let archetype_pointer_before = &raw const *entity.archetype();65236524assert_eq!(entity.get::<Foo>(), Some(&Foo(false)));65256526entity.modify_component(|foo: &mut Foo| {6527foo.0 = true;6528EXPECTED_VALUE.store(foo.0, Ordering::Relaxed);6529});65306531let archetype_pointer_after = &raw const *entity.archetype();65326533assert_eq!(entity.get::<Foo>(), Some(&Foo(true)));65346535assert_eq!(ADD_COUNT.load(Ordering::Relaxed), 1);6536assert_eq!(REMOVE_COUNT.load(Ordering::Relaxed), 0);6537assert_eq!(REPLACE_COUNT.load(Ordering::Relaxed), 1);6538assert_eq!(INSERT_COUNT.load(Ordering::Relaxed), 2);65396540assert_eq!(archetype_pointer_before, archetype_pointer_after);6541}65426543#[test]6544fn bundle_remove_only_triggers_for_present_components() {6545let mut world = World::default();65466547#[derive(Component)]6548struct A;65496550#[derive(Component)]6551struct B;65526553#[derive(Resource, PartialEq, Eq, Debug)]6554struct Tracker {6555a: bool,6556b: bool,6557}65586559world.insert_resource(Tracker { a: false, b: false });6560let entity = world.spawn(A).id();65616562world.add_observer(|_: On<Remove, A>, mut tracker: ResMut<Tracker>| {6563tracker.a = true;6564});6565world.add_observer(|_: On<Remove, B>, mut tracker: ResMut<Tracker>| {6566tracker.b = true;6567});65686569world.entity_mut(entity).remove::<(A, B)>();65706571assert_eq!(6572world.resource::<Tracker>(),6573&Tracker {6574a: true,6575// The entity didn't have a B component, so it should not have been triggered.6576b: false,6577}6578);6579}6580}658165826583