@@ -10,6 +10,7 @@ pub struct ReflectComponent {
10
10
add_component : fn ( & mut World , resources : & Resources , Entity , & dyn Reflect ) ,
11
11
apply_component : fn ( & mut World , Entity , & dyn Reflect ) ,
12
12
reflect_component : unsafe fn ( & Archetype , usize ) -> & dyn Reflect ,
13
+ reflect_component_mut : unsafe fn ( & Archetype , usize ) -> & mut dyn Reflect ,
13
14
copy_component : fn ( & World , & mut World , & Resources , Entity , Entity ) ,
14
15
}
15
16
@@ -38,6 +39,20 @@ impl ReflectComponent {
38
39
( self . reflect_component ) ( archetype, entity_index)
39
40
}
40
41
42
+ /// # Safety
43
+ /// This does not do bound checks on entity_index. You must make sure entity_index is within bounds before calling.
44
+ /// This method does not prevent you from having two mutable pointers to the same data, violating Rust's aliasing rules. To avoid this:
45
+ /// * Only call this method in a thread-local system to avoid sharing across threads.
46
+ /// * Don't call this method more than once in the same scope for a given component.
47
+ #[ allow( clippy:: mut_from_ref) ]
48
+ pub unsafe fn reflect_component_mut < ' a > (
49
+ & self ,
50
+ archetype : & ' a Archetype ,
51
+ entity_index : usize ,
52
+ ) -> & ' a mut dyn Reflect {
53
+ ( self . reflect_component_mut ) ( archetype, entity_index)
54
+ }
55
+
41
56
pub fn copy_component (
42
57
& self ,
43
58
source_world : & World ,
@@ -87,6 +102,13 @@ impl<C: Component + Reflect + FromResources> FromType<C> for ReflectComponent {
87
102
ptr. as_ref ( ) . unwrap ( )
88
103
}
89
104
} ,
105
+ reflect_component_mut : |archetype, index| {
106
+ unsafe {
107
+ // the type has been looked up by the caller, so this is safe
108
+ let ptr = archetype. get :: < C > ( ) . unwrap ( ) . as_ptr ( ) . add ( index) ;
109
+ & mut * ptr
110
+ }
111
+ } ,
90
112
}
91
113
}
92
114
}
0 commit comments