band_proc_macro 0.1.9

Support library for band
Documentation
extern crate proc_macro;
use proc_macro::TokenStream;
use syn::{Lit, parse_macro_input};

#[proc_macro]
pub fn make_tuples(input: TokenStream) -> TokenStream {
    let Lit::Int(max_len_lit) = parse_macro_input!(input as Lit) else { panic!("?"); };
    let max_len = max_len_lit.base10_parse::<usize>().unwrap();
    let mut result = String::new();
    for len in 2..=max_len {
        result.push_str("impl<'a, ");
        for i in 0..len {
            let end = if i == len - 1 {
                ""
            } else {
                ", "
            };
            result.push_str(&format!("TMarker{}, ", i));
            result.push_str(&format!("T{}{}", i, end));
        }
        result.push_str("> Queryable<MultiMarker> for (");
        for i in 0..len {
            let end = if i == len - 1 {
                ""
            } else {
                ", "
            };
            result.push_str(&format!("T{}{}", i, end));
        }
        result.push_str(") {\n");

        result.push_str("type Target = Self;\n");

        result.push_str("fn translations(\n\
            translations: &mut Vec<usize>,\n\
            storage_archetype: &Archetype,\n\
            query_archetype: &Archetype,\n\
        ) {\n");

        for i in 0..len {
            result.push_str(&format!("T{}::translations(translations, storage_archetype, query_archetype);\n", i));
        }

        result.push_str("}\n");

        result.push_str("fn add(archetype: &mut Archetype) {\n");

        for i in 0..len {
            result.push_str(&format!("T{}::add(archetype);\n", i));
        }

        result.push_str("}\n");

        result.push_str("fn get(\n\
            archetype: &Archetype,\n\
            ptr: *mut u8,\n\
            entity: *const Entity, \n\
            translations: &[usize], \n\
            idx: &mut usize, \n\
        ) -> Self {\n(\n");

        for i in 0..len {
            result.push_str(&format!("T{}::get(archetype, ptr, entity, translations, idx);\n", i));
        }

        result.push_str(")\n}\n");

        result.push_str("fn refs(deps: &mut HashSet<TypeId>) {\n");

        for i in 0..len {
            result.push_str(&format!("T{}::refs(deps);\n", i));
        }

        result.push_str("}\n");


        result.push_str("fn muts(deps: &mut HashSet<TypeId>) {\n");

        for i in 0..len {
            result.push_str(&format!("T{}::muts(deps);\n", i));
        }

        result.push_str("}\n");
        result.push_str("}\n");
    }
    result.parse().unwrap()
}

#[proc_macro]
pub fn make_systems(input: TokenStream) -> TokenStream {
    let Lit::Int(max_len_lit) = parse_macro_input!(input as Lit) else { panic!("?"); };
    let max_len = max_len_lit.base10_parse::<usize>().unwrap();
    let mut result = String::new();
    for len in 1..=max_len {
        result.push_str("impl<");
        for i in 0..len {
            result.push_str(&format!("TT{}, ", i));
            result.push_str(&format!("T{}: Queryable<TT{}>, ", i, i));
        }
        result.push_str("Function: Fn(");
        for i in 0..len {
            let end = if i == len - 1 && len != 1 {
                ""
            } else {
                ", "
            };
            result.push_str(&format!("T{}{}", i, end));
        }
        result.push_str(")> System<(");
        for i in 0..len {
            result.push_str(&format!("T{},", i));
        }
        result.push_str(")> for Function { \n");
        result.push_str("type Param = (");
        for i in 0..len {
            let end = if i == len - 1 {
                ""
            } else {
                ", "
            };
            result.push_str(&format!("T{}{}", i, end));
        }
        result.push_str(");\n");
        result.push_str("fn execute(&self, _: *mut Registry, (");
        for i in 0..len {
            let end = if i == len - 1 {
                ""
            } else {
                ", "
            };
            result.push_str(&format!("t{}{}", i, end));
        }
        result.push_str("): Self::Param) { self.call(");
        for i in 0..len {
            let end = if i == len - 1 && len != 1 {
                ""
            } else {
                ", "
            };
            result.push_str(&format!("t{}{}", i, end));
        }
        result.push_str(") }\n");

        result.push_str("\
            fn ref_deps(&self) -> HashSet<TypeId> { \n\
                unreachable!() \n\
            } \n\
            fn mut_deps(&self) -> HashSet<TypeId> {\n\
                unreachable!()\n\
            }\n\
        ");
        result.push_str("}\n");
    }
    result.parse().unwrap()
}