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"] }
quote = "1.0.35"
proc-macro2 = "1.0.86"
itertools = "0.14.0"
utilities = { git = "https://gavania.de/hodasemi/utilities.git" }

View file

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

View file

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

View file

@ -48,16 +48,20 @@ impl Query {
quote! {
{
let entity = &entities[#index];
let mut complies = true;
#(
if !entity.components.contains::<#components>() {
return false;
complies = false;
}
)*
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}"))
.collect::<Vec<_>>();
(
quote! {
#[allow(non_snake_case)]
let (
#( #resource_idents, )*
): (
#( &mut #resource_types, )*
) = world.resources.get_mut()?;
},
resource_idents,
)
if self.resources.is_empty() {
(quote! {}, Vec::new())
} else {
(
quote! {
#[allow(non_snake_case)]
let (
#( #resource_idents, )*
): (
#( &mut #resource_types, )*
) = world.resources.get_mut()?;
},
resource_idents,
)
}
}
pub fn resource_types(&self) -> TokenStream2 {
@ -332,6 +340,8 @@ impl ToTokens for Update {
let component_requirements = self.component_requirements();
let reource_requirement = self.reource_requirement();
let query_count = self.queries.len();
let verify_dedup = self
.queries
.iter()
@ -376,10 +386,18 @@ impl ToTokens for Update {
#( #verify_dedup )*
Self {
check_entity: Box::new(move |entities| {
queries: #query_count,
check_entity: Box::new(move |entity| {
let mut comply_queries = Vec::new();
#( #check_entities )*
true
if comply_queries.is_empty() {
None
} else {
Some(comply_queries)
}
}),
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));
// let q = quote! {
// #( #updates )*
// };
// panic!("{q}");
TokenStream::from(quote! {
#( #updates )*
})