@@ -44,17 +44,19 @@ pub struct ReflectComponentFns {
44
44
/// Function pointer implementing [`ReflectComponent::insert()`].
45
45
pub insert : fn ( & mut World , Entity , & dyn Reflect ) ,
46
46
/// Function pointer implementing [`ReflectComponent::apply()`].
47
- pub apply : fn ( & mut EntityMut , & dyn Reflect ) ,
47
+ pub apply : fn ( EntityMut , & dyn Reflect ) ,
48
48
/// Function pointer implementing [`ReflectComponent::apply_or_insert()`].
49
49
pub apply_or_insert : fn ( & mut World , Entity , & dyn Reflect ) ,
50
50
/// Function pointer implementing [`ReflectComponent::remove()`].
51
- pub remove : fn ( & mut EntityMut ) ,
51
+ pub remove : fn ( EntityMut ) ,
52
52
/// Function pointer implementing [`ReflectComponent::contains()`].
53
- pub contains : fn ( & EntityRef ) -> bool ,
53
+ pub contains : fn ( EntityRef ) -> bool ,
54
54
/// Function pointer implementing [`ReflectComponent::reflect()`].
55
- pub reflect : for < ' a > fn ( & ' a EntityRef ) -> Option < & ' a dyn Reflect > ,
55
+ pub reflect : fn ( EntityRef ) -> Option < & dyn Reflect > ,
56
56
/// Function pointer implementing [`ReflectComponent::reflect_mut()`].
57
- pub reflect_mut : for <' a > fn ( & ' a mut EntityMut ) -> Option < Mut < ' a , dyn Reflect > > ,
57
+ pub reflect_mut : for <' a > fn ( & ' a mut EntityMut < ' a > ) -> Option < Mut < ' a , dyn Reflect > > ,
58
+ /// Function pointer implementing [`ReflectComponent::reflect_unchecked_mut()`].
59
+ pub reflect_unchecked_mut : fn ( & World , Entity ) -> Option < Mut < dyn Reflect > > ,
58
60
/// Function pointer implementing [`ReflectComponent::copy()`].
59
61
pub copy : fn ( & World , & mut World , Entity , Entity ) ,
60
62
}
@@ -85,7 +87,7 @@ impl ReflectComponent {
85
87
/// # Panics
86
88
///
87
89
/// Panics if there is no [`Component`] of the given type.
88
- pub fn apply ( & self , entity : & mut EntityMut , component : & dyn Reflect ) {
90
+ pub fn apply ( & self , entity : EntityMut , component : & dyn Reflect ) {
89
91
( self . 0 . apply ) ( entity, component) ;
90
92
}
91
93
@@ -103,17 +105,17 @@ impl ReflectComponent {
103
105
/// # Panics
104
106
///
105
107
/// Panics if there is no [`Component`] of the given type.
106
- pub fn remove ( & self , entity : & mut EntityMut ) {
108
+ pub fn remove ( & self , entity : EntityMut ) {
107
109
( self . 0 . remove ) ( entity) ;
108
110
}
109
111
110
112
/// Returns whether entity contains this [`Component`]
111
- pub fn contains ( & self , entity : & EntityRef ) -> bool {
113
+ pub fn contains ( & self , entity : EntityRef ) -> bool {
112
114
( self . 0 . contains ) ( entity)
113
115
}
114
116
115
117
/// Gets the value of this [`Component`] type from the entity as a reflected reference.
116
- pub fn reflect < ' a > ( & self , entity : & ' a EntityRef < ' a > ) -> Option < & ' a dyn Reflect > {
118
+ pub fn reflect < ' a > ( & self , entity : EntityRef < ' a > ) -> Option < & ' a dyn Reflect > {
117
119
( self . 0 . reflect ) ( entity)
118
120
}
119
121
@@ -122,6 +124,20 @@ impl ReflectComponent {
122
124
( self . 0 . reflect_mut ) ( entity)
123
125
}
124
126
127
+ /// # Safety
128
+ /// This method does not prevent you from having two mutable pointers to the same data,
129
+ /// violating Rust's aliasing rules. To avoid this:
130
+ /// * Only call this method in an exclusive system to avoid sharing across threads (or use a
131
+ /// scheduler that enforces safe memory access).
132
+ /// * Don't call this method more than once in the same scope for a given [`Component`].
133
+ pub unsafe fn reflect_unchecked_mut < ' a > (
134
+ & self ,
135
+ world : & ' a World ,
136
+ entity : Entity ,
137
+ ) -> Option < Mut < ' a , dyn Reflect > > {
138
+ ( self . 0 . reflect_unchecked_mut ) ( world, entity)
139
+ }
140
+
125
141
/// Gets the value of this [`Component`] type from entity from `source_world` and [applies](Self::apply()) it to the value of this [`Component`] type in entity in `destination_world`.
126
142
///
127
143
/// # Panics
@@ -166,7 +182,7 @@ impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
166
182
component. apply ( reflected_component) ;
167
183
world. entity_mut ( entity) . insert ( component) ;
168
184
} ,
169
- apply : |entity, reflected_component| {
185
+ apply : |mut entity, reflected_component| {
170
186
let mut component = entity. get_mut :: < C > ( ) . unwrap ( ) ;
171
187
component. apply ( reflected_component) ;
172
188
} ,
@@ -179,7 +195,7 @@ impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
179
195
world. entity_mut ( entity) . insert ( component) ;
180
196
}
181
197
} ,
182
- remove : |entity| {
198
+ remove : |mut entity| {
183
199
entity. remove :: < C > ( ) ;
184
200
} ,
185
201
contains : |entity| entity. contains :: < C > ( ) ,
@@ -198,6 +214,19 @@ impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
198
214
ticks : c. ticks ,
199
215
} )
200
216
} ,
217
+ reflect_unchecked_mut : |world, entity| {
218
+ // SAFETY: reflect_mut is an unsafe function pointer used by `reflect_unchecked_mut` which promises to never
219
+ // produce aliasing mutable references, and reflect_mut, which has mutable world access
220
+ unsafe {
221
+ world
222
+ . get_entity ( entity) ?
223
+ . get_unchecked_mut :: < C > ( world. last_change_tick ( ) , world. read_change_tick ( ) )
224
+ . map ( |c| Mut {
225
+ value : c. value as & mut dyn Reflect ,
226
+ ticks : c. ticks ,
227
+ } )
228
+ }
229
+ } ,
201
230
} )
202
231
}
203
232
}
0 commit comments