Attempt to create combinations of archetypes
This commit is contained in:
parent
bbee8a0041
commit
29141e5b9a
4 changed files with 74 additions and 25 deletions
|
@ -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" }
|
||||
|
|
|
@ -11,5 +11,6 @@ serde.workspace = true
|
|||
paste.workspace = true
|
||||
ron.workspace = true
|
||||
utilities.workspace = true
|
||||
itertools.workspace = true
|
||||
|
||||
update_macros = { path = "../update_macros" }
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
// 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(entity_objects.iter().map(|e| e.as_entity()).collect(), cb);
|
||||
.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(())
|
||||
|
|
|
@ -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,6 +269,9 @@ impl Update {
|
|||
.map(|resource| format_ident!("res_{resource}"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if self.resources.is_empty() {
|
||||
(quote! {}, Vec::new())
|
||||
} else {
|
||||
(
|
||||
quote! {
|
||||
#[allow(non_snake_case)]
|
||||
|
@ -277,6 +284,7 @@ impl Update {
|
|||
resource_idents,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resource_types(&self) -> TokenStream2 {
|
||||
let resource_types = &self.resources;
|
||||
|
@ -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 )*
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue