turbo_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, ItemStruct};
4
5#[proc_macro_attribute]
6pub fn game(_attr: TokenStream, item: TokenStream) -> TokenStream {
7    let input = parse_macro_input!(item as ItemStruct);
8    let struct_ident = input.ident.clone();
9
10    let expanded = quote! {
11        #input
12
13        #[no_mangle]
14        #[cfg(turbo_hot_reload)]
15        pub unsafe extern "C" fn run() {
16            use turbo::sys;
17
18            let mut state = match sys::load() {
19                Ok(bytes) => <#struct_ident>::try_from_slice(&bytes).unwrap_or_else(|_| #struct_ident::new()),
20                Err(_) => #struct_ident::new(),
21            };
22
23            state.update();
24
25            if let Ok(bytes) = state.try_to_vec() {
26                let _ = sys::save(&bytes);
27            }
28        }
29        
30        #[no_mangle]
31        #[cfg(not(turbo_hot_reload))]
32        pub unsafe extern "C" fn run() {            
33            static mut GAME_STATE: Option<#struct_ident> = None;
34
35            let mut state = GAME_STATE.take().unwrap_or_else(#struct_ident::new);
36
37            state.update();
38
39            GAME_STATE = Some(state);
40        }
41    };
42
43    TokenStream::from(expanded)
44}