Skip to content

Commit

Permalink
Changing component tuples to use structs with named fields rather tha…
Browse files Browse the repository at this point in the history
…n tuples. Should be a non-breaking change for create functions.
  • Loading branch information
recatek committed Jan 20, 2025
1 parent 0f21486 commit f90381e
Show file tree
Hide file tree
Showing 13 changed files with 261 additions and 237 deletions.
112 changes: 85 additions & 27 deletions macros/src/generate/world.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use proc_macro2::{TokenStream, Literal};
use proc_macro2::{Literal, TokenStream};
use quote::{format_ident, quote};
use xxhash_rust::xxh3::xxh3_128;

Expand Down Expand Up @@ -162,24 +162,23 @@ pub fn generate_world(world_data: &DataWorld, raw_input: &str) -> TokenStream {
fn resolve_create(
&mut self,
data: <#Archetype as Archetype>::Components,
) -> Entity<#Archetype>
{
) -> Entity<#Archetype> {
self.#archetype.create(data)
}

#[inline(always)]
fn resolve_create_within_capacity(
&mut self,
data: <#Archetype as Archetype>::Components,
) -> Result<Entity<#Archetype>, <#Archetype as Archetype>::Components>
{
) -> Result<Entity<#Archetype>, <#Archetype as Archetype>::Components> {
self.#archetype.create_within_capacity(data)
}

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

