Start implementing proc macro solution for updates
This commit is contained in:
parent
fe1decdbbd
commit
4370853e23
2 changed files with 125 additions and 0 deletions
|
@ -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,
|
||||
|
|
98
update_macros/src/update.rs
Normal file
98
update_macros/src/update.rs
Normal 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, >
|
||||
|
||||
|
||||
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue