Skip to content

Commit 211747c

Browse files
use InteriorMutableEntityRef for Query and ReflectComponent
1 parent 967a011 commit 211747c

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
@@ -1173,6 +1173,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> {
11731173
}
11741174
let world = self.world;
11751175
let entity_ref = world
1176+
.as_interior_mutable()
11761177
.get_entity(entity)
11771178
.ok_or(QueryComponentError::NoSuchEntity)?;
11781179
let component_id = world
@@ -1189,7 +1190,7 @@ impl<'w, 's, Q: WorldQuery, F: ReadOnlyWorldQuery> Query<'w, 's, Q, F> {
11891190
.has_write(archetype_component)
11901191
{
11911192
entity_ref
1192-
.get_unchecked_mut::<T>(self.last_change_tick, self.change_tick)
1193+
.get_mut_using_ticks::<T>(self.last_change_tick, self.change_tick)
11931194
.ok_or(QueryComponentError::MissingComponent)
11941195
} else {
11951196
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
@@ -108,41 +108,6 @@ impl<'w> EntityRef<'w> {
108108
.map(|ticks| ticks.deref())
109109
}
110110
}
111-
112-
/// Gets a mutable reference to the component of type `T` associated with
113-
/// this entity without ensuring there are no other borrows active and without
114-
/// ensuring that the returned reference will stay valid.
115-
///
116-
/// # Safety
117-
///
118-
/// - The returned reference must never alias a mutable borrow of this component.
119-
/// - The returned reference must not be used after this component is moved which
120-
/// may happen from **any** `insert_component`, `remove_component` or `despawn`
121-
/// operation on this world (non-exhaustive list).
122-
#[inline]
123-
pub unsafe fn get_unchecked_mut<T: Component>(
124-
&self,
125-
last_change_tick: u32,
126-
change_tick: u32,
127-
) -> Option<Mut<'w, T>> {
128-
self.world
129-
.storages
130-
.get_component_and_ticks_with_type(
131-
&self.world.archetypes,
132-
&self.world.components,
133-
TypeId::of::<T>(),
134-
self.entity,
135-
self.location,
136-
)
137-
.map(|(value, ticks)| Mut {
138-
value: value.assert_unique().deref_mut::<T>(),
139-
ticks: Ticks {
140-
component_ticks: ticks.deref_mut(),
141-
last_change_tick,
142-
change_tick,
143-
},
144-
})
145-
}
146111
}
147112

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

260243
/// Retrieves the change ticks for the given component. This can be useful for implementing change
@@ -280,37 +263,6 @@ impl<'w> EntityMut<'w> {
280263
}
281264
}
282265

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

0 commit comments

Comments
 (0)