Expand Down Expand Up @@ -702,14 +701,13 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {
let ArchetypeBorrow = format_ident!("{}Borrow", archetype_data.name);
let ArchetypeView = format_ident!("{}View", archetype_data.name);
let ArchetypeSlices = format_ident!("{}Slices", archetype_data.name);
let ArchetypeComponents = format_ident!("{}Components", archetype_data.name);

let ComponentsN = format_ident!("Components{}", count_str);
let ViewN = format_ident!("View{}", count_str);
let SlicesN = format_ident!("Slices{}", count_str);
let ContentArgs = quote!(#Archetype, #(#Component),*);

let StorageN = format_ident!("Storage{}", count_str);
let BorrowN = format_ident!("Borrow{}", count_str);
let StorageArgs = quote!(#Archetype, #(#Component,)*);

let IterArgs = quote!((&'a Entity<#Archetype>, #(&'a #Component,)*));
let IterMutArgs = quote!((&'a Entity<#Archetype>, #(&'a mut #Component,)*));
Expand Down Expand Up @@ -767,14 +765,14 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {
#[repr(transparent)]
pub struct #Archetype {
#[doc(hidden)]
pub data: #StorageN<#StorageArgs>,
pub data: #StorageN<#Archetype, #(#Component),*>,
}

impl Archetype for #Archetype {
#[allow(unconditional_panic)]
const ARCHETYPE_ID: u8 = #ARCHETYPE_ID;

type Components = (#(#Component,)*);
type Components = #ArchetypeComponents;
type View<'a> = #ArchetypeView<'a>;
type Borrow<'a> = #ArchetypeBorrow<'a>;
type Slices<'a> = #ArchetypeSlices<'a>;
Expand Down Expand Up @@ -823,17 +821,17 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {
#[inline(always)]
fn create(
&mut self,
data: (#(#Component,)*),
components: impl Into<Self::Components>,
) -> Entity<#Archetype> {
self.data.push(data)
self.data.push(components.into())
}

#[inline(always)]
fn create_within_capacity(
&mut self,
data: (#(#Component,)*),
) -> Result<Entity<#Archetype>, (#(#Component,)*)> {
self.data.push_within_capacity(data)
components: impl Into<Self::Components>,
) -> Result<Entity<#Archetype>, #ArchetypeComponents> {
self.data.push_within_capacity(components.into())
}

#[inline(always)]
Expand Down Expand Up @@ -893,16 +891,76 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {

#[inline(always)]
fn resolve_extract(components: &Self::Components) -> &#Component {
&components.#component_index
&components.#component
}

#[inline(always)]
fn resolve_extract_mut(components: &mut Self::Components) -> &mut #Component {
&mut components.#component_index
&mut components.#component
}
}
)*

/// Struct for named access to all of the components in an archetype's component tuple.
pub struct #ArchetypeComponents {
#(
pub #component: #Component,
)*
}

impl Components for #ArchetypeComponents {
type Archetype = #Archetype;
type Tuple = (#(#Component,)*);

fn get<C>(&self) -> &C
where
Self::Archetype: ArchetypeHas<C>
{
<Self::Archetype as ArchetypeHas<C>>::resolve_extract(self)
}

fn get_mut<C>(&mut self) -> &mut C
where
Self::Archetype: ArchetypeHas<C>
{
<Self::Archetype as ArchetypeHas<C>>::resolve_extract_mut(self)
}

fn into_tuple(self) -> Self::Tuple {
(#(self.#component,)*)
}
}

impl #ComponentsN<#(#Component,)*> for #ArchetypeComponents {
#[inline(always)]
fn raw_new(#(#component: #Component,)*) -> Self {
Self { #(#component,)* }
}

#[inline(always)]
fn raw_get(self) -> (#(#Component,)*) {
(#(self.#component,)*)
}
}

impl From<(#(#Component,)*)> for #ArchetypeComponents {
#[inline(always)]
fn from(components: (#(#Component,)*)) -> #ArchetypeComponents {
Self {
#(
#component: components.#component_index,
)*
}
}
}

impl From<#ArchetypeComponents> for (#(#Component,)*) {
#[inline(always)]
fn from(components: #ArchetypeComponents) -> (#(#Component,)*) {
(#(components.#component,)*)
}
}

/// Access to all of the stored entity and component data within this archetype.
/// Each index in these parallel slices refers to the components for a given entity.
/// Component access is mutable, but entity access is fixed (entities can't be moved).
Expand All @@ -918,7 +976,7 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {
)*
}

impl<'a> #SlicesN<'a, #ContentArgs> for #ArchetypeSlices<'a> {
impl<'a> #SlicesN<'a, #Archetype, #(#Component),*> for #ArchetypeSlices<'a> {
#[inline(always)]
fn new(
entity: &'a [Entity<#Archetype>],
Expand Down Expand Up @@ -981,7 +1039,7 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {
}
)*

impl<'a> #ViewN<'a, #ContentArgs> for #ArchetypeView<'a> {
impl<'a> #ViewN<'a, #Archetype, #(#Component),*> for #ArchetypeView<'a> {
#[inline(always)]
fn new(
index: usize,
Expand All @@ -1000,7 +1058,7 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {
/// [^1]: This list may change based on `#[cfg]` state.
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct #ArchetypeBorrow<'a>(#BorrowN<'a, #StorageArgs>);
pub struct #ArchetypeBorrow<'a>(#BorrowN<'a, #Archetype, #(#Component),*>);

impl<'a> Borrow for #ArchetypeBorrow<'a> {
type Archetype = #Archetype;
Expand Down Expand Up @@ -1052,7 +1110,7 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {
}

#[inline(always)]
fn resolve_destroy(&mut self, key: Entity<#Archetype>) -> Option<(#(#Component,)*)> {
fn resolve_destroy(&mut self, key: Entity<#Archetype>) -> Option<<Self as Archetype>::Components> {
self.data.destroy(key)
}
}
Expand All @@ -1079,7 +1137,7 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {
}

#[inline(always)]
fn resolve_destroy(&mut self, key: EntityDirect<#Archetype>) -> Option<(#(#Component,)*)> {
fn resolve_destroy(&mut self, key: EntityDirect<#Archetype>) -> Option<<Self as Archetype>::Components> {
self.data.destroy(key)
}
}
Expand Down Expand Up @@ -1130,7 +1188,7 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {
}

#[inline(always)]
fn resolve_destroy(&mut self, key: EntityAny) -> Option<(#(#Component,)*)> {
fn resolve_destroy(&mut self, key: EntityAny) -> Option<<Self as Archetype>::Components> {
match key.try_into() {
Ok(SelectEntity::#Archetype(entity)) => {
self.data.destroy(entity)
Expand Down Expand Up @@ -1187,7 +1245,7 @@ fn section_archetype(archetype_data: &DataArchetype) -> TokenStream {
}

#[inline(always)]
fn resolve_destroy(&mut self, key: EntityDirectAny) -> Option<(#(#Component,)*)> {
fn resolve_destroy(&mut self, key: EntityDirectAny) -> Option<<Self as Archetype>::Components> {
match key.try_into() {
Ok(SelectEntityDirect::#Archetype(entity)) => {
self.data.destroy(entity)
Expand Down
21 changes: 21 additions & 0 deletions src/archetype/components.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use seq_macro::seq;

macro_rules! declare_components_n {
(
$name:ident,
$n:literal
) => {
seq!(I in 0..$n {
pub trait $name<#(T~I,)*> {
#[doc(hidden)]
fn raw_new(#(c~I: T~I,)*) -> Self;
#[doc(hidden)]
fn raw_get(self) -> (#(T~I,)*);
}
});
}
}

seq!(N in 1..=16 { declare_components_n!(Components~N, N); });
#[cfg(feature = "32_components")]
seq!(N in 17..=32 { declare_components_n!(Components~N, N); });
11 changes: 2 additions & 9 deletions src/archetype/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,6 @@ macro_rules! declare_iter_n {
};
}

// Declare entries for up to 16 components.
seq!(N in 1..=16 {
declare_iter_n!(Iter~N, IterMut~N, N);
});

// Declare additional entries for up to 32 components.
seq!(N in 1..=16 { declare_iter_n!(Iter~N, IterMut~N, N); });
#[cfg(feature = "32_components")]
seq!(N in 17..=32 {
declare_iter_n!(Iter~N, IterMut~N, N);
});
seq!(N in 17..=32 { declare_iter_n!(Iter~N, IterMut~N, N); });
1 change: 1 addition & 0 deletions src/archetype/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub(crate) mod slices;
pub(crate) mod slot;
pub(crate) mod storage;
pub(crate) mod view;
pub(crate) mod components;
11 changes: 2 additions & 9 deletions src/archetype/slices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ macro_rules! declare_slices_n {
};
}

// Declare slices for up to 16 components.
seq!(N in 1..=16 {
declare_slices_n!(Slices~N, N);
});

// Declare additional slices for up to 32 components.
seq!(N in 1..=16 { declare_slices_n!(Slices~N, N); });
#[cfg(feature = "32_components")]
seq!(N in 17..=32 {
declare_slices_n!(Slices~N, N);
});
seq!(N in 17..=32 { declare_slices_n!(Slices~N, N); });
Loading

0 comments on commit f90381e

Please sign in to comment.