@@ -11,7 +11,7 @@ extern crate shred;
1111use ahash:: AHashMap as HashMap ;
1212
1313use shred:: {
14- cell:: { Ref , RefMut } ,
14+ cell:: { AtomicRef , AtomicRefMut } ,
1515 Accessor , AccessorCow , CastFrom , DispatcherBuilder , DynamicSystemData , MetaTable , Read ,
1616 Resource , ResourceId , System , SystemData , World ,
1717} ;
@@ -54,32 +54,20 @@ impl<'a> System<'a> for DynamicSystem {
5454 let reads: Vec < & dyn Reflection > = data
5555 . reads
5656 . iter ( )
57- . map ( |resource| {
58- // explicitly use the type because we're dealing with `&Resource` which is
59- // implemented by a lot of types; we don't want to accidentally
60- // get a `&Box<Resource>` and cast it to a `&Resource`.
61- let res = Box :: as_ref ( resource) ;
62-
63- meta. get ( res) . expect ( "Not registered in meta table" )
64- } )
57+ . map ( |resource| meta. get ( & * * resource) . expect ( "Not registered in meta table" ) )
6558 . collect ( ) ;
6659
6760 let writes: Vec < & mut dyn Reflection > = data
6861 . writes
6962 . iter_mut ( )
7063 . map ( |resource| {
71- // explicitly use the type because we're dealing with `&mut Resource` which is
72- // implemented by a lot of types; we don't want to accidentally get a
73- // `&mut Box<Resource>` and cast it to a `&mut Resource`.
74- let res = Box :: as_mut ( resource) ;
75-
7664 // For some reason this needs a type ascription, otherwise Rust will think it's
77- // a `&mut (Reflection + '_)` (as opposed to `&mut (Reflection + 'static)`.
78- let res: & mut dyn Reflection = meta. get_mut ( res) . expect (
65+ // a `&mut (Reflaction + '_)` (as opposed to `&mut (Reflection + 'static)`. (Note this
66+ // isn't needed in newer rust version but fails on the MSRV of 1.59.0).
67+ let res: & mut dyn Reflection = meta. get_mut ( & mut * * resource) . expect (
7968 "Not registered in meta \
8069 table",
8170 ) ;
82-
8371 res
8472 } )
8573 . collect ( ) ;
@@ -150,37 +138,47 @@ struct ScriptInput<'a> {
150138
151139struct ScriptSystemData < ' a > {
152140 meta_table : Read < ' a , ReflectionTable > ,
153- reads : Vec < Ref < ' a , Box < dyn Resource + ' static > > > ,
154- writes : Vec < RefMut < ' a , Box < dyn Resource + ' static > > > ,
141+ reads : Vec < AtomicRef < ' a , dyn Resource + ' static > > ,
142+ writes : Vec < AtomicRefMut < ' a , dyn Resource + ' static > > ,
155143}
156144
157145impl < ' a > DynamicSystemData < ' a > for ScriptSystemData < ' a > {
158146 type Accessor = Dependencies ;
159147
160148 fn setup ( _accessor : & Dependencies , _res : & mut World ) { }
161149
162- fn fetch ( access : & Dependencies , res : & ' a World ) -> Self {
150+ fn fetch ( access : & Dependencies , world : & ' a World ) -> Self {
163151 let reads = access
164152 . reads
165153 . iter ( )
166154 . map ( |id| {
167- res. try_fetch_internal ( id. clone ( ) )
168- . expect ( "bug: the requested resource does not exist" )
169- . borrow ( )
155+ let id = id. clone ( ) ;
156+ // SAFETY: We don't expose mutable reference to the Box or swap it out.
157+ let res = unsafe { world. try_fetch_internal ( id) } ;
158+ AtomicRef :: map (
159+ res. expect ( "bug: the requested resource does not exist" )
160+ . borrow ( ) ,
161+ Box :: as_ref,
162+ )
170163 } )
171164 . collect ( ) ;
172165 let writes = access
173166 . writes
174167 . iter ( )
175168 . map ( |id| {
176- res. try_fetch_internal ( id. clone ( ) )
177- . expect ( "bug: the requested resource does not exist" )
178- . borrow_mut ( )
169+ let id = id. clone ( ) ;
170+ // SAFETY: We don't expose mutable reference to the Box or swap it out.
171+ let res = unsafe { world. try_fetch_internal ( id) } ;
172+ AtomicRefMut :: map (
173+ res. expect ( "bug: the requested resource does not exist" )
174+ . borrow_mut ( ) ,
175+ Box :: as_mut,
176+ )
179177 } )
180178 . collect ( ) ;
181179
182180 ScriptSystemData {
183- meta_table : SystemData :: fetch ( res ) ,
181+ meta_table : SystemData :: fetch ( world ) ,
184182 reads,
185183 writes,
186184 }
0 commit comments