Skip to content

Commit

Permalink
impl EntityBorrow for more types
Browse files Browse the repository at this point in the history
  • Loading branch information
Victoronz committed Dec 20, 2024
1 parent 65835f5 commit 2f57443
Show file tree
Hide file tree
Showing 4 changed files with 283 additions and 10 deletions.
259 changes: 257 additions & 2 deletions crates/bevy_ecs/src/world/entity_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use crate::{
bundle::{Bundle, BundleId, BundleInfo, BundleInserter, DynamicBundle, InsertMode},
change_detection::MutUntyped,
component::{Component, ComponentId, ComponentTicks, Components, Mutable, StorageType},
entity::{Entities, Entity, EntityCloneBuilder, EntityLocation},
entity::{
Entities, Entity, EntityBorrow, EntityCloneBuilder, EntityLocation, TrustedEntityBorrow,
},
event::Event,
observer::Observer,
query::{Access, ReadOnlyQueryData},
Expand All @@ -17,7 +19,14 @@ use bevy_ptr::{OwningPtr, Ptr};
use bevy_utils::{HashMap, HashSet};
#[cfg(feature = "track_change_detection")]
use core::panic::Location;
use core::{any::TypeId, marker::PhantomData, mem::MaybeUninit};
use core::{
any::TypeId,
borrow::Borrow,
cmp::Ordering,
hash::{Hash, Hasher},
marker::PhantomData,
mem::MaybeUninit,
};
use thiserror::Error;

use super::{unsafe_world_cell::UnsafeEntityCell, Ref, ON_REMOVE, ON_REPLACE};
Expand Down Expand Up @@ -369,6 +378,47 @@ impl<'a> TryFrom<&'a FilteredEntityMut<'_>> for EntityRef<'a> {
}
}

impl PartialEq for EntityRef<'_> {
fn eq(&self, other: &Self) -> bool {
self.entity() == other.entity()
}
}

impl Eq for EntityRef<'_> {}

impl PartialOrd for EntityRef<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.entity().partial_cmp(&other.entity())
}
}

impl Ord for EntityRef<'_> {
fn cmp(&self, other: &Self) -> Ordering {
self.entity().cmp(&other.entity())
}
}

impl Hash for EntityRef<'_> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.entity().hash(state);
}
}

impl Borrow<Entity> for EntityRef<'_> {
fn borrow(&self) -> &Entity {
&self.0.entity
}
}

impl EntityBorrow for EntityRef<'_> {
fn entity(&self) -> Entity {
self.id()
}
}

// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
unsafe impl TrustedEntityBorrow for EntityRef<'_> {}

/// Provides mutable access to a single entity and all of its components.
///
/// Contrast with [`EntityWorldMut`], which allows adding and removing components,
Expand Down Expand Up @@ -869,6 +919,47 @@ impl<'a> TryFrom<&'a mut FilteredEntityMut<'_>> for EntityMut<'a> {
}
}

impl PartialEq for EntityMut<'_> {
fn eq(&self, other: &Self) -> bool {
self.entity() == other.entity()
}
}

impl Eq for EntityMut<'_> {}

impl PartialOrd for EntityMut<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.entity().partial_cmp(&other.entity())
}
}

impl Ord for EntityMut<'_> {
fn cmp(&self, other: &Self) -> Ordering {
self.entity().cmp(&other.entity())
}
}

impl Hash for EntityMut<'_> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.entity().hash(state);
}
}

impl Borrow<Entity> for EntityMut<'_> {
fn borrow(&self) -> &Entity {
&self.0.entity
}
}

impl EntityBorrow for EntityMut<'_> {
fn entity(&self) -> Entity {
self.id()
}
}

// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
unsafe impl TrustedEntityBorrow for EntityMut<'_> {}

/// A mutable reference to a particular [`Entity`], and the entire world.
///
/// This is essentially a performance-optimized `(Entity, &mut World)` tuple,
Expand Down Expand Up @@ -2969,6 +3060,47 @@ impl<'a> From<&'a EntityWorldMut<'_>> for FilteredEntityRef<'a> {
}
}

