Skip to content

Commit eb129b7

Browse files
committed
Review items
1 parent ba09058 commit eb129b7

File tree

2 files changed

+35
-6
lines changed

2 files changed

+35
-6
lines changed

crates/bevy_ecs/src/reflect.rs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ pub struct ReflectComponentFns {
5050
/// Function pointer implementing [`ReflectComponent::remove()`].
5151
pub remove: fn(&mut EntityMut),
5252
/// Function pointer implementing [`ReflectComponent::contains()`].
53-
pub contains: fn(&EntityRef) -> bool,
53+
pub contains: fn(EntityRef) -> bool,
5454
/// 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>,
5656
/// 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>>,
5860
/// Function pointer implementing [`ReflectComponent::copy()`].
5961
pub copy: fn(&World, &mut World, Entity, Entity),
6062
}
@@ -108,12 +110,12 @@ impl ReflectComponent {
108110
}
109111

110112
/// Returns whether entity contains this [`Component`]
111-
pub fn contains(&self, entity: &EntityRef) -> bool {
113+
pub fn contains(&self, entity: EntityRef) -> bool {
112114
(self.0.contains)(entity)
113115
}
114116

115117
/// 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> {
117119
(self.0.reflect)(entity)
118120
}
119121

@@ -122,6 +124,20 @@ impl ReflectComponent {
122124
(self.0.reflect_mut)(entity)
123125
}
124126

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+
125141
/// 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`.
126142
///
127143
/// # Panics
@@ -198,6 +214,19 @@ impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
198214
ticks: c.ticks,
199215
})
200216
},
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+
},
201230
})
202231
}
203232
}

crates/bevy_scene/src/dynamic_scene_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ impl<'w> DynamicSceneBuilder<'w> {
132132
.get_info(component_id)
133133
.and_then(|info| type_registry.get(info.type_id().unwrap()))
134134
.and_then(|registration| registration.data::<ReflectComponent>())
135-
.and_then(|reflect_component| reflect_component.reflect(&entity));
135+
.and_then(|reflect_component| reflect_component.reflect(entity));
136136

137137
if let Some(reflect_component) = reflect_component {
138138
entry.components.push(reflect_component.clone_value());

0 commit comments

Comments
 (0)