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"] }
|
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" }
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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(())
|
||||||
|
|
|
@ -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 )*
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue