turbine_proc/
lib.rs

1use proc_macro::TokenStream;
2use proc_macro2::TokenStream as TokenStream2;
3use syn::{parse_macro_input, parse_quote, ItemFn};
4
5#[proc_macro_attribute]
6pub fn playdate_main_raw(_a: TokenStream, tokens: TokenStream) -> TokenStream {
7    let input = parse_macro_input!(tokens as ItemFn);
8    let name = input.clone().sig.ident;
9
10    let parsed: TokenStream2 = parse_quote! {
11        extern "C" fn pd_update_wrapper_fn(ud: *mut ::core::ffi::c_void) -> ::core::ffi::c_int {
12            #name(unsafe { (&mut *(ud as *mut ::turbine::sys::PlaydateAPI)).into() }).into()
13        }
14
15        #[no_mangle]
16        #[allow(unsafe_code)]
17        extern "C" fn eventHandler(pd: *mut ::turbine::sys::PlaydateAPI, event: ::turbine::sys::PDSystemEvent, arg: u32) -> ::core::ffi::c_int {
18            if event == ::turbine::sys::PDSystemEvent::kEventInit {
19                unsafe { (*(*pd).system).setUpdateCallback.unwrap()(Some(pd_update_wrapper_fn), pd as *mut ::core::ffi::c_void) }
20            }
21
22            0
23        }
24
25        #input
26    };
27
28    parsed.into()
29}
30
31#[proc_macro_attribute]
32pub fn playdate_main(_a: TokenStream, tokens: TokenStream) -> TokenStream {
33    let input = parse_macro_input!(tokens as ItemFn);
34    let name = input.clone().sig.ident;
35
36    let parsed: TokenStream2 = parse_quote! {
37        #[::turbine::playdate_main_raw] 
38        fn inject_turbine_api(pd: &mut ::turbine::sys::PlaydateAPI) -> ::core::ffi::c_int {
39            let api = &mut unsafe { ::turbine::core::PlaydateAPI::from_raw_ptr(pd as *mut ::turbine::sys::PlaydateAPI)  }.unwrap();
40
41            #name(api).into()
42        }
43
44        #input
45    };
46
47    parsed.into()
48}