@@ -14,10 +14,12 @@ use std::{
1414 rc:: Rc ,
1515} ;
1616
17+ use super :: interior_mutable_world:: InteriorMutableWorld ;
18+
1719/// Exposes safe mutable access to multiple resources at a time in a World. Attempting to access
1820/// World in a way that violates Rust's mutability rules will panic thanks to runtime checks.
1921pub struct WorldCell < ' w > {
20- pub ( crate ) world : & ' w mut World ,
22+ pub ( crate ) world : InteriorMutableWorld < ' w > ,
2123 pub ( crate ) access : Rc < RefCell < ArchetypeComponentAccess > > ,
2224}
2325
@@ -76,8 +78,16 @@ impl ArchetypeComponentAccess {
7678impl < ' w > Drop for WorldCell < ' w > {
7779 fn drop ( & mut self ) {
7880 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+ }
8191 }
8292}
8393
@@ -175,25 +185,25 @@ impl<'w> WorldCell<'w> {
175185 pub ( crate ) fn new ( world : & ' w mut World ) -> Self {
176186 // this is cheap because ArchetypeComponentAccess::new() is const / allocation free
177187 let access = std:: mem:: replace (
178- & mut world. archetype_component_access ,
188+ world. archetype_component_access . get_mut ( ) ,
179189 ArchetypeComponentAccess :: new ( ) ,
180190 ) ;
181191 // world's ArchetypeComponentAccess is recycled to cut down on allocations
182192 Self {
183- world,
193+ world : world . as_interior_mutable ( ) ,
184194 access : Rc :: new ( RefCell :: new ( access) ) ,
185195 }
186196 }
187197
188198 /// Gets a reference to the resource of the given type
189199 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+
194204 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 > ( ) } ,
197207 archetype_component_id,
198208 self . access . clone ( ) ,
199209 )
@@ -220,17 +230,11 @@ impl<'w> WorldCell<'w> {
220230
221231 /// Gets a mutable reference to the resource of the given type
222232 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 ( ) ;
227235 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 > ( ) } ,
234238 archetype_component_id,
235239 self . access . clone ( ) ,
236240 )
@@ -257,13 +261,11 @@ impl<'w> WorldCell<'w> {
257261
258262 /// Gets an immutable reference to the non-send resource of the given type, if it exists.
259263 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 ( ) ;
264266 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 > ( ) } ,
267269 archetype_component_id,
268270 self . access . clone ( ) ,
269271 )
@@ -290,17 +292,11 @@ impl<'w> WorldCell<'w> {
290292
291293 /// Gets a mutable reference to the non-send resource of the given type, if it exists.
292294 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 ( ) ;
297297 WorldBorrowMut :: try_new (
298298 // 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 > ( ) } ,
304300 archetype_component_id,
305301 self . access . clone ( ) ,
306302 )
@@ -416,10 +412,11 @@ mod tests {
416412 let u32_archetype_component_id = world
417413 . get_resource_archetype_component_id ( u32_component_id)
418414 . unwrap ( ) ;
419- assert_eq ! ( world. archetype_component_access. access. len( ) , 1 ) ;
415+ assert_eq ! ( world. archetype_component_access. get_mut ( ) . access. len( ) , 1 ) ;
420416 assert_eq ! (
421417 world
422418 . archetype_component_access
419+ . get_mut( )
423420 . access
424421 . get( u32_archetype_component_id) ,
425422 Some ( & BASE_ACCESS ) ,
0 commit comments