Compare commits

...

5 Commits

  1. 36
      src/ecs/component.rs
  2. 7
      src/ecs/entity.rs
  3. 22
      src/ecs/relation.rs

@ -37,6 +37,18 @@ impl Component {
unsafe { Flags::from_bits_masked(self.high) } unsafe { Flags::from_bits_masked(self.high) }
} }
#[inline]
#[must_use]
pub fn is_entity(&self) -> bool {
self.flags() == Flags::NONE
}
#[inline]
#[must_use]
pub fn is_relation(&self) -> bool {
self.flags() == Flags::RELATION
}
#[inline] #[inline]
#[must_use] #[must_use]
pub fn to_bits(&self) -> u64 { pub fn to_bits(&self) -> u64 {
@ -123,3 +135,27 @@ impl Flags {
value | flags.bits() value | flags.bits()
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use super::super::entity::Entity;
use super::super::relation::Relation;
#[test]
fn component_from_and_to_entity() {
let entity = Entity::new_checked(1337, 42).unwrap();
let component: Component = entity.into();
assert!(component.is_entity());
assert_eq!(entity, component.try_into().unwrap());
}
#[test]
fn component_from_and_to_relation() {
let relation = Relation::new_checked(20, 21).unwrap();
let component: Component = relation.into();
assert!(component.is_relation());
assert_eq!(relation, component.try_into().unwrap());
}
}

@ -116,7 +116,12 @@ impl TryFrom<Component> for Entity {
type Error = (); type Error = ();
#[inline] #[inline]
fn try_from(component: Component) -> Result<Self, Self::Error> { fn try_from(component: Component) -> Result<Self, Self::Error> {
Self::from_bits(component.to_bits()).ok_or(()) if component.is_entity() {
// SAFETY: If component is valid and an entity, bitwise conversion is valid.
Ok(unsafe { Self::from_bits_unchecked(component.to_bits()) })
} else {
Err(())
}
} }
} }

@ -78,9 +78,13 @@ impl Relation {
#[inline] #[inline]
#[must_use] #[must_use]
pub fn from_bits(bits: u64) -> Option<Self> { pub fn from_bits(bits: u64) -> Option<Self> {
let kind = (bits >> 32) as u32;
let target = bits as u32; let target = bits as u32;
let high = (bits >> 32) as u32;
if let (kind, Flags::RELATION) = Flags::unpack(high)? {
Self::new_checked(kind, target) Self::new_checked(kind, target)
} else {
None
}
} }
#[inline] #[inline]
@ -94,7 +98,12 @@ impl TryFrom<Component> for Relation {
type Error = (); type Error = ();
#[inline] #[inline]
fn try_from(component: Component) -> Result<Self, Self::Error> { fn try_from(component: Component) -> Result<Self, Self::Error> {
Self::from_bits(component.to_bits()).ok_or(()) if component.is_relation() {
// SAFETY: If component is valid and a relation, bitwise conversion is valid.
Ok(unsafe { Self::from_bits_unchecked(component.to_bits()) })
} else {
Err(())
}
} }
} }
@ -133,3 +142,12 @@ impl std::hash::Hash for Relation {
self.to_bits().hash(state); self.to_bits().hash(state);
} }
} }
impl std::fmt::Debug for Relation {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Relation")
.field("target", &self.target)
.field("kind", &self.kind())
.finish()
}
}

Loading…
Cancel
Save