From 4370853e2380762917c073235c9ca6c414778ca6 Mon Sep 17 00:00:00 2001 From: hodasemi Date: Wed, 9 Apr 2025 07:25:23 +0200 Subject: [PATCH] Start implementing proc macro solution for updates --- update_macros/src/lib.rs | 27 ++++++++++ update_macros/src/update.rs | 98 +++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 update_macros/src/update.rs diff --git a/update_macros/src/lib.rs b/update_macros/src/lib.rs index 3479469..fc09f29 100644 --- a/update_macros/src/lib.rs +++ b/update_macros/src/lib.rs @@ -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 { + let max_components = input.parse::()?.base10_parse()?; + input.parse::()?; + let max_queries = input.parse::()?.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, diff --git a/update_macros/src/update.rs b/update_macros/src/update.rs new file mode 100644 index 0000000..23cd829 --- /dev/null +++ b/update_macros/src/update.rs @@ -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, + filter: Ident, +} + +impl Query { + pub fn new(components: impl Iterator, 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::>(); + + 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::>(); + + 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, + resources: Vec, +} + +impl Update { + pub fn new(queries: impl Iterator, 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 + + + + }) +}