@@ -42,6 +42,14 @@ impl<'w> EntityRef<'w> {
42
42
}
43
43
}
44
44
45
+ fn as_interior_mutable_readonly ( & self ) -> InteriorMutableEntityRef < ' w > {
46
+ InteriorMutableEntityRef :: new (
47
+ self . world . as_interior_mutable_readonly ( ) ,
48
+ self . entity ,
49
+ self . location ,
50
+ )
51
+ }
52
+
45
53
#[ inline]
46
54
#[ must_use = "Omit the .id() call if you do not need to store the `Entity` identifier." ]
47
55
pub fn id ( & self ) -> Entity {
@@ -80,39 +88,16 @@ impl<'w> EntityRef<'w> {
80
88
81
89
#[ inline]
82
90
pub fn get < T : Component > ( & self ) -> Option < & ' w T > {
83
- // SAFETY:
84
- // - entity location and entity is valid
85
- // - the storage type provided is correct for T
86
- // - world access is immutable, lifetime tied to `&self`
87
- unsafe {
88
- self . world
89
- . get_component_with_type (
90
- TypeId :: of :: < T > ( ) ,
91
- T :: Storage :: STORAGE_TYPE ,
92
- self . entity ,
93
- self . location ,
94
- )
95
- // SAFETY: returned component is of type T
96
- . map ( |value| value. deref :: < T > ( ) )
97
- }
91
+ // SAFETY: &self implies shared access for duration of returned value
92
+ unsafe { self . as_interior_mutable_readonly ( ) . get :: < T > ( ) }
98
93
}
99
94
100
95
/// Retrieves the change ticks for the given component. This can be useful for implementing change
101
96
/// detection in custom runtimes.
102
97
#[ inline]
103
98
pub fn get_change_ticks < T : Component > ( & self ) -> Option < ComponentTicks > {
104
- // SAFETY:
105
- // - entity location and entity is valid
106
- // - world access is immutable, lifetime tied to `&self`
107
- // - the storage type provided is correct for T
108
- unsafe {
109
- self . world . get_ticks_with_type (
110
- TypeId :: of :: < T > ( ) ,
111
- T :: Storage :: STORAGE_TYPE ,
112
- self . entity ,
113
- self . location ,
114
- )
115
- }
99
+ // SAFETY: &self implies shared access
100
+ unsafe { self . as_interior_mutable_readonly ( ) . get_change_ticks :: < T > ( ) }
116
101
}
117
102
118
103
/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
@@ -123,18 +108,10 @@ impl<'w> EntityRef<'w> {
123
108
/// compile time.**
124
109
#[ inline]
125
110
pub fn get_change_ticks_by_id ( & self , component_id : ComponentId ) -> Option < ComponentTicks > {
126
- let info = self . world . components ( ) . get_info ( component_id) ?;
127
- // SAFETY:
128
- // - entity location and entity is valid
129
- // - world access is immutable, lifetime tied to `&self`
130
- // - the storage type provided is correct for T
111
+ // SAFETY: &self implies shared access
131
112
unsafe {
132
- self . world . get_ticks (
133
- component_id,
134
- info. storage_type ( ) ,
135
- self . entity ,
136
- self . location ,
137
- )
113
+ self . as_interior_mutable_readonly ( )
114
+ . get_change_ticks_by_id ( component_id)
138
115
}
139
116
}
140
117
}
@@ -150,19 +127,8 @@ impl<'w> EntityRef<'w> {
150
127
/// which is only valid while the `'w` borrow of the lifetime is active.
151
128
#[ inline]
152
129
pub fn get_by_id ( & self , component_id : ComponentId ) -> Option < Ptr < ' w > > {
153
- let info = self . world . components ( ) . get_info ( component_id) ?;
154
- // SAFETY:
155
- // - entity_location and entity are valid
156
- // - component_id is valid as checked by the line above
157
- // - the storage type is accurate as checked by the fetched ComponentInfo
158
- unsafe {
159
- self . world . get_component (
160
- component_id,
161
- info. storage_type ( ) ,
162
- self . entity ,
163
- self . location ,
164
- )
165
- }
130
+ // SAFETY: &self implies shared access for duration of returned value
131
+ unsafe { self . as_interior_mutable_readonly ( ) . get_by_id ( component_id) }
166
132
}
167
133
}
168
134
@@ -182,6 +148,17 @@ pub struct EntityMut<'w> {
182
148
}
183
149
184
150
impl < ' w > EntityMut < ' w > {
151
+ fn as_interior_mutable_readonly ( & self ) -> InteriorMutableEntityRef < ' _ > {
152
+ InteriorMutableEntityRef :: new (
153
+ self . world . as_interior_mutable_readonly ( ) ,
154
+ self . entity ,
155
+ self . location ,
156
+ )
157
+ }
158
+ fn as_interior_mutable ( & mut self ) -> InteriorMutableEntityRef < ' _ > {
159
+ InteriorMutableEntityRef :: new ( self . world . as_interior_mutable ( ) , self . entity , self . location )
160
+ }
161
+
185
162
/// # Safety
186
163
///
187
164
/// - `entity` must be valid for `world`: the generation should match that of the entity at the same index.
@@ -237,50 +214,22 @@ impl<'w> EntityMut<'w> {
237
214
238
215
#[ inline]
239
216
pub fn get < T : Component > ( & self ) -> Option < & ' _ T > {
240
- // SAFETY:
241
- // - entity location is valid
242
- // - world access is immutable, lifetime tied to `&self`
243
- // - the storage type provided is correct for T
244
- unsafe {
245
- self . world
246
- . get_component_with_type (
247
- TypeId :: of :: < T > ( ) ,
248
- T :: Storage :: STORAGE_TYPE ,
249
- self . entity ,
250
- self . location ,
251
- )
252
- // SAFETY: returned component is of type T
253
- . map ( |value| value. deref :: < T > ( ) )
254
- }
217
+ // SAFETY: &self implies shared access for duration of returned value
218
+ unsafe { self . as_interior_mutable_readonly ( ) . get :: < T > ( ) }
255
219
}
256
220
257
221
#[ inline]
258
222
pub fn get_mut < T : Component > ( & mut self ) -> Option < Mut < ' _ , T > > {
259
- let interior_mutable = InteriorMutableEntityRef :: new (
260
- self . world . as_interior_mutable ( ) ,
261
- self . entity ,
262
- self . location ,
263
- ) ;
264
- // SAFETY: interiormutableentityref has exclusive access
265
- unsafe { interior_mutable. get_mut ( ) }
223
+ // SAFETY: &mut self implies exclusive access for duration of returned value
224
+ unsafe { self . as_interior_mutable ( ) . get_mut ( ) }
266
225
}
267
226
268
227
/// Retrieves the change ticks for the given component. This can be useful for implementing change
269
228
/// detection in custom runtimes.
270
229
#[ inline]
271
230
pub fn get_change_ticks < T : Component > ( & self ) -> Option < ComponentTicks > {
272
- // SAFETY:
273
- // - entity location is valid
274
- // - world access is immutable, lifetime tied to `&self`
275
- // - the storage type provided is correct for T
276
- unsafe {
277
- self . world . get_ticks_with_type (
278
- TypeId :: of :: < T > ( ) ,
279
- T :: Storage :: STORAGE_TYPE ,
280
- self . entity ,
281
- self . location ,
282
- )
283
- }
231
+ // SAFETY: &self implies shared access
232
+ unsafe { self . as_interior_mutable_readonly ( ) . get_change_ticks :: < T > ( ) }
284
233
}
285
234
286
235
/// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
@@ -291,18 +240,10 @@ impl<'w> EntityMut<'w> {
291
240
/// compile time.**
292
241
#[ inline]
293
242
pub fn get_change_ticks_by_id ( & self , component_id : ComponentId ) -> Option < ComponentTicks > {
294
- let info = self . world . components ( ) . get_info ( component_id) ?;
295
- // SAFETY:
296
- // - entity location is valid
297
- // - world access is immutable, lifetime tied to `&self`
298
- // - the storage type provided is correct for T
243
+ // SAFETY: &self implies shared access
299
244
unsafe {
300
- self . world . get_ticks (
301
- component_id,
302
- info. storage_type ( ) ,
303
- self . entity ,
304
- self . location ,
305
- )
245
+ self . as_interior_mutable_readonly ( )
246
+ . get_change_ticks_by_id ( component_id)
306
247
}
307
248
}
308
249
0 commit comments