---
# System prepended metadata

title: Entity Pointer Dereference
tags: [ECS]

---

# Entity Pointer Dereference

Authors: @doot 
Contributors: @bushRAT @quartermeister @Diddykonga @Victoron

> This document details an alternative design to [Unified EntityPtr Types](/8m_dGybhTCy7SrMPtwGbiQ).

We have a few types within Bevy ECS that allow access to an Entity's metadata and components:

- `EntityRef`: provides read-only access.
- `EntityMut`: provides mutable access.
- `EntityWorldMut`: provides structurally mutable access, like adding/removing components or despawning.

However, we incur API duplication because these are unique types even though they only differ in semantics (they are essentially layout and alignment-compatible). If we can either 1. safely treat them as a single type for certain operations, or 2. eliminate the need for explicit conversions, we can reduce this duplication. This document attempts #2.

## New type: `EntityView`

To reduce API duplication we can try to implement a Deref "ladder" following: `EntityWorldMut` -> `EntityMut` -> `EntityRef`. However, that creates a soundness issue that we'll describe below:

```rust
#[derive(Copy, Clone)] // Remember that we can currently copy around EntityRefs
pub struct EntityRef<'w>(UnsafeEntityCell<'w>);

pub struct EntityMut<'w>(UnsafeEntityCell<'w>);

// We can deref from &'a EntityMut<'w> to &'a EntityRef<'w>
// So if we then clone the EntityRef we would now have an owned EntityRef<'w>.
// This would untie the lifetime of the EntityRef from the EntityMut,
// which means we could still mess with the EntityMut mutably while reading
// from the EntityRef. That is aliased mutability aka Undefined Behavior (UB)!
impl<'w> Deref for EntityMut<'w> {
    type Target = EntityRef<'w>;
    fn deref(&self) -> &Self::Target;
}
```

So, enter `EntityView`:

```rust
pub struct EntityView<'w>(UnsafeEntityCell<'w>);

impl<'w> EntityView<'w> {
    // Only read operations are allowed, no mutations
    pub fn id(&self) -> Entity;
    pub fn contains<T: Component>(&self) -> bool;
    pub fn get<T: Component>(&self) -> Option<&'_ T>;
    pub fn components<Q: ReadOnlyQueryData>(&self) -> Q::Item<'_>;
    // ...
}
```

It's *almost* exactly what `EntityRef` currently is *except* it doesn't impl `Clone` or `Copy`, which means we can deref `EntityMut` into it without causing UB. To keep things simple we'll also deref `EntityRef` into it, which leaves us with two separate `Deref` "ladders":

- `EntityWorldMut` -> `EntityMut` -> `EntityView`
- `EntityRef` -> `EntityView`

