Attempt to create combinations of archetypes

This commit is contained in:
hodasemi 2025-04-09 14:40:25 +02:00
parent bbee8a0041
commit 29141e5b9a
4 changed files with 74 additions and 25 deletions

View file

@ -12,5 +12,6 @@ ron = "0.9.0"
syn = { version = "2.0.67", features = ["extra-traits", "full"] } syn = { version = "2.0.67", features = ["extra-traits", "full"] }
quote = "1.0.35" quote = "1.0.35"
proc-macro2 = "1.0.86" proc-macro2 = "1.0.86"
itertools = "0.14.0"
utilities = { git = "https://gavania.de/hodasemi/utilities.git" } utilities = { git = "https://gavania.de/hodasemi/utilities.git" }

View file

@ -11,5 +11,6 @@ serde.workspace = true
paste.workspace = true paste.workspace = true
ron.workspace = true ron.workspace = true
utilities.workspace = true utilities.workspace = true
itertools.workspace = true
update_macros = { path = "../update_macros" } update_macros = { path = "../update_macros" }

View file

@ -5,6 +5,7 @@ use std::{any::TypeId, marker::PhantomData};
use anyhow::Result; use anyhow::Result;
use indexmap::IndexMap; use indexmap::IndexMap;
use itertools::Itertools;
use update_macros::implement_updates; use update_macros::implement_updates;
use crate::resources::Resource as ResourceTrait; use crate::resources::Resource as ResourceTrait;
@ -136,7 +137,8 @@ impl ArchetypeInfo {
} }
pub struct Archetype { pub struct Archetype {
check_entity: Box<dyn Fn(&[&EntityObject]) -> bool + Send + Sync>, queries: usize,
check_entity: Box<dyn Fn(&EntityObject) -> Option<Vec<usize>> + Send + Sync>,
create_callback: Box< create_callback: Box<
dyn Fn( dyn Fn(
&[&EntityObject], &[&EntityObject],
@ -154,16 +156,38 @@ impl Archetype {
pub fn add_entities( pub fn add_entities(
&mut self, &mut self,
new_entity: &EntityObject, new_entity: &EntityObject,
entity_objects: &[&EntityObject], entity_objects: &IndexMap<Entity, EntityObject>,
) -> Result<()> { ) -> Result<()> {
if !(self.check_entity)(entity_objects) { let mut complying_entities: Vec<Vec<&EntityObject>> = vec![Vec::new(); self.queries];
return Ok(());
match (self.check_entity)(new_entity) {
Some(complying_queries) => complying_queries
.into_iter()
.for_each(|q| complying_entities[q].push(new_entity)),
None => return Ok(()),
} }
let cb = (self.create_callback)(entity_objects)?; for old_entity in entity_objects.values() {
if let Some(complying_queries) = (self.check_entity)(old_entity) {
complying_queries
.into_iter()
.for_each(|q| complying_entities[q].push(old_entity));
}
}
self.entities // check if one of the queries could not be fullfilled
.insert(entity_objects.iter().map(|e| e.as_entity()).collect(), cb); for queryable_entities in complying_entities {
if queryable_entities.is_empty() {
return Ok(());
}
}
for combinations in complying_entities.into_iter().multi_cartesian_product() {
let cb = (self.create_callback)(&combinations)?;
self.entities
.insert(combinations.iter().map(|e| e.as_entity()).collect(), cb);
}
Ok(()) Ok(())
} }
@ -227,8 +251,7 @@ impl Updates {
entities: &IndexMap<Entity, EntityObject>, entities: &IndexMap<Entity, EntityObject>,
) -> Result<()> { ) -> Result<()> {
for (_, archetype) in self.updates.iter_mut() { for (_, archetype) in self.updates.iter_mut() {
todo!(); archetype.add_entities(entity_object, entities)?;
// archetype.add_entity(entity_object, entities)?;
} }
Ok(()) Ok(())

View file

@ -48,16 +48,20 @@ impl Query {
quote! { quote! {
{ {
let entity = &entities[#index]; let mut complies = true;
#( #(
if !entity.components.contains::<#components>() { if !entity.components.contains::<#components>() {
return false; complies = false;
} }
)* )*
if !#filter::check(entity) { if !#filter::check(entity) {
return false; complies = false;
}
if complies {
comply_queries.push(#index);
} }
} }
} }
@ -265,17 +269,21 @@ impl Update {
.map(|resource| format_ident!("res_{resource}")) .map(|resource| format_ident!("res_{resource}"))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
( if self.resources.is_empty() {
quote! { (quote! {}, Vec::new())
#[allow(non_snake_case)] } else {
let ( (
#( #resource_idents, )* quote! {
): ( #[allow(non_snake_case)]
#( &mut #resource_types, )* let (
) = world.resources.get_mut()?; #( #resource_idents, )*
}, ): (
resource_idents, #( &mut #resource_types, )*
) ) = world.resources.get_mut()?;
},
resource_idents,
)
}
} }
pub fn resource_types(&self) -> TokenStream2 { pub fn resource_types(&self) -> TokenStream2 {
@ -332,6 +340,8 @@ impl ToTokens for Update {
let component_requirements = self.component_requirements(); let component_requirements = self.component_requirements();
let reource_requirement = self.reource_requirement(); let reource_requirement = self.reource_requirement();
let query_count = self.queries.len();
let verify_dedup = self let verify_dedup = self
.queries .queries
.iter() .iter()
@ -376,10 +386,18 @@ impl ToTokens for Update {
#( #verify_dedup )* #( #verify_dedup )*
Self { Self {
check_entity: Box::new(move |entities| { queries: #query_count,
check_entity: Box::new(move |entity| {
let mut comply_queries = Vec::new();
#( #check_entities )* #( #check_entities )*
true if comply_queries.is_empty() {
None
} else {
Some(comply_queries)
}
}), }),
create_callback: Box::new(move |entities| { create_callback: Box::new(move |entities| {
@ -473,6 +491,12 @@ pub fn update(max_components: usize) -> TokenStream {
// updates.push(Update::new(vec![1].into_iter(), 0)); // updates.push(Update::new(vec![1].into_iter(), 0));
// let q = quote! {
// #( #updates )*
// };
// panic!("{q}");
TokenStream::from(quote! { TokenStream::from(quote! {
#( #updates )* #( #updates )*
}) })