@@ -4,7 +4,7 @@ use crate::{
4
4
change_detection:: MutUntyped ,
5
5
component:: { Component , ComponentId , ComponentTicks , Components , StorageType } ,
6
6
entity:: { Entities , Entity , EntityLocation } ,
7
- query:: { Access , DebugCheckedUnwrap } ,
7
+ query:: Access ,
8
8
removal_detection:: RemovedComponentEvents ,
9
9
storage:: Storages ,
10
10
world:: { Mut , World } ,
@@ -1824,8 +1824,9 @@ impl<'w> FilteredEntityRef<'w> {
1824
1824
let id = self . entity . world ( ) . components ( ) . get_id ( TypeId :: of :: < T > ( ) ) ?;
1825
1825
self . access
1826
1826
. has_read ( id)
1827
- // SAFETY: We have read access so we must have the component
1828
- . then ( || unsafe { self . entity . get ( ) . debug_checked_unwrap ( ) } )
1827
+ // SAFETY: We have read access
1828
+ . then ( || unsafe { self . entity . get ( ) } )
1829
+ . flatten ( )
1829
1830
}
1830
1831
1831
1832
/// Gets access to the component of type `T` for the current entity,
@@ -1837,8 +1838,9 @@ impl<'w> FilteredEntityRef<'w> {
1837
1838
let id = self . entity . world ( ) . components ( ) . get_id ( TypeId :: of :: < T > ( ) ) ?;
1838
1839
self . access
1839
1840
. has_read ( id)
1840
- // SAFETY: We have read access so we must have the component
1841
- . then ( || unsafe { self . entity . get_ref ( ) . debug_checked_unwrap ( ) } )
1841
+ // SAFETY: We have read access
1842
+ . then ( || unsafe { self . entity . get_ref ( ) } )
1843
+ . flatten ( )
1842
1844
}
1843
1845
1844
1846
/// Retrieves the change ticks for the given component. This can be useful for implementing change
@@ -1848,8 +1850,9 @@ impl<'w> FilteredEntityRef<'w> {
1848
1850
let id = self . entity . world ( ) . components ( ) . get_id ( TypeId :: of :: < T > ( ) ) ?;
1849
1851
self . access
1850
1852
. has_read ( id)
1851
- // SAFETY: We have read access so we must have the component
1852
- . then ( || unsafe { self . entity . get_change_ticks :: < T > ( ) . debug_checked_unwrap ( ) } )
1853
+ // SAFETY: We have read access
1854
+ . then ( || unsafe { self . entity . get_change_ticks :: < T > ( ) } )
1855
+ . flatten ( )
1853
1856
}
1854
1857
1855
1858
/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
@@ -1860,12 +1863,11 @@ impl<'w> FilteredEntityRef<'w> {
1860
1863
/// compile time.**
1861
1864
#[ inline]
1862
1865
pub fn get_change_ticks_by_id ( & self , component_id : ComponentId ) -> Option < ComponentTicks > {
1863
- // SAFETY: We have read access so we must have the component
1864
- self . access . has_read ( component_id) . then ( || unsafe {
1865
- self . entity
1866
- . get_change_ticks_by_id ( component_id)
1867
- . debug_checked_unwrap ( )
1868
- } )
1866
+ self . access
1867
+ . has_read ( component_id)
1868
+ // SAFETY: We have read access
1869
+ . then ( || unsafe { self . entity . get_change_ticks_by_id ( component_id) } )
1870
+ . flatten ( )
1869
1871
}
1870
1872
1871
1873
/// Gets the component of the given [`ComponentId`] from the entity.
@@ -1880,8 +1882,9 @@ impl<'w> FilteredEntityRef<'w> {
1880
1882
pub fn get_by_id ( & self , component_id : ComponentId ) -> Option < Ptr < ' w > > {
1881
1883
self . access
1882
1884
. has_read ( component_id)
1883
- // SAFETY: We have read access so we must have the component
1884
- . then ( || unsafe { self . entity . get_by_id ( component_id) . debug_checked_unwrap ( ) } )
1885
+ // SAFETY: We have read access
1886
+ . then ( || unsafe { self . entity . get_by_id ( component_id) } )
1887
+ . flatten ( )
1885
1888
}
1886
1889
}
1887
1890
@@ -2094,8 +2097,9 @@ impl<'w> FilteredEntityMut<'w> {
2094
2097
let id = self . entity . world ( ) . components ( ) . get_id ( TypeId :: of :: < T > ( ) ) ?;
2095
2098
self . access
2096
2099
. has_write ( id)
2097
- // SAFETY: We have write access so we must have the component
2098
- . then ( || unsafe { self . entity . get_mut ( ) . debug_checked_unwrap ( ) } )
2100
+ // SAFETY: We have write access
2101
+ . then ( || unsafe { self . entity . get_mut ( ) } )
2102
+ . flatten ( )
2099
2103
}
2100
2104
2101
2105
/// Retrieves the change ticks for the given component. This can be useful for implementing change
@@ -2139,12 +2143,11 @@ impl<'w> FilteredEntityMut<'w> {
2139
2143
/// which is only valid while the [`FilteredEntityMut`] is alive.
2140
2144
#[ inline]
2141
2145
pub fn get_mut_by_id ( & mut self , component_id : ComponentId ) -> Option < MutUntyped < ' _ > > {
2142
- // SAFETY: We have write access so we must have the component
2143
- self . access . has_write ( component_id) . then ( || unsafe {
2144
- self . entity
2145
- . get_mut_by_id ( component_id)
2146
- . debug_checked_unwrap ( )
2147
- } )
2146
+ self . access
2147
+ . has_write ( component_id)
2148
+ // SAFETY: We have write access
2149
+ . then ( || unsafe { self . entity . get_mut_by_id ( component_id) } )
2150
+ . flatten ( )
2148
2151
}
2149
2152
}
2150
2153
@@ -2416,6 +2419,7 @@ mod tests {
2416
2419
use bevy_ptr:: OwningPtr ;
2417
2420
use std:: panic:: AssertUnwindSafe ;
2418
2421
2422
+ use crate :: world:: { FilteredEntityMut , FilteredEntityRef } ;
2419
2423
use crate :: { self as bevy_ecs, component:: ComponentId , prelude:: * , system:: assert_is_system} ;
2420
2424
2421
2425
#[ test]
@@ -2918,4 +2922,64 @@ mod tests {
2918
2922
2919
2923
assert_is_system ( incompatible_system) ;
2920
2924
}
2925
+
2926
+ #[ test]
2927
+ fn filtered_entity_ref_normal ( ) {
2928
+ let mut world = World :: new ( ) ;
2929
+ let a_id = world. init_component :: < A > ( ) ;
2930
+
2931
+ let e: FilteredEntityRef = world. spawn ( A ) . into ( ) ;
2932
+
2933
+ assert ! ( e. get:: <A >( ) . is_some( ) ) ;
2934
+ assert ! ( e. get_ref:: <A >( ) . is_some( ) ) ;
2935
+ assert ! ( e. get_change_ticks:: <A >( ) . is_some( ) ) ;
2936
+ assert ! ( e. get_by_id( a_id) . is_some( ) ) ;
2937
+ assert ! ( e. get_change_ticks_by_id( a_id) . is_some( ) ) ;
2938
+ }
2939
+
2940
+ #[ test]
2941
+ fn filtered_entity_ref_missing ( ) {
2942
+ let mut world = World :: new ( ) ;
2943
+ let a_id = world. init_component :: < A > ( ) ;
2944
+
2945
+ let e: FilteredEntityRef = world. spawn ( ( ) ) . into ( ) ;
2946
+
2947
+ assert ! ( e. get:: <A >( ) . is_none( ) ) ;
2948
+ assert ! ( e. get_ref:: <A >( ) . is_none( ) ) ;
2949
+ assert ! ( e. get_change_ticks:: <A >( ) . is_none( ) ) ;
2950
+ assert ! ( e. get_by_id( a_id) . is_none( ) ) ;
2951
+ assert ! ( e. get_change_ticks_by_id( a_id) . is_none( ) ) ;
2952
+ }
2953
+
2954
+ #[ test]
2955
+ fn filtered_entity_mut_normal ( ) {
2956
+ let mut world = World :: new ( ) ;
2957
+ let a_id = world. init_component :: < A > ( ) ;
2958
+
2959
+ let mut e: FilteredEntityMut = world. spawn ( A ) . into ( ) ;
2960
+
2961
+ assert ! ( e. get:: <A >( ) . is_some( ) ) ;
2962
+ assert ! ( e. get_ref:: <A >( ) . is_some( ) ) ;
2963
+ assert ! ( e. get_mut:: <A >( ) . is_some( ) ) ;
2964
+ assert ! ( e. get_change_ticks:: <A >( ) . is_some( ) ) ;
2965
+ assert ! ( e. get_by_id( a_id) . is_some( ) ) ;
2966
+ assert ! ( e. get_mut_by_id( a_id) . is_some( ) ) ;
2967
+ assert ! ( e. get_change_ticks_by_id( a_id) . is_some( ) ) ;
2968
+ }
2969
+
2970
+ #[ test]
2971
+ fn filtered_entity_mut_missing ( ) {
2972
+ let mut world = World :: new ( ) ;
2973
+ let a_id = world. init_component :: < A > ( ) ;
2974
+
2975
+ let mut e: FilteredEntityMut = world. spawn ( ( ) ) . into ( ) ;
2976
+
2977
+ assert ! ( e. get:: <A >( ) . is_none( ) ) ;
2978
+ assert ! ( e. get_ref:: <A >( ) . is_none( ) ) ;
2979
+ assert ! ( e. get_mut:: <A >( ) . is_none( ) ) ;
2980
+ assert ! ( e. get_change_ticks:: <A >( ) . is_none( ) ) ;
2981
+ assert ! ( e. get_by_id( a_id) . is_none( ) ) ;
2982
+ assert ! ( e. get_mut_by_id( a_id) . is_none( ) ) ;
2983
+ assert ! ( e. get_change_ticks_by_id( a_id) . is_none( ) ) ;
2984
+ }
2921
2985
}
0 commit comments