impl PartialEq for FilteredEntityRef<'_> {
fn eq(&self, other: &Self) -> bool {
self.entity() == other.entity()
}
}

impl Eq for FilteredEntityRef<'_> {}

impl PartialOrd for FilteredEntityRef<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.entity().partial_cmp(&other.entity())
}
}

impl Ord for FilteredEntityRef<'_> {
fn cmp(&self, other: &Self) -> Ordering {
self.entity().cmp(&other.entity())
}
}

impl Hash for FilteredEntityRef<'_> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.entity().hash(state);
}
}

impl Borrow<Entity> for FilteredEntityRef<'_> {
fn borrow(&self) -> &Entity {
&self.entity.entity
}
}

impl EntityBorrow for FilteredEntityRef<'_> {
fn entity(&self) -> Entity {
self.id()
}
}

// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
unsafe impl TrustedEntityBorrow for FilteredEntityRef<'_> {}

/// Provides mutable access to a single entity and some of its components defined by the contained [`Access`].
///
/// To define the access when used as a [`QueryData`](crate::query::QueryData),
Expand Down Expand Up @@ -3258,6 +3390,47 @@ impl<'a> From<&'a mut EntityWorldMut<'_>> for FilteredEntityMut<'a> {
}
}

impl PartialEq for FilteredEntityMut<'_> {
fn eq(&self, other: &Self) -> bool {
self.entity() == other.entity()
}
}

impl Eq for FilteredEntityMut<'_> {}

impl PartialOrd for FilteredEntityMut<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.entity().partial_cmp(&other.entity())
}
}

impl Ord for FilteredEntityMut<'_> {
fn cmp(&self, other: &Self) -> Ordering {
self.entity().cmp(&other.entity())
}
}

impl Hash for FilteredEntityMut<'_> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.entity().hash(state);
}
}

impl Borrow<Entity> for FilteredEntityMut<'_> {
fn borrow(&self) -> &Entity {
&self.entity.entity
}
}

impl EntityBorrow for FilteredEntityMut<'_> {
fn entity(&self) -> Entity {
self.id()
}
}

// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
unsafe impl TrustedEntityBorrow for FilteredEntityMut<'_> {}

/// Error type returned by [`TryFrom`] conversions from filtered entity types
/// ([`FilteredEntityRef`]/[`FilteredEntityMut`]) to full-access entity types
/// ([`EntityRef`]/[`EntityMut`]).
Expand Down Expand Up @@ -3361,6 +3534,47 @@ where
}
}

impl<B: Bundle> PartialEq for EntityRefExcept<'_, B> {
fn eq(&self, other: &Self) -> bool {
self.entity() == other.entity()
}
}

impl<B: Bundle> Eq for EntityRefExcept<'_, B> {}

impl<B: Bundle> PartialOrd for EntityRefExcept<'_, B> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.entity().partial_cmp(&other.entity())
}
}

impl<B: Bundle> Ord for EntityRefExcept<'_, B> {
fn cmp(&self, other: &Self) -> Ordering {
self.entity().cmp(&other.entity())
}
}

impl<B: Bundle> Hash for EntityRefExcept<'_, B> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.entity().hash(state);
}
}

impl<B: Bundle> Borrow<Entity> for EntityRefExcept<'_, B> {
fn borrow(&self) -> &Entity {
&self.entity.entity
}
}

impl<B: Bundle> EntityBorrow for EntityRefExcept<'_, B> {
fn entity(&self) -> Entity {
self.id()
}
}

// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
unsafe impl<B: Bundle> TrustedEntityBorrow for EntityRefExcept<'_, B> {}

/// Provides mutable access to all components of an entity, with the exception
/// of an explicit set.
///
Expand Down Expand Up @@ -3464,6 +3678,47 @@ where
}
}

impl<B: Bundle> PartialEq for EntityMutExcept<'_, B> {
fn eq(&self, other: &Self) -> bool {
self.entity() == other.entity()
}
}

impl<B: Bundle> Eq for EntityMutExcept<'_, B> {}