And if users want to go from `EntityMut` -> `EntityRef` or `EntityRef` <-> `EntityView`, we'll still provide `From`/`Into` implementations for those conversions. However, those follow a `&'a EntityMut<'w>` -> `EntityRef<'a>` conversion (i.e. following the current lifetime shortening we use) so we don't introduce any UB. See the [Public API Definition](#Public-API-Definition) below for a more complete look.

## Public API Definition

The TL;DR is that `impl<'w> Deref for EntityMut<'w> { type Target = EntityRef<'w>; }` is unsound because `impl Clone for EntityRef` so we need a new type that's like `EntityRef` but doesn't implement `Clone` or `Copy`.

```rust
#[repr(transparent)]
pub struct EntityView<'w>(UnsafeEntityCell<'w>);

impl<'w> EntityView<'w> {
    pub fn id(&self) -> Entity;
    pub fn location(&self) -> EntityLocation;
    pub fn archetype(&self) -> &Archetype;
    pub fn contains<T: Component>(&self) -> bool;
    pub fn contains_id(&self, component_id: ComponentId) -> bool;
    pub fn contains_type_id(&self, type_id: TypeId) -> bool;
    pub fn get<T: Component>(&self) -> Option<&'_ T>;
    pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>>;
    pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks>;
    pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks>;
    pub fn get_by_id<F: DynamicComponentFetch>(&self, component_ids: F) -> Result<F::Ref<'_>, EntityComponentError>;
    pub fn components<Q: ReadOnlyQueryData>(&self) -> Q::Item<'_>;
    pub fn get_components<Q: ReadOnlyQueryData>(&self) -> Option<Q::Item<'_>>;
}

impl<'w> From<EntityRef<'w>> for EntityView<'w> {}
impl<'w> From<EntityMut<'w>> for EntityView<'w> {}
impl<'w> From<EntityWorldMut<'w>> for EntityView<'w> {}
impl<'a> From<&'a EntityView<'_>> for EntityView<'a> {}
impl<'a> From<&'a EntityRef<'_>> for EntityView<'a> {}
impl<'a> From<&'a EntityMut<'_>> for EntityView<'a> {}
impl<'a> From<&'a EntityWorldMut<'w>> for EntityView<'a> {}

#[derive(Clone, Copy)]
#[repr(transparent)]
pub struct EntityRef<'w>(UnsafeEntityCell<'w>);

impl<'w> EntityRef<'w> {
    pub fn get<T: Component>(&self) -> Option<&'w T>;
    pub fn get_ref<T: Component>(&self) -> Option<Ref<'w, T>>;
    pub fn get_by_id<F: DynamicComponentFetch>(&self, component_ids: F) -> Result<F::Ref<'w>, EntityComponentError>;
    pub fn components<Q: ReadOnlyQueryData>(&self) -> Q::Item<'w>;
    pub fn get_components<Q: ReadOnlyQueryData>(&self) -> Option<Q::Item<'w>>;
}

impl<'w> Deref for EntityRef<'w> {
    type Target = EntityView<'w>;
    fn deref(&self) -> &Self::Target;
}

impl<'w> From<EntityView<'w>> for EntityRef<'w> {}
impl<'w> From<EntityMut<'w>> for EntityRef<'w> {}
impl<'w> From<EntityWorldMut<'w>> for EntityRef<'w> {}
impl<'w> From<&'a EntityView<'_>> for EntityRef<'a> {}
impl<'w> From<&'a EntityRef<'_>> for EntityRef<'a> {}
impl<'a> From<&'a EntityMut<'_>> for EntityRef<'a> {}
impl<'a> From<&'a EntityWorldMut<'w>> for EntityRef<'a> {}

#[repr(transparent)]
pub struct EntityMut<'w>(UnsafeEntityCell<'w>);

impl<'w> EntityMut<'w> {
    pub fn reborrow(&mut self) -> EntityMut<'_>;
    pub fn as_readonly(&self) -> EntityRef<'_>;
    pub fn into_borrow<T: Component>(self) -> Option<&'w T>;
    pub fn into_ref<T: Component>(self) -> Option<Ref<'w, T>>;
    pub fn get_mut<T: Component>(&mut self) -> Option<Mut<'_, T>>;
    pub fn into_mut<T: Component>(self) -> Option<Mut<'w, T>>;
    pub fn into_borrow_by_id<F: DynamicComponentFetch>(self, component_ids: F) -> Result<F::Ref<'w>, EntityComponentError>;
    pub fn get_mut_by_id<F: DynamicComponentFetch>(&mut self, component_ids: F) -> Result<F::Mut<'_>, EntityComponentError>;
    pub unsafe fn get_mut_by_id_unchecked<F: DynamicComponentFetch>(&self, component_ids: F) -> Result<F::Mut<'_>, EntityComponentError>;
    pub fn into_mut_by_id<F: DynamicComponentFetch>(self, component_ids: F) -> Result<F::Mut<'w>, EntityComponentError>;
    pub fn into_components<Q: ReadOnlyQueryData>(self) -> Q::Item<'w>;
    pub fn try_into_components<Q: ReadOnlyQueryData>(self) -> Option<Q::Item<'w>>;
}

impl<'w> Deref for EntityMut<'w> {
    type Target = EntityView<'w>;
    fn deref(&self) -> &Self::Target;
}

impl<'w> From<EntityWorldMut<'w>> for EntityMut<'w> {}
impl<'a> From<&'a mut EntityMut<'_>> for EntityMut<'a> {}
impl<'a> From<&'a mut EntityWorldMut<'_>> for EntityMut<'a> {}

#[repr(transparent)]
pub struct EntityWorldMut<'w>(UnsafeEntityCell<'w>);

impl<'w> EntityWorldMut<'w> {
    pub fn insert<T: Bundle>(&mut self, bundle: T);
    pub fn insert_if_new<T: Bundle>(&mut self, bundle: T) -> &mut Self;
    pub unsafe fn insert_by_id(&mut self, component_id: ComponentId, component: OwningPtr<'_>) -> &mut Self;
    pub unsafe fn insert_by_ids<'a, I: Iterator<Item = OwningPtr<'a>>>(&mut self, component_ids: &[ComponentId], iter_components: I) -> &mut Self;
    pub fn take<T: Bundle>(&mut self) -> Option<T>;
    pub fn remove<T: Bundle>(&mut self) -> &mut Self;
    pub fn remove_with_requires<T: Bundle>(&mut self) -> &mut Self;
    pub fn retain<T: Bundle>(&mut self) -> &mut Self;
    pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self;
    pub fn clear(&mut self) -> &mut Self;
    pub fn despawn(self);
    pub fn flush(self) -> Entity;
    pub fn world(&self) -> &World;
    pub unsafe fn world_mut(&mut self) -> &mut World;
    pub fn into_world_mut(self) -> &'w mut World;
    pub fn world_scope<U>(&mut self, f: impl FnOnce(&mut World) -> U) -> U;
    pub fn update_location(&mut self);
    pub fn entry<'a, T: Component>(&'a mut self) -> Entry<'w, 'a, T>;
    pub fn trigger(&mut self, event: impl Event) -> &mut Self;
    pub fn observe<E: Event, B: Bundle, M>(&mut self, observer: impl IntoObserverSystem<E, B, M>) -> &mut Self;
}

impl<'w> Deref for EntityWorldMut<'w> {
    type Target = EntityMut<'w>;
    fn deref(&self) -> &Self::Target;
}

impl<'w> DerefMut for EntityWorldMut<'w> {
    fn deref_mut(&mut self) -> &mut Self::Target;
}
```