Skip to content

Commit a975ef5

Browse files
committed
Review items
1 parent ba09058 commit a975ef5

File tree

2 files changed

+41
-12
lines changed

2 files changed

+41
-12
lines changed

crates/bevy_ecs/src/reflect.rs

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,19 @@ pub struct ReflectComponentFns {
4444
/// Function pointer implementing [`ReflectComponent::insert()`].
4545
pub insert: fn(&mut World, Entity, &dyn Reflect),
4646
/// Function pointer implementing [`ReflectComponent::apply()`].
47-
pub apply: fn(&mut EntityMut, &dyn Reflect),
47+
pub apply: fn(EntityMut, &dyn Reflect),
4848
/// Function pointer implementing [`ReflectComponent::apply_or_insert()`].
4949
pub apply_or_insert: fn(&mut World, Entity, &dyn Reflect),
5050
/// Function pointer implementing [`ReflectComponent::remove()`].
51-
pub remove: fn(&mut EntityMut),
51+
pub remove: fn(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
}
@@ -85,7 +87,7 @@ impl ReflectComponent {
8587
/// # Panics
8688
///
8789
/// 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) {
8991
(self.0.apply)(entity, component);
9092
}
9193

@@ -103,17 +105,17 @@ impl ReflectComponent {
103105
/// # Panics
104106
///
105107
/// 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) {
107109
(self.0.remove)(entity);
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
@@ -166,7 +182,7 @@ impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
166182
component.apply(reflected_component);
167183
world.entity_mut(entity).insert(component);
168184
},
169-
apply: |entity, reflected_component| {
185+
apply: |mut entity, reflected_component| {
170186
let mut component = entity.get_mut::<C>().unwrap();
171187
component.apply(reflected_component);
172188
},
@@ -179,7 +195,7 @@ impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
179195
world.entity_mut(entity).insert(component);
180196
}
181197
},
182-
remove: |entity| {
198+
remove: |mut entity| {
183199
entity.remove::<C>();
184200
},
185201
contains: |entity| entity.contains::<C>(),
@@ -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)