impl<B: Bundle> PartialOrd for EntityMutExcept<'_, B> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.entity().partial_cmp(&other.entity())
}
}

impl<B: Bundle> Ord for EntityMutExcept<'_, B> {
fn cmp(&self, other: &Self) -> Ordering {
self.entity().cmp(&other.entity())
}
}

impl<B: Bundle> Hash for EntityMutExcept<'_, B> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.entity().hash(state);
}
}

impl<B: Bundle> Borrow<Entity> for EntityMutExcept<'_, B> {
fn borrow(&self) -> &Entity {
&self.entity.entity
}
}

impl<B: Bundle> EntityBorrow for EntityMutExcept<'_, B> {
fn entity(&self) -> Entity {
self.id()
}
}

// SAFETY: This type represents one Entity. We implement the comparison traits based on that Entity.
unsafe impl<B: Bundle> TrustedEntityBorrow for EntityMutExcept<'_, B> {}

fn bundle_contains_component<B>(components: &Components, query_id: ComponentId) -> bool
where
B: Bundle,
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_ecs/src/world/unsafe_world_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -650,9 +650,9 @@ impl Debug for UnsafeWorldCell<'_> {
/// A interior-mutable reference to a particular [`Entity`] and all of its components
#[derive(Copy, Clone)]
pub struct UnsafeEntityCell<'w> {
world: UnsafeWorldCell<'w>,
entity: Entity,
location: EntityLocation,
pub(crate) world: UnsafeWorldCell<'w>,
pub(crate) entity: Entity,
pub(crate) location: EntityLocation,
}

impl<'w> UnsafeEntityCell<'w> {
Expand Down
21 changes: 20 additions & 1 deletion crates/bevy_render/src/sync_world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use bevy_derive::{Deref, DerefMut};
use bevy_ecs::entity::EntityHash;
use bevy_ecs::{
component::Component,
entity::Entity,
entity::{Entity, EntityBorrow, TrustedEntityBorrow},
observer::Trigger,
query::With,
reflect::ReflectComponent,
Expand Down Expand Up @@ -140,6 +140,16 @@ impl From<Entity> for RenderEntity {
}
}

impl EntityBorrow for RenderEntity {
fn entity(&self) -> Entity {
self.id()
}
}


// SAFETY: RenderEntity is a newtype around Entity that derives its comparison traits.
unsafe impl TrustedEntityBorrow for RenderEntity {}

/// Component added on the render world entities to keep track of the corresponding main world entity.
///
/// Can also be used as a newtype wrapper for main world entities.
Expand All @@ -158,6 +168,15 @@ impl From<Entity> for MainEntity {
}
}

impl EntityBorrow for MainEntity {
fn entity(&self) -> Entity {
self.id()
}
}

// SAFETY: RenderEntity is a newtype around Entity that derives its comparison traits.
unsafe impl TrustedEntityBorrow for MainEntity {}

/// A [`HashMap`](hashbrown::HashMap) pre-configured to use [`EntityHash`] hashing with a [`MainEntity`].
pub type MainEntityHashMap<V> = hashbrown::HashMap<MainEntity, V, EntityHash>;

Expand Down
7 changes: 3 additions & 4 deletions crates/bevy_window/src/window.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::num::NonZero;

use bevy_ecs::{
entity::{Entity, VisitEntities, VisitEntitiesMut},
entity::{Entity, EntityBorrow, VisitEntities, VisitEntitiesMut},
prelude::{Component, ReflectComponent},
};
use bevy_math::{CompassOctant, DVec2, IVec2, UVec2, Vec2};
Expand Down Expand Up @@ -88,9 +88,8 @@ impl VisitEntitiesMut for WindowRef {
)]
pub struct NormalizedWindowRef(Entity);

impl NormalizedWindowRef {
/// Fetch the entity of this window reference
pub fn entity(&self) -> Entity {
impl EntityBorrow for NormalizedWindowRef {
fn entity(&self) -> Entity {
self.0
}
}
Expand Down

0 comments on commit 2f57443

Please sign in to comment.