@@ -3287,6 +3287,24 @@ impl<'a> From<&'a EntityWorldMut<'_>> for FilteredEntityRef<'a> {
3287
3287
}
3288
3288
}
3289
3289
3290
+ impl < ' a , B : Bundle > From < & ' a EntityRefExcept < ' _ , B > > for FilteredEntityRef < ' a > {
3291
+ fn from ( value : & ' a EntityRefExcept < ' _ , B > ) -> Self {
3292
+ // SAFETY:
3293
+ // - The FilteredEntityRef has the same component access as the given EntityRefExcept.
3294
+ unsafe {
3295
+ let mut access = Access :: default ( ) ;
3296
+ access. read_all ( ) ;
3297
+ let components = value. entity . world ( ) . components ( ) ;
3298
+ B :: get_component_ids ( components, & mut |maybe_id| {
3299
+ if let Some ( id) = maybe_id {
3300
+ access. remove_component_read ( id) ;
3301
+ }
3302
+ } ) ;
3303
+ FilteredEntityRef :: new ( value. entity , access)
3304
+ }
3305
+ }
3306
+ }
3307
+
3290
3308
impl PartialEq for FilteredEntityRef < ' _ > {
3291
3309
fn eq ( & self , other : & Self ) -> bool {
3292
3310
self . entity ( ) == other. entity ( )
@@ -3612,6 +3630,24 @@ impl<'a> From<&'a mut EntityWorldMut<'_>> for FilteredEntityMut<'a> {
3612
3630
}
3613
3631
}
3614
3632
3633
+ impl < ' a , B : Bundle > From < & ' a EntityMutExcept < ' _ , B > > for FilteredEntityMut < ' a > {
3634
+ fn from ( value : & ' a EntityMutExcept < ' _ , B > ) -> Self {
3635
+ // SAFETY:
3636
+ // - The FilteredEntityMut has the same component access as the given EntityMutExcept.
3637
+ unsafe {
3638
+ let mut access = Access :: default ( ) ;
3639
+ access. write_all ( ) ;
3640
+ let components = value. entity . world ( ) . components ( ) ;
3641
+ B :: get_component_ids ( components, & mut |maybe_id| {
3642
+ if let Some ( id) = maybe_id {
3643
+ access. remove_component_read ( id) ;
3644
+ }
3645
+ } ) ;
3646
+ FilteredEntityMut :: new ( value. entity , access)
3647
+ }
3648
+ }
3649
+ }
3650
+
3615
3651
impl PartialEq for FilteredEntityMut < ' _ > {
3616
3652
fn eq ( & self , other : & Self ) -> bool {
3617
3653
self . entity ( ) == other. entity ( )
@@ -3737,6 +3773,93 @@ where
3737
3773
pub fn spawned_by ( & self ) -> MaybeLocation {
3738
3774
self . entity . spawned_by ( )
3739
3775
}
3776
+
3777
+ /// Gets the component of the given [`ComponentId`] from the entity.
3778
+ ///
3779
+ /// **You should prefer to use the typed API [`Self::get`] where possible and only
3780
+ /// use this in cases where the actual component types are not known at
3781
+ /// compile time.**
3782
+ ///
3783
+ /// Unlike [`EntityRefExcept::get`], this returns a raw pointer to the component,
3784
+ /// which is only valid while the [`EntityRefExcept`] is alive.
3785
+ #[ inline]
3786
+ pub fn get_by_id ( & self , component_id : ComponentId ) -> Option < Ptr < ' w > > {
3787
+ let components = self . entity . world ( ) . components ( ) ;
3788
+ ( !bundle_contains_component :: < B > ( components, component_id) )
3789
+ . then ( || {
3790
+ // SAFETY: We have read access for this component
3791
+ unsafe { self . entity . get_by_id ( component_id) }
3792
+ } )
3793
+ . flatten ( )
3794
+ }
3795
+
3796
+ /// Returns `true` if the current entity has a component of type `T`.
3797
+ /// Otherwise, this returns `false`.
3798
+ ///
3799
+ /// ## Notes
3800
+ ///
3801
+ /// If you do not know the concrete type of a component, consider using
3802
+ /// [`Self::contains_id`] or [`Self::contains_type_id`].
3803
+ #[ inline]
3804
+ pub fn contains < T : Component > ( & self ) -> bool {
3805
+ self . contains_type_id ( TypeId :: of :: < T > ( ) )
3806
+ }
3807
+
3808
+ /// Returns `true` if the current entity has a component identified by `component_id`.
3809
+ /// Otherwise, this returns false.
3810
+ ///
3811
+ /// ## Notes
3812
+ ///
3813
+ /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
3814
+ /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
3815
+ /// [`Self::contains_type_id`].
3816
+ #[ inline]
3817
+ pub fn contains_id ( & self , component_id : ComponentId ) -> bool {
3818
+ self . entity . contains_id ( component_id)
3819
+ }
3820
+
3821
+ /// Returns `true` if the current entity has a component with the type identified by `type_id`.
3822
+ /// Otherwise, this returns false.
3823
+ ///
3824
+ /// ## Notes
3825
+ ///
3826
+ /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
3827
+ /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
3828
+ #[ inline]
3829
+ pub fn contains_type_id ( & self , type_id : TypeId ) -> bool {
3830
+ self . entity . contains_type_id ( type_id)
3831
+ }
3832
+
3833
+ /// Retrieves the change ticks for the given component. This can be useful for implementing change
3834
+ /// detection in custom runtimes.
3835
+ #[ inline]
3836
+ pub fn get_change_ticks < T : Component > ( & self ) -> Option < ComponentTicks > {
3837
+ let component_id = self . entity . world ( ) . components ( ) . get_id ( TypeId :: of :: < T > ( ) ) ?;
3838
+ let components = self . entity . world ( ) . components ( ) ;
3839
+ ( !bundle_contains_component :: < B > ( components, component_id) )
3840
+ . then ( || {
3841
+ // SAFETY: We have read access
3842
+ unsafe { self . entity . get_change_ticks :: < T > ( ) }
3843
+ } )
3844
+ . flatten ( )
3845
+ }
3846
+
3847
+ /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
3848
+ /// detection in custom runtimes.
3849
+ ///
3850
+ /// **You should prefer to use the typed API [`Self::get_change_ticks`] where possible and only
3851
+ /// use this in cases where the actual component types are not known at
3852
+ /// compile time.**
3853
+ #[ inline]
3854
+ pub fn get_change_ticks_by_id ( & self , component_id : ComponentId ) -> Option < ComponentTicks > {
3855
+ let components = self . entity . world ( ) . components ( ) ;
3856
+ ( !bundle_contains_component :: < B > ( components, component_id) )
3857
+ . then ( || {
3858
+ // SAFETY: We have read access
3859
+ unsafe { self . entity . get_change_ticks_by_id ( component_id) }
3860
+ } )
3861
+ . flatten ( )
3862
+ }
3740
3863
}
3741
3864
3742
3865
impl < ' a , B > From < & ' a EntityMutExcept < ' _ , B > > for EntityRefExcept < ' a , B >
@@ -3894,6 +4017,78 @@ where
3894
4017
pub fn spawned_by ( & self ) -> MaybeLocation {
3895
4018
self . entity . spawned_by ( )
3896
4019
}
4020
+
4021
+ /// Returns `true` if the current entity has a component of type `T`.
4022
+ /// Otherwise, this returns `false`.
4023
+ ///
4024
+ /// ## Notes
4025
+ ///
4026
+ /// If you do not know the concrete type of a component, consider using
4027
+ /// [`Self::contains_id`] or [`Self::contains_type_id`].
4028
+ #[ inline]
4029
+ pub fn contains < T : Component > ( & self ) -> bool {
4030
+ self . contains_type_id ( TypeId :: of :: < T > ( ) )
4031
+ }
4032
+
4033
+ /// Returns `true` if the current entity has a component identified by `component_id`.
4034
+ /// Otherwise, this returns false.
4035
+ ///
4036
+ /// ## Notes
4037
+ ///
4038
+ /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
4039
+ /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
4040
+ /// [`Self::contains_type_id`].
4041
+ #[ inline]
4042
+ pub fn contains_id ( & self , component_id : ComponentId ) -> bool {
4043
+ self . entity . contains_id ( component_id)
4044
+ }
4045
+
4046
+ /// Returns `true` if the current entity has a component with the type identified by `type_id`.
4047
+ /// Otherwise, this returns false.
4048
+ ///
4049
+ /// ## Notes
4050
+ ///
4051
+ /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
4052
+ /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
4053
+ #[ inline]
4054
+ pub fn contains_type_id ( & self , type_id : TypeId ) -> bool {
4055
+ self . entity . contains_type_id ( type_id)
4056
+ }
4057
+
4058
+ /// Gets the component of the given [`ComponentId`] from the entity.
4059
+ ///
4060
+ /// **You should prefer to use the typed API [`Self::get`] where possible and only
4061
+ /// use this in cases where the actual component types are not known at
4062
+ /// compile time.**
4063
+ ///
4064
+ /// Unlike [`EntityMutExcept::get`], this returns a raw pointer to the component,
4065
+ /// which is only valid while the [`EntityMutExcept`] is alive.
4066
+ #[ inline]
4067
+ pub fn get_by_id ( & ' w self , component_id : ComponentId ) -> Option < Ptr < ' w > > {
4068
+ self . as_readonly ( ) . get_by_id ( component_id)
4069
+ }
4070
+
4071
+ /// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.
4072
+ ///
4073
+ /// **You should prefer to use the typed API [`Self::get_mut`] where possible and only
4074
+ /// use this in cases where the actual component types are not known at
4075
+ /// compile time.**
4076
+ ///
4077
+ /// Unlike [`EntityMutExcept::get_mut`], this returns a raw pointer to the component,
4078
+ /// which is only valid while the [`EntityMutExcept`] is alive.
4079
+ #[ inline]
4080
+ pub fn get_mut_by_id < F : DynamicComponentFetch > (
4081
+ & mut self ,
4082
+ component_id : ComponentId ,
4083
+ ) -> Option < MutUntyped < ' _ > > {
4084
+ let components = self . entity . world ( ) . components ( ) ;
4085
+ ( !bundle_contains_component :: < B > ( components, component_id) )
4086
+ . then ( || {
4087
+ // SAFETY: We have write access
4088
+ unsafe { self . entity . get_mut_by_id ( component_id) . ok ( ) }
4089
+ } )
4090
+ . flatten ( )
4091
+ }
3897
4092
}
3898
4093
3899
4094
impl < B : Bundle > PartialEq for EntityMutExcept < ' _ , B > {
0 commit comments