Skip to content

Commit

Permalink
Simplifying resolution of any-type entities (including making them no…
Browse files Browse the repository at this point in the history
… longer panic)
  • Loading branch information
recatek committed Jan 22, 2025
1 parent afda315 commit e1223aa
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 149 deletions.
141 changes: 40 additions & 101 deletions macros/src/generate/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1070,172 +1070,111 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {

impl ArchetypeCanResolve<Entity<#Archetype>> for #Archetype {
#[inline(always)]
fn resolve_for(&self, key: Entity<#Archetype>) -> Option<usize> {
self.data.resolve(key)
fn resolve_for(&self, entity: Entity<#Archetype>) -> Option<usize> {
self.data.resolve(entity)
}

#[inline(always)]
fn resolve_direct(&self, key: Entity<#Archetype>) -> Option<EntityDirect<#Archetype>> {
self.data.to_direct(key)
fn resolve_direct(&self, entity: Entity<#Archetype>) -> Option<EntityDirect<#Archetype>> {
self.data.to_direct(entity)
}

#[inline(always)]
fn resolve_view(&mut self, key: Entity<#Archetype>) -> Option<<Self as Archetype>::View<'_>> {
self.data.get_view_mut(key)
fn resolve_view(&mut self, entity: Entity<#Archetype>) -> Option<<Self as Archetype>::View<'_>> {
self.data.get_view_mut(entity)
}

#[inline(always)]
fn resolve_borrow(&self, key: Entity<#Archetype>) -> Option<<Self as Archetype>::Borrow<'_>> {
self.data.begin_borrow(key).map(#ArchetypeBorrow)
fn resolve_borrow(&self, entity: Entity<#Archetype>) -> Option<<Self as Archetype>::Borrow<'_>> {
self.data.begin_borrow(entity).map(#ArchetypeBorrow)
}

#[inline(always)]
fn resolve_destroy(&mut self, key: Entity<#Archetype>) -> Option<<Self as Archetype>::Components> {
self.data.destroy(key)
fn resolve_destroy(&mut self, entity: Entity<#Archetype>) -> Option<<Self as Archetype>::Components> {
self.data.destroy(entity)
}
}

impl ArchetypeCanResolve<EntityDirect<#Archetype>> for #Archetype {
#[inline(always)]
fn resolve_for(&self, key: EntityDirect<#Archetype>) -> Option<usize> {
self.data.resolve(key)
fn resolve_for(&self, entity: EntityDirect<#Archetype>) -> Option<usize> {
self.data.resolve(entity)
}

#[inline(always)]
fn resolve_direct(&self, key: EntityDirect<#Archetype>) -> Option<EntityDirect<#Archetype>> {
self.data.to_direct(key)
fn resolve_direct(&self, entity: EntityDirect<#Archetype>) -> Option<EntityDirect<#Archetype>> {
self.data.to_direct(entity)
}

#[inline(always)]
fn resolve_view(&mut self, key: EntityDirect<#Archetype>) -> Option<<Self as Archetype>::View<'_>> {
self.data.get_view_mut(key)
fn resolve_view(&mut self, entity: EntityDirect<#Archetype>) -> Option<<Self as Archetype>::View<'_>> {
self.data.get_view_mut(entity)
}

#[inline(always)]
fn resolve_borrow(&self, key: EntityDirect<#Archetype>) -> Option<<Self as Archetype>::Borrow<'_>> {
self.data.begin_borrow(key).map(#ArchetypeBorrow)
fn resolve_borrow(&self, entity: EntityDirect<#Archetype>) -> Option<<Self as Archetype>::Borrow<'_>> {
self.data.begin_borrow(entity).map(#ArchetypeBorrow)
}

#[inline(always)]
fn resolve_destroy(&mut self, key: EntityDirect<#Archetype>) -> Option<<Self as Archetype>::Components> {
self.data.destroy(key)
fn resolve_destroy(&mut self, entity: EntityDirect<#Archetype>) -> Option<<Self as Archetype>::Components> {
self.data.destroy(entity)
}
}

impl ArchetypeCanResolve<EntityAny> for #Archetype {
#[inline(always)]
fn resolve_for(&self, key: EntityAny) -> Option<usize> {
match key.try_into() {
Ok(SelectEntity::#Archetype(entity)) => {
self.data.resolve(entity)
},
Ok(_) => None, // Wrong archetype ID in the entity
Err(_) => panic!("invalid entity type"),
}
fn resolve_for(&self, entity: EntityAny) -> Option<usize> {
self.data.resolve(Entity::<Self>::try_from(entity).ok()?)
}

#[inline(always)]
fn resolve_direct(&self, key: EntityAny) -> Option<EntityDirectAny> {
match key.try_into() {
Ok(SelectEntity::#Archetype(entity)) => {
self.data.resolve_direct(entity).map(|e| e.into())
},
Ok(_) => None, // Wrong archetype ID in the entity
Err(_) => panic!("invalid entity type"),
}
fn resolve_direct(&self, entity: EntityAny) -> Option<EntityDirectAny> {
self.data.resolve_direct(Entity::<Self>::try_from(entity).ok()?).map(Into::into)
}

#[inline(always)]
fn resolve_view(&mut self, key: EntityAny) -> Option<<Self as Archetype>::View<'_>> {
match key.try_into() {
Ok(SelectEntity::#Archetype(entity)) => {
self.data.get_view_mut(entity)
},
Ok(_) => None, // Wrong archetype ID in the entity
Err(_) => panic!("invalid entity type"),
}
fn resolve_view(&mut self, entity: EntityAny) -> Option<<Self as Archetype>::View<'_>> {
self.data.get_view_mut(Entity::<Self>::try_from(entity).ok()?)
}

#[inline(always)]
fn resolve_borrow(&self, key: EntityAny) -> Option<<Self as Archetype>::Borrow<'_>> {
match key.try_into() {
Ok(SelectEntity::#Archetype(entity)) => {
self.data.begin_borrow(entity).map(#ArchetypeBorrow)
},
Ok(_) => None, // Wrong archetype ID in the entity
Err(_) => panic!("invalid entity type"),
}
fn resolve_borrow(&self, entity: EntityAny) -> Option<<Self as Archetype>::Borrow<'_>> {
self.data.begin_borrow(Entity::<Self>::try_from(entity).ok()?).map(#ArchetypeBorrow)
}

#[inline(always)]
fn resolve_destroy(&mut self, key: EntityAny) -> Option<<Self as Archetype>::Components> {
match key.try_into() {
Ok(SelectEntity::#Archetype(entity)) => {
self.data.destroy(entity)
},
Ok(_) => None, // Wrong archetype ID in the entity
Err(_) => panic!("invalid entity type"),
}
fn resolve_destroy(&mut self, entity: EntityAny) -> Option<<Self as Archetype>::Components> {
self.data.destroy(Entity::<Self>::try_from(entity).ok()?)
}
}

impl ArchetypeCanResolve<EntityDirectAny> for #Archetype {
#[inline(always)]
fn resolve_for(&self, key: EntityDirectAny) -> Option<usize> {
match key.try_into() {
Ok(SelectEntityDirect::#Archetype(entity)) => {
self.data.resolve(entity)
},
Ok(_) => None, // Wrong archetype ID in the entity
Err(_) => panic!("invalid entity type"),
}
fn resolve_for(&self, entity: EntityDirectAny) -> Option<usize> {
self.data.resolve(EntityDirect::<Self>::try_from(entity).ok()?)
}

#[inline(always)]
fn resolve_direct(&self, key: EntityDirectAny) -> Option<EntityDirectAny> {
match key.try_into() {
Ok(SelectEntityDirect::#Archetype(entity)) => {
self.data.resolve_direct(entity).map(|e| e.into())
},
Ok(_) => None, // Wrong archetype ID in the entity
Err(_) => panic!("invalid entity type"),
}
fn resolve_direct(&self, entity: EntityDirectAny) -> Option<EntityDirectAny> {
self.data.resolve_direct(EntityDirect::<Self>::try_from(entity).ok()?).map(Into::into)
}

#[inline(always)]
fn resolve_view(&mut self, key: EntityDirectAny) -> Option<<Self as Archetype>::View<'_>> {
match key.try_into() {
Ok(SelectEntityDirect::#Archetype(entity)) => {
self.data.get_view_mut(entity)
},
Ok(_) => None, // Wrong archetype ID in the entity
Err(_) => panic!("invalid entity type"),
}
fn resolve_view(&mut self, entity: EntityDirectAny) -> Option<<Self as Archetype>::View<'_>> {
self.data.get_view_mut(EntityDirect::<Self>::try_from(entity).ok()?)
}

#[inline(always)]
fn resolve_borrow(&self, key: EntityDirectAny) -> Option<<Self as Archetype>::Borrow<'_>> {
match key.try_into() {
Ok(SelectEntityDirect::#Archetype(entity)) => {
self.data.begin_borrow(entity).map(#ArchetypeBorrow)
},
Ok(_) => None, // Wrong archetype ID in the entity
Err(_) => panic!("invalid entity type"),
}
fn resolve_borrow(&self, entity: EntityDirectAny) -> Option<<Self as Archetype>::Borrow<'_>> {
self.data.begin_borrow(EntityDirect::<Self>::try_from(entity).ok()?).map(#ArchetypeBorrow)
}

#[inline(always)]
fn resolve_destroy(&mut self, key: EntityDirectAny) -> Option<<Self as Archetype>::Components> {
match key.try_into() {
Ok(SelectEntityDirect::#Archetype(entity)) => {
self.data.destroy(entity)
},
Ok(_) => None, // Wrong archetype ID in the entity
Err(_) => panic!("invalid entity type"),
}
fn resolve_destroy(&mut self, entity: EntityDirectAny) -> Option<<Self as Archetype>::Components> {
self.data.destroy(EntityDirect::<Self>::try_from(entity).ok()?)
}
}

)
}

Expand Down
57 changes: 10 additions & 47 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,6 @@ pub trait World: Sized {
}

/// Returns true if this world contains the given entity key.
///
///
/// # Panics
///
/// This will panic if given a dynamic key ([`EntityAny`] or [`EntityDirectAny`]) with an
/// archetype ID that is not known to this ECS world.
#[inline(always)]
fn contains<K: EntityKey>(&self, entity: K) -> bool
where
Expand All @@ -114,11 +108,6 @@ pub trait World: Sized {

/// If the entity exists in the world, this returns a direct entity pointing to its data.
/// See [`EntityDirect`] and [`EntityDirectAny`] for more information.
///
/// # Panics
///
/// This will panic if given a dynamic key ([`EntityAny`] or [`EntityDirectAny`]) with an
/// archetype ID that is not known to this ECS world.
#[inline(always)]
fn to_direct<K: EntityKey>(&self, entity: K) -> Option<K::DirectOutput>
where
Expand Down Expand Up @@ -212,11 +201,6 @@ pub trait World: Sized {
/// return component type tuple can't be known at compile time. To get the components from the
/// entity on destruction, convert the any-type entity into a typed entity before destroying it
/// (see [`SelectEntity`](crate::SelectEntity) for example).
///
/// # Panics
///
/// This will panic if given a dynamic key ([`EntityAny`] or [`EntityDirectAny`]) with an
/// archetype ID that is not known to the ECS world that this archetype was built within.
#[inline(always)]
fn destroy<K: EntityKey>(&mut self, entity: K) -> K::DestroyOutput
where
Expand Down Expand Up @@ -436,11 +420,6 @@ where

/// If the entity exists in the archetype, this returns a direct entity pointing to its data.
/// See [`EntityDirect`] and [`EntityDirectAny`] for more information.
///
/// # Panics
///
/// This will panic if given a dynamic key ([`EntityAny`] or [`EntityDirectAny`]) with an
/// archetype ID that is not known to the ECS world that this archetype was built within.
#[inline(always)]
fn to_direct<K: EntityKey>(&self, entity: K) -> Option<K::DirectOutput>
where
Expand All @@ -451,11 +430,6 @@ where

/// Returns a ['View'] with mutable references to all of this entity's components.
///
/// # Panics
///
/// This will panic if given a dynamic key ([`EntityAny`] or [`EntityDirectAny`]) with an
/// archetype ID that is not known to the ECS world that this archetype was built within.
///
/// # Examples
///
/// ```rust
Expand Down Expand Up @@ -490,12 +464,6 @@ where

/// Returns a [`Borrow`] with borrowed references to all of this entity's components.
///
/// # Panics
///
/// This will panic if given a dynamic key ([`EntityAny`] or [`EntityDirectAny`]) with an
/// archetype ID that is not known to the ECS world that this archetype was built within.
///
///
/// # Examples
///
/// ```rust
Expand Down Expand Up @@ -533,11 +501,6 @@ where
/// This returns an `Option<(C0, C1, ..., Cn)>` where `(C0, C1, ..., Cn)` are the entity's
/// former (now removed) components. A `Some` result means the entity was found and destroyed.
/// A `None` result means the given entity handle was invalid.
///
/// # Panics
///
/// This will panic if given a dynamic key ([`EntityAny`] or [`EntityDirectAny`]) with an
/// archetype ID that is not known to the ECS world that this archetype was built within.
#[inline(always)]
fn destroy<K: EntityKey>(&mut self, entity: K) -> Option<Self::Components>
where
Expand Down Expand Up @@ -932,6 +895,16 @@ pub trait ArchetypeCanResolve<K: EntityKey> {
Self: Archetype;
}

#[doc(hidden)]
pub trait StorageCanResolve<K: EntityKey> {
#[doc(hidden)]
fn resolve_for(&self, entity: K) -> Option<usize>;
#[doc(hidden)]
fn resolve_direct(&self, entity: K) -> Option<K::DirectOutput>;
#[doc(hidden)]
fn resolve_destroy(&mut self, entity: K) -> K::DestroyOutput;
}

#[doc(hidden)]
pub trait EntityKey: Clone + Copy {
#[doc(hidden)]
Expand All @@ -945,13 +918,3 @@ pub trait EntityKeyTyped<A: Archetype + ArchetypeCanResolve<Self>>: EntityKey {
#[doc(hidden)]
type Archetype: Archetype;
}

#[doc(hidden)]
pub trait StorageCanResolve<K: EntityKey> {
#[doc(hidden)]
fn resolve_for(&self, entity: K) -> Option<usize>;
#[doc(hidden)]
fn resolve_direct(&self, entity: K) -> Option<K::DirectOutput>;
#[doc(hidden)]
fn resolve_destroy(&mut self, entity: K) -> K::DestroyOutput;
}
2 changes: 1 addition & 1 deletion tests/test_generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn test_generic_view_get() {

view_get_increment(&mut world, entity);

let mut view = world.view(entity).unwrap();
let view = world.view(entity).unwrap();
assert_eq!(view.component::<CompA>().0, 2);
assert_eq!(view.component::<CompB>().0, 2);
}
Expand Down

0 comments on commit e1223aa

Please sign in to comment.