@@ -189,6 +189,31 @@ impl<'w> EntityRef<'w> {
189
189
)
190
190
}
191
191
}
192
+
193
+ /// Gets the component of the given [`ComponentId`] from the entity.
194
+ ///
195
+ /// **You should prefer to use the typed API where possible and only
196
+ /// use this in cases where the actual component types are not known at
197
+ /// compile time.**
198
+ ///
199
+ /// Unlike [`EntityRef::get`], this returns a raw pointer to the component,
200
+ /// which is only valid while the `'w` borrow of the lifetime is active.
201
+ ///
202
+ /// # Safety
203
+ ///
204
+ /// - The returned reference must never alias a mutable borrow of this component.
205
+ /// - The returned reference must not be used after this component is moved which
206
+ /// may happen from **any** `insert_component`, `remove_component` or `despawn`
207
+ /// operation on this world (non-exhaustive list).
208
+ #[ inline]
209
+ pub unsafe fn get_unchecked_mut_by_id (
210
+ & self ,
211
+ component_id : ComponentId ,
212
+ ) -> Option < MutUntyped < ' w > > {
213
+ self . world . components ( ) . get_info ( component_id) ?;
214
+ // SAFETY: entity_location is valid, component_id is valid as checked by the line above, world access is promised by the caller
215
+ get_mut_by_id ( self . world , self . entity , self . location , component_id)
216
+ }
192
217
}
193
218
194
219
impl < ' w > From < EntityMut < ' w > > for EntityRef < ' w > {
@@ -692,7 +717,7 @@ impl<'w> EntityMut<'w> {
692
717
#[ inline]
693
718
pub fn get_mut_by_id ( & mut self , component_id : ComponentId ) -> Option < MutUntyped < ' _ > > {
694
719
self . world . components ( ) . get_info ( component_id) ?;
695
- // SAFETY: entity_location is valid, component_id is valid as checked by the line above
720
+ // SAFETY: entity_location is valid, component_id is valid as checked by the line above, world access is unique
696
721
unsafe { get_mut_by_id ( self . world , self . entity , self . location , component_id) }
697
722
}
698
723
}
@@ -1064,21 +1089,26 @@ pub(crate) unsafe fn get_mut<T: Component>(
1064
1089
} )
1065
1090
}
1066
1091
1067
- // SAFETY: EntityLocation must be valid, component_id must be valid
1092
+ // SAFETY:
1093
+ // - EntityLocation must be valid, component_id must be valid
1094
+ // - world access to the component must be valid, either because the caller has a `&mut` world or it synchronizes access like systems do
1068
1095
#[ inline]
1069
1096
pub ( crate ) unsafe fn get_mut_by_id (
1070
- world : & mut World ,
1097
+ world : & World ,
1071
1098
entity : Entity ,
1072
1099
location : EntityLocation ,
1073
1100
component_id : ComponentId ,
1074
1101
) -> Option < MutUntyped > {
1075
- let change_tick = world. change_tick ( ) ;
1076
1102
let info = world. components . get_info_unchecked ( component_id) ;
1077
- // SAFETY: world access is unique , entity location and component_id required to be valid
1103
+ // SAFETY: world access promised by the caller , entity location and component_id required to be valid
1078
1104
get_component_and_ticks ( world, component_id, info. storage_type ( ) , entity, location) . map (
1079
1105
|( value, ticks) | MutUntyped {
1080
1106
value : value. assert_unique ( ) ,
1081
- ticks : Ticks :: from_tick_cells ( ticks, world. last_change_tick ( ) , change_tick) ,
1107
+ ticks : Ticks :: from_tick_cells (
1108
+ ticks,
1109
+ world. last_change_tick ( ) ,
1110
+ world. read_change_tick ( ) ,
1111
+ ) ,
1082
1112
} ,
1083
1113
)
1084
1114
}
0 commit comments