Start implementing proc macro solution for updates

This commit is contained in:
hodasemi 2025-04-09 07:25:23 +02:00
parent fe1decdbbd
commit 4370853e23
2 changed files with 125 additions and 0 deletions

View file

@ -1,8 +1,10 @@
mod pair_update;
mod single_update;
mod update;
use pair_update::pair_update;
use single_update::single_update;
use update::update;
use proc_macro::TokenStream;
use quote::quote;
@ -13,6 +15,31 @@ use syn::{
token::Comma,
};
struct UpdateInfo {
max_components: usize,
max_queries: usize,
}
impl Parse for UpdateInfo {
fn parse(input: ParseStream) -> Result<Self> {
let max_components = input.parse::<LitInt>()?.base10_parse()?;
input.parse::<Comma>()?;
let max_queries = input.parse::<LitInt>()?.base10_parse()?;
Ok(Self {
max_components,
max_queries,
})
}
}
#[proc_macro]
pub fn implement_updates(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as UpdateInfo);
update(input.max_components, input.max_queries)
}
struct InputInfo {
macro_ident: Ident,
start: usize,

View file

@ -0,0 +1,98 @@
use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::{ToTokens, format_ident, quote};
use syn::Ident;
struct Query {
components: Vec<Ident>,
filter: Ident,
}
impl Query {
pub fn new(components: impl Iterator<Item = Ident>, filter_id: usize) -> Self {
Self {
components: components.collect(),
filter: format_ident!("Filter{filter_id}"),
}
}
pub fn types(&self) -> proc_macro2::TokenStream {
let component_list = self
.components
.iter()
.map(|c| quote! { #c, })
.collect::<Vec<_>>();
let components = if component_list.len() == 1 {
let component = &component_list[0];
quote! { #component }
} else {
quote! { ( #(#component_list)* ) }
};
components
}
pub fn filter(&self) -> &Ident {
&self.filter
}
}
impl ToTokens for Query {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
let component_list = self
.components
.iter()
.map(|c| quote! { &mut #c, })
.collect::<Vec<_>>();
let components = if component_list.len() == 1 {
let component = &component_list[0];
quote! { #component }
} else {
quote! { ( #(#component_list)* ) }
};
let filter = self.filter.clone();
proc_macro2::TokenStream::from(quote! {
Query<#components, #filter>
})
.to_tokens(tokens);
}
}
struct Update {
queries: Vec<Query>,
resources: Vec<Ident>,
}
impl Update {
pub fn new(queries: impl Iterator<Item = usize>, resources: usize) -> Self {
Self {
queries: queries
.enumerate()
.map(|(query, component_count)| {
Query::new(
(1..component_count).map(|component| format_ident!("C{component}Q{query}")),
query,
)
})
.collect(),
resources: (0..resources)
.map(|resource| format_ident!("Res{resource}"))
.collect(),
}
}
pub fn query_types(&self)
}
pub fn update(max_components: usize, max_queries: usize) -> TokenStream {
TokenStream::from(quote! {
impl<Func, Filter, >
})
}