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]
@@ -603,19 +621,10 @@ impl<'w> EntityMut<'w> {
603
621
/// which is only valid while the [`EntityMut`] is alive.
604
622
#[ inline]
605
623
pub fn get_by_id ( & self , component_id : ComponentId ) -> Option < Ptr < ' _ > > {
606
- let info = self . world . components ( ) . get_info ( component_id) ?;
607
624
// SAFETY:
608
- // - entity_location is valid
609
- // - component_id is valid as checked by the line above
610
- // - the storage type is accurate as checked by the fetched ComponentInfo
611
- unsafe {
612
- self . world . get_component (
613
- component_id,
614
- info. storage_type ( ) ,
615
- self . entity ,
616
- self . location ,
617
- )
618
- }
625
+ // - `&self` ensures that no mutable references exist to this entity's components.
626
+ // - `as_unsafe_world_cell_readonly` gives read only permission for all components on this entity
627
+ unsafe { self . as_unsafe_world_cell_readonly ( ) . get_by_id ( component_id) }
619
628
}
620
629
621
630
/// Gets a [`MutUntyped`] of the component of the given [`ComponentId`] from the entity.
@@ -628,32 +637,13 @@ impl<'w> EntityMut<'w> {
628
637
/// which is only valid while the [`EntityMut`] is alive.
629
638
#[ inline]
630
639
pub fn get_mut_by_id ( & mut self , component_id : ComponentId ) -> Option < MutUntyped < ' _ > > {
631
- self . world . components ( ) . get_info ( component_id) ?;
632
- // SAFETY: entity_location is valid, component_id is valid as checked by the line above
633
- unsafe { get_mut_by_id ( self . world , self . entity , self . location , component_id) }
634
- }
635
- }
636
-
637
- pub ( crate ) fn contains_component_with_type (
638
- world : & World ,
639
- type_id : TypeId ,
640
- location : EntityLocation ,
641
- ) -> bool {
642
- if let Some ( component_id) = world. components . get_id ( type_id) {
643
- contains_component_with_id ( world, component_id, location)
644
- } else {
645
- false
640
+ // SAFETY:
641
+ // - `&mut self` ensures that no references exist to this entity's components.
642
+ // - `as_unsafe_world_cell` gives mutable permission for all components on this entity
643
+ unsafe { self . as_unsafe_world_cell ( ) . get_mut_by_id ( component_id) }
646
644
}
647
645
}
648
646
649
- pub ( crate ) fn contains_component_with_id (
650
- world : & World ,
651
- component_id : ComponentId ,
652
- location : EntityLocation ,
653
- ) -> bool {
654
- world. archetypes [ location. archetype_id ] . contains ( component_id)
655
- }
656
-
657
647
/// Removes a bundle from the given archetype and returns the resulting archetype (or None if the
658
648
/// removal was invalid). in the event that adding the given bundle does not result in an Archetype
659
649
/// change. Results are cached in the Archetype Graph to avoid redundant work.
@@ -771,59 +761,6 @@ fn sorted_remove<T: Eq + Ord + Copy>(source: &mut Vec<T>, remove: &[T]) {
771
761
} ) ;
772
762
}
773
763
774
- // SAFETY: EntityLocation must be valid
775
- #[ inline]
776
- pub ( crate ) unsafe fn get_mut < T : Component > (
777
- world : & mut World ,
778
- entity : Entity ,
779
- location : EntityLocation ,
780
- ) -> Option < Mut < ' _ , T > > {
781
- let change_tick = world. change_tick ( ) ;
782
- let last_change_tick = world. last_change_tick ( ) ;
783
- // SAFETY:
784
- // - world access is unique
785
- // - entity location is valid
786
- // - returned component is of type T
787
- world
788
- . get_component_and_ticks_with_type (
789
- TypeId :: of :: < T > ( ) ,
790
- T :: Storage :: STORAGE_TYPE ,
791
- entity,
792
- location,
793
- )
794
- . map ( |( value, ticks) | Mut {
795
- // SAFETY:
796
- // - world access is unique and ties world lifetime to `Mut` lifetime
797
- // - `value` is of type `T`
798
- value : value. assert_unique ( ) . deref_mut :: < T > ( ) ,
799
- ticks : TicksMut :: from_tick_cells ( ticks, last_change_tick, change_tick) ,
800
- } )
801
- }
802
-
803
- // SAFETY: EntityLocation must be valid, component_id must be valid
804
- #[ inline]
805
- pub ( crate ) unsafe fn get_mut_by_id (
806
- world : & mut World ,
807
- entity : Entity ,
808
- location : EntityLocation ,
809
- component_id : ComponentId ,
810
- ) -> Option < MutUntyped < ' _ > > {
811
- let change_tick = world. change_tick ( ) ;
812
- // SAFETY: component_id is valid
813
- let info = world. components . get_info_unchecked ( component_id) ;
814
- // SAFETY:
815
- // - world access is unique
816
- // - entity location is valid
817
- // - returned component is of type T
818
- world
819
- . get_component_and_ticks ( component_id, info. storage_type ( ) , entity, location)
820
- . map ( |( value, ticks) | MutUntyped {
821
- // SAFETY: world access is unique and ties world lifetime to `MutUntyped` lifetime
822
- value : value. assert_unique ( ) ,
823
- ticks : TicksMut :: from_tick_cells ( ticks, world. last_change_tick ( ) , change_tick) ,
824
- } )
825
- }
826
-
827
764
/// Moves component data out of storage.
828
765
///
829
766
/// This function leaves the underlying memory unchanged, but the component behind
0 commit comments