Skip to content

Endianness based Entity representation #3788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions crates/bevy_ecs/src/entity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ pub use map_entities::*;

use crate::{archetype::ArchetypeId, storage::SparseSetIndex};
use std::{
cmp::{Ordering as CmpOrdering, PartialEq},
convert::TryFrom,
fmt, mem,
fmt,
hash::{Hash, Hasher},
mem,
sync::atomic::{AtomicI64, Ordering},
};

Expand All @@ -44,9 +47,15 @@ use std::{
/// `Entity` can be a part of a query, e.g. `Query<(Entity, &MyComponent)>`.
/// Components of a specific entity can be accessed using
/// [`Query::get`](crate::system::Query::get) and related methods.
#[derive(Clone, Copy, Hash, Eq, Ord, PartialEq, PartialOrd)]
#[derive(Clone, Copy)]
#[repr(C, align(8))]
pub struct Entity {
// Do not reorder the fields here. The ordering is explicitly used by repr(C)
// to make this struct equivalent to a u64.
#[cfg(target_endian = "little")]
pub(crate) id: u32,
pub(crate) generation: u32,
#[cfg(target_endian = "big")]
pub(crate) id: u32,
}

Expand Down Expand Up @@ -114,6 +123,7 @@ impl Entity {
/// for serialization between runs.
///
/// No particular structure is guaranteed for the returned bits.
#[inline(always)]
pub fn to_bits(self) -> u64 {
u64::from(self.generation) << 32 | u64::from(self.id)
}
Expand Down Expand Up @@ -147,6 +157,38 @@ impl Entity {
}
}

// Required for ordering correctness. Cannot be done with a derive macro.
impl PartialOrd for Entity {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<CmpOrdering> {
Some(self.to_bits().cmp(&other.to_bits()))
}
}

// Required for ordering correctness. Cannot be done with a derive macro.
impl Ord for Entity {
#[inline]
fn cmp(&self, other: &Self) -> CmpOrdering {
self.to_bits().cmp(&other.to_bits())
}
}

impl Hash for Entity {
#[inline]
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.to_bits().hash(hasher)
}
}

impl PartialEq for Entity {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.to_bits() == other.to_bits()
}
}

impl Eq for Entity {}

impl fmt::Debug for Entity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}v{}", self.id, self.generation)
Expand Down