@@ -3824,6 +3824,62 @@ impl ContainsEntity for FilteredEntityRef<'_, '_> {
38243824// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
38253825unsafe impl EntityEquivalent for FilteredEntityRef < ' _ , ' _ > { }
38263826
3827+ /// Variant of [`FilteredEntityMut`] that can be used to create copies of a [`FilteredEntityMut`], as long
3828+ /// as the user ensures that these won't cause aliasing violations.
3829+ ///
3830+ /// This can be useful to mutably query multiple components from a single `FilteredEntityMut`.
3831+ ///
3832+ /// ### Example Usage
3833+ ///
3834+ /// ```
3835+ /// # use bevy_ecs::{prelude::*, world::{FilteredEntityMut, UnsafeFilteredEntityMut}};
3836+ /// #
3837+ /// # #[derive(Component)]
3838+ /// # struct A;
3839+ /// # #[derive(Component)]
3840+ /// # struct B;
3841+ /// #
3842+ /// # let mut world = World::new();
3843+ /// # world.spawn((A, B));
3844+ /// #
3845+ /// // This gives the `FilteredEntityMut` access to `&mut A` and `&mut B`.
3846+ /// let mut query = QueryBuilder::<FilteredEntityMut>::new(&mut world)
3847+ /// .data::<(&mut A, &mut B)>()
3848+ /// .build();
3849+ ///
3850+ /// let mut filtered_entity: FilteredEntityMut = query.single_mut(&mut world).unwrap();
3851+ /// let unsafe_filtered_entity = UnsafeFilteredEntityMut::new_readonly(&filtered_entity);
3852+ /// // SAFETY: the original FilteredEntityMut accesses `&mut A` and the clone accesses `&mut B`, so no aliasing violations occur.
3853+ /// let mut filtered_entity_clone: FilteredEntityMut = unsafe { unsafe_filtered_entity.into_mut() };
3854+ /// let a: Mut<A> = filtered_entity.get_mut().unwrap();
3855+ /// let b: Mut<B> = filtered_entity_clone.get_mut().unwrap();
3856+ /// ```
3857+ #[ derive( Copy , Clone ) ]
3858+ pub struct UnsafeFilteredEntityMut < ' w , ' s > {
3859+ entity : UnsafeEntityCell < ' w > ,
3860+ access : & ' s Access ,
3861+ }
3862+
3863+ impl < ' w , ' s > UnsafeFilteredEntityMut < ' w , ' s > {
3864+ /// Creates a [`UnsafeFilteredEntityMut`] that can be used to have multiple concurrent [`FilteredEntityMut`]s.
3865+ #[ inline]
3866+ pub fn new_readonly ( filtered_entity_mut : & FilteredEntityMut < ' w , ' s > ) -> Self {
3867+ Self {
3868+ entity : filtered_entity_mut. entity ,
3869+ access : filtered_entity_mut. access ,
3870+ }
3871+ }
3872+
3873+ /// Returns a new instance of [`FilteredEntityMut`].
3874+ ///
3875+ /// # Safety
3876+ /// - The user must ensure that no aliasing violations occur when using the returned `FilteredEntityMut`.
3877+ #[ inline]
3878+ pub unsafe fn into_mut ( self ) -> FilteredEntityMut < ' w , ' s > {
3879+ FilteredEntityMut :: new ( self . entity , self . access )
3880+ }
3881+ }
3882+
38273883/// Provides mutable access to a single entity and some of its components defined by the contained [`Access`].
38283884///
38293885/// To define the access when used as a [`QueryData`](crate::query::QueryData),
@@ -3847,6 +3903,8 @@ unsafe impl EntityEquivalent for FilteredEntityRef<'_, '_> {}
38473903/// let mut filtered_entity: FilteredEntityMut = query.single_mut(&mut world).unwrap();
38483904/// let component: Mut<A> = filtered_entity.get_mut().unwrap();
38493905/// ```
3906+ ///
3907+ /// Also see [`UnsafeFilteredEntityMut`] for a way to bypass borrow-checker restrictions.
38503908pub struct FilteredEntityMut < ' w , ' s > {
38513909 entity : UnsafeEntityCell < ' w > ,
38523910 access : & ' s Access ,
@@ -3962,17 +4020,70 @@ impl<'w, 's> FilteredEntityMut<'w, 's> {
39624020 }
39634021
39644022 /// Gets mutable access to the component of type `T` for the current entity.
3965- /// Returns `None` if the entity does not have a component of type `T`.
4023+ /// Returns `None` if the entity does not have a component of type `T` or if
4024+ /// the access does not include write access to `T`.
39664025 #[ inline]
39674026 pub fn get_mut < T : Component < Mutability = Mutable > > ( & mut self ) -> Option < Mut < ' _ , T > > {
4027+ // SAFETY: we use a mutable reference to self, so we cannot use the `FilteredEntityMut` to access
4028+ // another component
4029+ unsafe { self . get_mut_unchecked ( ) }
4030+ }
4031+
4032+ /// Gets mutable access to the component of type `T` for the current entity.
4033+ /// Returns `None` if the entity does not have a component of type `T` or if
4034+ /// the access does not include write access to `T`.
4035+ ///
4036+ /// This only requires `&self`, and so may be used to get mutable access to multiple components.
4037+ ///
4038+ /// # Example
4039+ ///
4040+ /// ```
4041+ /// # use bevy_ecs::{prelude::*, world::FilteredEntityMut};
4042+ /// #
4043+ /// #[derive(Component)]
4044+ /// struct X(usize);
4045+ /// #[derive(Component)]
4046+ /// struct Y(usize);
4047+ ///
4048+ /// # let mut world = World::default();
4049+ /// let mut entity = world.spawn((X(0), Y(0))).into_mutable();
4050+ ///
4051+ /// // This gives the `FilteredEntityMut` access to `&mut X` and `&mut Y`.
4052+ /// let mut query = QueryBuilder::<FilteredEntityMut>::new(&mut world)
4053+ /// .data::<(&mut X, &mut Y)>()
4054+ /// .build();
4055+ ///
4056+ /// let mut filtered_entity: FilteredEntityMut = query.single_mut(&mut world).unwrap();
4057+ ///
4058+ /// // Get mutable access to two components at once
4059+ /// // SAFETY: We don't take any other references to `X` from this entity
4060+ /// let mut x = unsafe { filtered_entity.get_mut_unchecked::<X>() }.unwrap();
4061+ /// // SAFETY: We don't take any other references to `Y` from this entity
4062+ /// let mut y = unsafe { filtered_entity.get_mut_unchecked::<Y>() }.unwrap();
4063+ /// *x = X(1);
4064+ /// *y = Y(1);
4065+ /// ```
4066+ ///
4067+ /// # Safety
4068+ ///
4069+ /// No other references to the same component may exist at the same time as the returned reference.
4070+ ///
4071+ /// # See also
4072+ ///
4073+ /// - [`get_mut`](Self::get_mut) for the safe version.
4074+ #[ inline]
4075+ pub unsafe fn get_mut_unchecked < T : Component < Mutability = Mutable > > (
4076+ & self ,
4077+ ) -> Option < Mut < ' _ , T > > {
39684078 let id = self
39694079 . entity
39704080 . world ( )
39714081 . components ( )
39724082 . get_valid_id ( TypeId :: of :: < T > ( ) ) ?;
39734083 self . access
39744084 . has_component_write ( id)
3975- // SAFETY: We have write access
4085+ // SAFETY: We have permission to access the component mutable
4086+ // and we promise to not create other references to the same component
39764087 . then ( || unsafe { self . entity . get_mut ( ) } )
39774088 . flatten ( )
39784089 }
@@ -4052,9 +4163,38 @@ impl<'w, 's> FilteredEntityMut<'w, 's> {
40524163 /// which is only valid while the [`FilteredEntityMut`] is alive.
40534164 #[ inline]
40544165 pub fn get_mut_by_id ( & mut self , component_id : ComponentId ) -> Option < MutUntyped < ' _ > > {
4166+ // SAFETY: we use a mutable reference to self, so we cannot use the `FilteredEntityMut` to access
4167+ // another component
4168+ unsafe { self . get_mut_by_id_unchecked ( component_id) }
4169+ }
4170+
4171+ /// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.
4172+ ///
4173+ /// **You should prefer to use the typed API [`Self::get_mut`] where possible and only
4174+ /// use this in cases where the actual component types are not known at
4175+ /// compile time.**
4176+ ///
4177+ /// Unlike [`FilteredEntityMut::get_mut`], this returns a raw pointer to the component,
4178+ /// which is only valid while the [`FilteredEntityMut`] is alive.
4179+ ///
4180+ /// This only requires `&self`, and so may be used to get mutable access to multiple components.
4181+ ///
4182+ /// # Safety
4183+ ///
4184+ /// No other references to the same component may exist at the same time as the returned reference.
4185+ ///
4186+ /// # See also
4187+ ///
4188+ /// - [`get_mut_by_id`](Self::get_mut_by_id) for the safe version.
4189+ #[ inline]
4190+ pub unsafe fn get_mut_by_id_unchecked (
4191+ & self ,
4192+ component_id : ComponentId ,
4193+ ) -> Option < MutUntyped < ' _ > > {
40554194 self . access
40564195 . has_component_write ( component_id)
4057- // SAFETY: We have write access
4196+ // SAFETY: We have permission to access the component mutable
4197+ // and we promise to not create other references to the same component
40584198 . then ( || unsafe { self . entity . get_mut_by_id ( component_id) . ok ( ) } )
40594199 . flatten ( )
40604200 }
0 commit comments