@@ -3824,6 +3824,62 @@ impl ContainsEntity for FilteredEntityRef<'_, '_> {
3824
3824
// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
3825
3825
unsafe impl EntityEquivalent for FilteredEntityRef < ' _ , ' _ > { }
3826
3826
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
+
3827
3883
/// Provides mutable access to a single entity and some of its components defined by the contained [`Access`].
3828
3884
///
3829
3885
/// To define the access when used as a [`QueryData`](crate::query::QueryData),
@@ -3847,6 +3903,8 @@ unsafe impl EntityEquivalent for FilteredEntityRef<'_, '_> {}
3847
3903
/// let mut filtered_entity: FilteredEntityMut = query.single_mut(&mut world).unwrap();
3848
3904
/// let component: Mut<A> = filtered_entity.get_mut().unwrap();
3849
3905
/// ```
3906
+ ///
3907
+ /// Also see [`UnsafeFilteredEntityMut`] for a way to bypass borrow-checker restrictions.
3850
3908
pub struct FilteredEntityMut < ' w , ' s > {
3851
3909
entity : UnsafeEntityCell < ' w > ,
3852
3910
access : & ' s Access ,
@@ -3962,17 +4020,70 @@ impl<'w, 's> FilteredEntityMut<'w, 's> {
3962
4020
}
3963
4021
3964
4022
/// 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`.
3966
4025
#[ inline]
3967
4026
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 > > {
3968
4078
let id = self
3969
4079
. entity
3970
4080
. world ( )
3971
4081
. components ( )
3972
4082
. get_valid_id ( TypeId :: of :: < T > ( ) ) ?;
3973
4083
self . access
3974
4084
. 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
3976
4087
. then ( || unsafe { self . entity . get_mut ( ) } )
3977
4088
. flatten ( )
3978
4089
}
@@ -4052,9 +4163,38 @@ impl<'w, 's> FilteredEntityMut<'w, 's> {
4052
4163
/// which is only valid while the [`FilteredEntityMut`] is alive.
4053
4164
#[ inline]
4054
4165
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 < ' _ > > {
4055
4194
self . access
4056
4195
. 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
4058
4198
. then ( || unsafe { self . entity . get_mut_by_id ( component_id) . ok ( ) } )
4059
4199
. flatten ( )
4060
4200
}
0 commit comments