@@ -14,10 +14,12 @@ use std::{
14
14
rc:: Rc ,
15
15
} ;
16
16
17
+ use super :: interior_mutable_world:: InteriorMutableWorld ;
18
+
17
19
/// Exposes safe mutable access to multiple resources at a time in a World. Attempting to access
18
20
/// World in a way that violates Rust's mutability rules will panic thanks to runtime checks.
19
21
pub struct WorldCell < ' w > {
20
- pub ( crate ) world : & ' w mut World ,
22
+ pub ( crate ) world : InteriorMutableWorld < ' w > ,
21
23
pub ( crate ) access : Rc < RefCell < ArchetypeComponentAccess > > ,
22
24
}
23
25
@@ -76,8 +78,16 @@ impl ArchetypeComponentAccess {
76
78
impl < ' w > Drop for WorldCell < ' w > {
77
79
fn drop ( & mut self ) {
78
80
let mut access = self . access . borrow_mut ( ) ;
79
- // give world ArchetypeComponentAccess back to reuse allocations
80
- std:: mem:: swap ( & mut self . world . archetype_component_access , & mut * access) ;
81
+
82
+ {
83
+ // SAFETY: we only swap `archetype_component_access`
84
+ let world = unsafe { self . world . world ( ) } ;
85
+ // SAFETY: the WorldCell has exclusive world access
86
+ let world_cached_access = unsafe { & mut * world. archetype_component_access . get ( ) } ;
87
+
88
+ // give world ArchetypeComponentAccess back to reuse allocations
89
+ std:: mem:: swap ( world_cached_access, & mut * access) ;
90
+ }
81
91
}
82
92
}
83
93
@@ -175,25 +185,25 @@ impl<'w> WorldCell<'w> {
175
185
pub ( crate ) fn new ( world : & ' w mut World ) -> Self {
176
186
// this is cheap because ArchetypeComponentAccess::new() is const / allocation free
177
187
let access = std:: mem:: replace (
178
- & mut world. archetype_component_access ,
188
+ world. archetype_component_access . get_mut ( ) ,
179
189
ArchetypeComponentAccess :: new ( ) ,
180
190
) ;
181
191
// world's ArchetypeComponentAccess is recycled to cut down on allocations
182
192
Self {
183
- world,
193
+ world : world . as_interior_mutable ( ) ,
184
194
access : Rc :: new ( RefCell :: new ( access) ) ,
185
195
}
186
196
}
187
197
188
198
/// Gets a reference to the resource of the given type
189
199
pub fn get_resource < T : Resource > ( & self ) -> Option < WorldBorrow < ' _ , T > > {
190
- let component_id = self . world . components . get_resource_id ( TypeId :: of :: < T > ( ) ) ?;
191
- let archetype_component_id = self
192
- . world
193
- . get_resource_archetype_component_id ( component_id ) ? ;
200
+ let component_id = self . world . components ( ) . get_resource_id ( TypeId :: of :: < T > ( ) ) ?;
201
+
202
+ let archetype_component_id = self . world . storages ( ) . resources . get ( component_id ) ? . id ( ) ;
203
+
194
204
WorldBorrow :: try_new (
195
- // SAFETY: ComponentId matches TypeId
196
- || unsafe { self . world . get_resource_with_id ( component_id ) } ,
205
+ // SAFETY: access is checked by WorldBorrow
206
+ || unsafe { self . world . get_resource :: < T > ( ) } ,
197
207
archetype_component_id,
198
208
self . access . clone ( ) ,
199
209
)
@@ -220,17 +230,11 @@ impl<'w> WorldCell<'w> {
220
230
221
231
/// Gets a mutable reference to the resource of the given type
222
232
pub fn get_resource_mut < T : Resource > ( & self ) -> Option < WorldBorrowMut < ' _ , T > > {
223
- let component_id = self . world . components . get_resource_id ( TypeId :: of :: < T > ( ) ) ?;
224
- let archetype_component_id = self
225
- . world
226
- . get_resource_archetype_component_id ( component_id) ?;
233
+ let component_id = self . world . components ( ) . get_resource_id ( TypeId :: of :: < T > ( ) ) ?;
234
+ let archetype_component_id = self . world . storages ( ) . resources . get ( component_id) ?. id ( ) ;
227
235
WorldBorrowMut :: try_new (
228
- // SAFETY: ComponentId matches TypeId and access is checked by WorldBorrowMut
229
- || unsafe {
230
- self . world
231
- . as_interior_mutable_migration_internal ( )
232
- . get_resource_mut_with_id ( component_id)
233
- } ,
236
+ // SAFETY: access is checked by WorldBorrowMut
237
+ || unsafe { self . world . get_resource_mut :: < T > ( ) } ,
234
238
archetype_component_id,
235
239
self . access . clone ( ) ,
236
240
)
@@ -257,13 +261,11 @@ impl<'w> WorldCell<'w> {
257
261
258
262
/// Gets an immutable reference to the non-send resource of the given type, if it exists.
259
263
pub fn get_non_send_resource < T : ' static > ( & self ) -> Option < WorldBorrow < ' _ , T > > {
260
- let component_id = self . world . components . get_resource_id ( TypeId :: of :: < T > ( ) ) ?;
261
- let archetype_component_id = self
262
- . world
263
- . get_resource_archetype_component_id ( component_id) ?;
264
+ let component_id = self . world . components ( ) . get_resource_id ( TypeId :: of :: < T > ( ) ) ?;
265
+ let archetype_component_id = self . world . storages ( ) . resources . get ( component_id) ?. id ( ) ;
264
266
WorldBorrow :: try_new (
265
- // SAFETY: ComponentId matches TypeId
266
- || unsafe { self . world . get_non_send_with_id ( component_id ) } ,
267
+ // SAFETY: access is checked by WorldBorrowMut
268
+ || unsafe { self . world . get_non_send_resource :: < T > ( ) } ,
267
269
archetype_component_id,
268
270
self . access . clone ( ) ,
269
271
)
@@ -290,17 +292,11 @@ impl<'w> WorldCell<'w> {
290
292
291
293
/// Gets a mutable reference to the non-send resource of the given type, if it exists.
292
294
pub fn get_non_send_resource_mut < T : ' static > ( & self ) -> Option < WorldBorrowMut < ' _ , T > > {
293
- let component_id = self . world . components . get_resource_id ( TypeId :: of :: < T > ( ) ) ?;
294
- let archetype_component_id = self
295
- . world
296
- . get_resource_archetype_component_id ( component_id) ?;
295
+ let component_id = self . world . components ( ) . get_resource_id ( TypeId :: of :: < T > ( ) ) ?;
296
+ let archetype_component_id = self . world . storages ( ) . resources . get ( component_id) ?. id ( ) ;
297
297
WorldBorrowMut :: try_new (
298
298
// SAFETY: access is checked by WorldBorrowMut
299
- || unsafe {
300
- self . world
301
- . as_interior_mutable_migration_internal ( )
302
- . get_non_send_resource_mut :: < T > ( )
303
- } ,
299
+ || unsafe { self . world . get_non_send_resource_mut :: < T > ( ) } ,
304
300
archetype_component_id,
305
301
self . access . clone ( ) ,
306
302
)
@@ -416,10 +412,11 @@ mod tests {
416
412
let u32_archetype_component_id = world
417
413
. get_resource_archetype_component_id ( u32_component_id)
418
414
. unwrap ( ) ;
419
- assert_eq ! ( world. archetype_component_access. access. len( ) , 1 ) ;
415
+ assert_eq ! ( world. archetype_component_access. get_mut ( ) . access. len( ) , 1 ) ;
420
416
assert_eq ! (
421
417
world
422
418
. archetype_component_access
419
+ . get_mut( )
423
420
. access
424
421
. get( u32_archetype_component_id) ,
425
422
Some ( & BASE_ACCESS ) ,
0 commit comments