Skip to content

Commit

Permalink
make EntityRef lenient
Browse files Browse the repository at this point in the history
  • Loading branch information
BoxyUwU committed Apr 3, 2022
1 parent c3ad453 commit 05f0168
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 35 deletions.
6 changes: 2 additions & 4 deletions crates/bevy_ecs/src/reflect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,15 @@ impl<C: Component + Reflect + FromWorld> FromType<C> for ReflectComponent {
.entity_mut(destination_entity)
.insert(destination_component);
},
reflect_component: |world, entity| unsafe {
reflect_component: |world, entity| {
world
.get_entity(entity)?
// SAFE: lifetimes force correct usage of returned data
.get_unchecked::<C>()
.get::<C>()
.map(|c| c as &dyn Reflect)
},
reflect_component_mut: |world, entity| unsafe {
world
.get_entity(entity)?
// SAFE: lifetimes force correct usage of returned data
.get_unchecked_mut::<C>(world.last_change_tick(), world.read_change_tick())
.map(|c| ReflectMut {
value: c.value as &mut dyn Reflect,
Expand Down
9 changes: 3 additions & 6 deletions crates/bevy_ecs/src/system/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -868,12 +868,9 @@ where
.archetype_component_access
.has_read(archetype_component)
{
// SAFE: lifetimes enforce correct usage of returned borrow
unsafe {
entity_ref
.get_unchecked::<T>()
.ok_or(QueryComponentError::MissingComponent)
}
entity_ref
.get::<T>()
.ok_or(QueryComponentError::MissingComponent)
} else {
Err(QueryComponentError::MissingReadAccess)
}
Expand Down
24 changes: 5 additions & 19 deletions crates/bevy_ecs/src/world/entity_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,26 +62,12 @@ impl<'w> EntityRef<'w> {
}

#[inline]
pub fn get<T: Component>(&self) -> Option<&'_ T> {
// SAFE: lifetimes enforce correct usage of returned borrow
unsafe { self.get_unchecked::<T>() }
}

/// Gets an immutable reference to the component of type `T` associated with
/// this entity without ensuring there are no unique borrows active and without
/// ensuring that the returned reference will stay valid.
///
/// # Safety
///
/// - The returned reference must never alias a mutable borrow of this component.
/// - The returned reference must not be used after this component is moved which
/// may happen from **any** `insert_component`, `remove_component` or `despawn`
/// operation on this world (non-exhaustive list).
#[inline]
pub unsafe fn get_unchecked<T: Component>(&self) -> Option<&'w T> {
pub fn get<T: Component>(&self) -> Option<&'w T> {
// SAFE: entity location is valid and returned component is of type T
get_component_with_type(self.world, TypeId::of::<T>(), self.entity, self.location)
.map(|value| &*value.cast::<T>())
unsafe {
get_component_with_type(self.world, TypeId::of::<T>(), self.entity, self.location)
.map(|value| &*value.cast::<T>())
}
}

/// Gets a mutable reference to the component of type `T` associated with
Expand Down
9 changes: 3 additions & 6 deletions crates/bevy_ecs/src/world/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,7 @@ impl World {
/// .insert(Position { x: 0.0, y: 0.0 })
/// .id();
///
/// let entity_ref = world.entity(entity);
/// let position = entity_ref.get::<Position>().unwrap();
/// let position = world.entity(entity).get::<Position>().unwrap();
/// assert_eq!(position.x, 0.0);
/// ```
#[inline]
Expand Down Expand Up @@ -338,8 +337,7 @@ impl World {
/// .insert_bundle((Num(1), Label("hello"))) // add a bundle of components
/// .id();
///
/// let entity_ref = world.entity(entity);
/// let position = entity_ref.get::<Position>().unwrap();
/// let position = world.entity(entity).get::<Position>().unwrap();
/// assert_eq!(position.x, 0.0);
/// ```
pub fn spawn(&mut self) -> EntityMut {
Expand Down Expand Up @@ -416,8 +414,7 @@ impl World {
/// ```
#[inline]
pub fn get<T: Component>(&self, entity: Entity) -> Option<&T> {
// SAFE: lifetimes enforce correct usage of returned borrow
unsafe { self.get_entity(entity)?.get_unchecked::<T>() }
self.get_entity(entity)?.get()
}

/// Retrieves a mutable reference to the given `entity`'s [Component] of the given type.
Expand Down

0 comments on commit 05f0168

Please sign in to comment.