ecs/update_macros/src/single_update.rs

70 lines
1.9 KiB
Rust

use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::{format_ident, quote};
use syn::Ident;
use crate::InputInfo;
const MIN_RESOURCE: usize = 1;
pub fn single_update(input: InputInfo) -> TokenStream {
let mut generic_counts = Vec::new();
for components in input.start..=input.end {
for resources in MIN_RESOURCE..=input.end {
generic_counts.push((components, resources));
}
}
let generics: Vec<(Vec<Ident>, Vec<Ident>)> = generic_counts
.into_iter()
.map(|(component_count, resource_count)| {
let components = (input.start..(input.start + component_count))
.map(|i| format_ident!("t{}", i))
.collect();
let resources = (MIN_RESOURCE..(MIN_RESOURCE + resource_count))
.map(|i| format_ident!("r{}", i))
.collect();
(components, resources)
})
.collect();
let resource_invocations: Vec<TokenStream2> = generics
.iter()
.map(|(components, resources)| {
let macro_ident = &input.macro_ident;
quote! {
#macro_ident!(#(#components,)* [#(#resources,)*]);
}
})
.collect();
let generate_inputs: Vec<Vec<Ident>> = (input.start..=input.end)
.map(|count| {
(input.start..(input.start + count))
.map(|i| format_ident!("t{}", i))
.collect()
})
.collect();
let empty_resource_invocations: Vec<TokenStream2> = generate_inputs
.iter()
.map(|t| {
let macro_ident = &input.macro_ident;
quote! {
#macro_ident!(#(#t,)*);
}
})
.collect();
TokenStream::from(quote! {
#(
#empty_resource_invocations
#resource_invocations
)*
})
}