1
1
use crate :: {
2
2
archetype:: { Archetype , ArchetypeId , Archetypes } ,
3
3
bundle:: { Bundle , BundleInfo } ,
4
- change_detection:: { MutUntyped , TicksMut } ,
5
- component:: {
6
- Component , ComponentId , ComponentStorage , ComponentTicks , Components , StorageType ,
7
- } ,
4
+ change_detection:: MutUntyped ,
5
+ component:: { Component , ComponentId , ComponentTicks , Components , StorageType } ,
8
6
entity:: { Entities , Entity , EntityLocation } ,
9
7
storage:: { SparseSet , Storages } ,
10
8
world:: { Mut , World } ,
@@ -78,12 +76,22 @@ impl<'w> EntityRef<'w> {
78
76
79
77
#[ inline]
80
78
pub fn contains_id ( & self , component_id : ComponentId ) -> bool {
81
- contains_component_with_id ( self . world , component_id, self . location )
79
+ // SAFETY:
80
+ // - `EntityRef` existing requires there not to be a `&mut World`
81
+ unsafe {
82
+ self . as_unsafe_world_cell_readonly ( )
83
+ . contains_id ( component_id)
84
+ }
82
85
}
83
86
84
87
#[ inline]
85
88
pub fn contains_type_id ( & self , type_id : TypeId ) -> bool {
86
- contains_component_with_type ( self . world , type_id, self . location )
89
+ // SAFETY:
90
+ // - `EntityRef` existing requires there not to be a `&mut World`
91
+ unsafe {
92
+ self . as_unsafe_world_cell_readonly ( )
93
+ . contains_type_id ( type_id)
94
+ }
87
95
}
88
96
89
97
#[ inline]
@@ -208,12 +216,22 @@ impl<'w> EntityMut<'w> {
208
216
209
217
#[ inline]
210
218
pub fn contains_id ( & self , component_id : ComponentId ) -> bool {
211
- contains_component_with_id ( self . world , component_id, self . location )
219
+ // SAFETY:
220
+ // - `EntityMut` has exclusive access on world so noone else can have a `&mut World`
221
+ unsafe {
222
+ self . as_unsafe_world_cell_readonly ( )
223
+ . contains_id ( component_id)
224
+ }
212
225
}
213
226
214
227
#[ inline]
215
228
pub fn contains_type_id ( & self , type_id : TypeId ) -> bool {
216
- contains_component_with_type ( self . world , type_id, self . location )
229
+ // SAFETY:
230
+ // - `EntityMut` has exclusive access on world so noone else can have a `&mut World`
231
+ unsafe {
232
+ self . as_unsafe_world_cell_readonly ( )
233
+ . contains_type_id ( type_id)
234
+ }
217
235
}
218
236
219
237
#[ inline]
@@ -564,19 +582,10 @@ impl<'w> EntityMut<'w> {
564
582
/// which is only valid while the [`EntityMut`] is alive.
565
583
#[ inline]
566
584
pub fn get_by_id ( & self , component_id : ComponentId ) -> Option < Ptr < ' _ > > {
567
- let info = self . world . components ( ) . get_info ( component_id) ?;
568
585
// SAFETY:
569
- // - entity_location is valid
570
- // - component_id is valid as checked by the line above
571
- // - the storage type is accurate as checked by the fetched ComponentInfo
572
- unsafe {
573
- self . world . get_component (
574
- component_id,
575
- info. storage_type ( ) ,
576
- self . entity ,
577
- self . location ,
578
- )
579
- }
586
+ // - `&self` ensures that no mutable references exist to this entity's components.
587
+ // - `as_unsafe_world_cell_readonly` gives read only permission for all components on this entity
588
+ unsafe { self . as_unsafe_world_cell_readonly ( ) . get_by_id ( component_id) }
580
589
}
581
590
582
591
/// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.
@@ -589,32 +598,13 @@ impl<'w> EntityMut<'w> {
589
598
/// which is only valid while the [`EntityMut`] is alive.
590
599
#[ inline]
591
600
pub fn get_mut_by_id ( & mut self , component_id : ComponentId ) -> Option < MutUntyped < ' _ > > {
592
- self . world . components ( ) . get_info ( component_id) ?;
593
- // SAFETY: entity_location is valid, component_id is valid as checked by the line above
594
- unsafe { get_mut_by_id ( self . world , self . entity , self . location , component_id) }
595
- }
596
- }
597
-
598
- pub ( crate ) fn contains_component_with_type (
599
- world : & World ,
600
- type_id : TypeId ,
601
- location : EntityLocation ,
602
- ) -> bool {
603
- if let Some ( component_id) = world. components . get_id ( type_id) {
604
- contains_component_with_id ( world, component_id, location)
605
- } else {
606
- false
601
+ // SAFETY:
602
+ // - `&mut self` ensures that no references exist to this entity's components.
603
+ // - `as_unsafe_world_cell` gives mutable permission for all components on this entity
604
+ unsafe { self . as_unsafe_world_cell ( ) . get_mut_by_id ( component_id) }
607
605
}
608
606
}
609
607
610
- pub ( crate ) fn contains_component_with_id (
611
- world : & World ,
612
- component_id : ComponentId ,
613
- location : EntityLocation ,
614
- ) -> bool {
615
- world. archetypes [ location. archetype_id ] . contains ( component_id)
616
- }
617
-
618
608
/// Removes a bundle from the given archetype and returns the resulting archetype (or None if the
619
609
/// removal was invalid). in the event that adding the given bundle does not result in an Archetype
620
610
/// change. Results are cached in the Archetype Graph to avoid redundant work.
@@ -732,59 +722,6 @@ fn sorted_remove<T: Eq + Ord + Copy>(source: &mut Vec<T>, remove: &[T]) {
732
722
} ) ;
733
723
}
734
724
735
- // SAFETY: EntityLocation must be valid
736
- #[ inline]
737
- pub ( crate ) unsafe fn get_mut < T : Component > (
738
- world : & mut World ,
739
- entity : Entity ,
740
- location : EntityLocation ,
741
- ) -> Option < Mut < ' _ , T > > {
742
- let change_tick = world. change_tick ( ) ;
743
- let last_change_tick = world. last_change_tick ( ) ;
744
- // SAFETY:
745
- // - world access is unique
746
- // - entity location is valid
747
- // - returned component is of type T
748
- world
749
- . get_component_and_ticks_with_type (
750
- TypeId :: of :: < T > ( ) ,
751
- T :: Storage :: STORAGE_TYPE ,
752
- entity,
753
- location,
754
- )
755
- . map ( |( value, ticks) | Mut {
756
- // SAFETY:
757
- // - world access is unique and ties world lifetime to `Mut` lifetime
758
- // - `value` is of type `T`
759
- value : value. assert_unique ( ) . deref_mut :: < T > ( ) ,
760
- ticks : TicksMut :: from_tick_cells ( ticks, last_change_tick, change_tick) ,
761
- } )
762
- }
763
-
764
- // SAFETY: EntityLocation must be valid, component_id must be valid
765
- #[ inline]
766
- pub ( crate ) unsafe fn get_mut_by_id (
767
- world : & mut World ,
768
- entity : Entity ,
769
- location : EntityLocation ,
770
- component_id : ComponentId ,
771
- ) -> Option < MutUntyped < ' _ > > {
772
- let change_tick = world. change_tick ( ) ;
773
- // SAFETY: component_id is valid
774
- let info = world. components . get_info_unchecked ( component_id) ;
775
- // SAFETY:
776
- // - world access is unique
777
- // - entity location is valid
778
- // - returned component is of type T
779
- world
780
- . get_component_and_ticks ( component_id, info. storage_type ( ) , entity, location)
781
- . map ( |( value, ticks) | MutUntyped {
782
- // SAFETY: world access is unique and ties world lifetime to `MutUntyped` lifetime
783
- value : value. assert_unique ( ) ,
784
- ticks : TicksMut :: from_tick_cells ( ticks, world. last_change_tick ( ) , change_tick) ,
785
- } )
786
- }
787
-
788
725
/// Moves component data out of storage.
789
726
///
790
727
/// This function leaves the underlying memory unchanged, but the component behind
0 commit comments