Skip to content

Commit 05a3c83

Browse files
use InteriorMutableEntityRef for Query and ReflectComponent
1 parent c9bae09 commit 05a3c83

File tree

3 files changed

+28
-80
lines changed

3 files changed

+28
-80
lines changed

crates/bevy_ecs/src/reflect.rs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -210,19 +210,14 @@ impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
210210
.map(|c| c as &dyn Reflect)
211211
},
212212
reflect_mut: |world, entity| {
213-
// SAFETY: reflect_mut is an unsafe function pointer used by `reflect_unchecked_mut` which promises to never
214-
// produce aliasing mutable references, and reflect_mut, which has mutable world access
213+
// SAFETY: reflect_mut is an unsafe function pointer used by
214+
// 1. `reflect_unchecked_mut` which must be called with an InteriorMutableWorld with access the the component `C` on the `entity`, and
215+
// 2. reflect_mut, which has mutable world access
215216
unsafe {
216-
// SAFETY: entity access through the InteriorMutableWorld is not implemented yet.
217-
// The following code only accesses the component `C` through the entity `entity`
218-
let world = world.world();
219-
world
220-
.get_entity(entity)?
221-
.get_unchecked_mut::<C>(world.last_change_tick(), world.read_change_tick())
222-
.map(|c| Mut {
223-
value: c.value as &mut dyn Reflect,
224-
ticks: c.ticks,
225-
})
217+
world.get_entity(entity)?.get_mut::<C>().map(|c| Mut {
218+
value: c.value as &mut dyn Reflect,
219+
ticks: c.ticks,
220+
})
226221
}
227222
},
228223
})

crates/bevy_ecs/src/system/query.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> {
11761176
}
11771177
let world = self.world;
11781178
let entity_ref = world
1179+
.as_interior_mutable()
11791180
.get_entity(entity)
11801181
.ok_or(QueryComponentError::NoSuchEntity)?;
11811182
let component_id = world
@@ -1192,7 +1193,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> {
11921193
.has_write(archetype_component)
11931194
{
11941195
entity_ref
1195-
.get_unchecked_mut::<T>(self.last_change_tick, self.change_tick)
1196+
.get_mut_using_ticks::<T>(self.last_change_tick, self.change_tick)
11961197
.ok_or(QueryComponentError::MissingComponent)
11971198
} else {
11981199
Err(QueryComponentError::MissingWriteAccess)

crates/bevy_ecs/src/world/entity_ref.rs

Lines changed: 19 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -107,41 +107,6 @@ impl<'w> EntityRef<'w> {
107107
.map(|ticks| ticks.deref())
108108
}
109109
}
110-
111-
/// Gets a mutable reference to the component of type `T` associated with
112-
/// this entity without ensuring there are no other borrows active and without
113-
/// ensuring that the returned reference will stay valid.
114-
///
115-
/// # Safety
116-
///
117-
/// - The returned reference must never alias a mutable borrow of this component.
118-
/// - The returned reference must not be used after this component is moved which
119-
/// may happen from **any** `insert_component`, `remove_component` or `despawn`
120-
/// operation on this world (non-exhaustive list).
121-
#[inline]
122-
pub unsafe fn get_unchecked_mut<T: Component>(
123-
&self,
124-
last_change_tick: u32,
125-
change_tick: u32,
126-
) -> Option<Mut<'w, T>> {
127-
self.world
128-
.storages
129-
.get_component_and_ticks_with_type(
130-
&self.world.archetypes,
131-
&self.world.components,
132-
TypeId::of::<T>(),
133-
self.entity,
134-
self.location,
135-
)
136-
.map(|(value, ticks)| Mut {
137-
value: value.assert_unique().deref_mut::<T>(),
138-
ticks: Ticks {
139-
component_ticks: ticks.deref_mut(),
140-
last_change_tick,
141-
change_tick,
142-
},
143-
})
144-
}
145110
}
146111

147112
impl<'w> EntityRef<'w> {
@@ -253,7 +218,25 @@ impl<'w> EntityMut<'w> {
253218
#[inline]
254219
pub fn get_mut<T: Component>(&mut self) -> Option<Mut<'_, T>> {
255220
// SAFETY: world access is unique, and lifetimes enforce correct usage of returned borrow
256-
unsafe { self.get_unchecked_mut::<T>() }
221+
unsafe {
222+
self.world
223+
.storages
224+
.get_component_and_ticks_with_type(
225+
&self.world.archetypes,
226+
&self.world.components,
227+
TypeId::of::<T>(),
228+
self.entity,
229+
self.location,
230+
)
231+
.map(|(value, ticks)| Mut {
232+
value: value.assert_unique().deref_mut::<T>(),
233+
ticks: Ticks {
234+
component_ticks: ticks.deref_mut(),
235+
last_change_tick: self.world.last_change_tick(),
236+
change_tick: self.world.read_change_tick(),
237+
},
238+
})
239+
}
257240
}
258241

259242
/// Retrieves the change ticks for the given component. This can be useful for implementing change
@@ -279,37 +262,6 @@ impl<'w> EntityMut<'w> {
279262
}
280263
}
281264

282-
/// Gets a mutable reference to the component of type `T` associated with
283-
/// this entity without ensuring there are no other borrows active and without
284-
/// ensuring that the returned reference will stay valid.
285-
///
286-
/// # Safety
287-
///
288-
/// - The returned reference must never alias a mutable borrow of this component.
289-
/// - The returned reference must not be used after this component is moved which
290-
/// may happen from **any** `insert_component`, `remove_component` or `despawn`
291-
/// operation on this world (non-exhaustive list).
292-
#[inline]
293-
pub unsafe fn get_unchecked_mut<T: Component>(&self) -> Option<Mut<'_, T>> {
294-
self.world
295-
.storages
296-
.get_component_and_ticks_with_type(
297-
&self.world.archetypes,
298-
&self.world.components,
299-
TypeId::of::<T>(),
300-
self.entity,
301-
self.location,
302-
)
303-
.map(|(value, ticks)| Mut {
304-
value: value.assert_unique().deref_mut::<T>(),
305-
ticks: Ticks {
306-
component_ticks: ticks.deref_mut(),
307-
last_change_tick: self.world.last_change_tick(),
308-
change_tick: self.world.read_change_tick(),
309-
},
310-
})
311-
}
312-
313265
#[deprecated(
314266
since = "0.9.0",
315267
note = "Use `insert` instead, which now accepts bundles, components, and tuples of bundles and components."

0 commit comments

Comments
 (0)