Skip to main content

roast2d_macro/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, Ident};
4
5#[proc_macro]
6pub fn hotreload(input: TokenStream) -> TokenStream {
7    let game_struct = parse_macro_input!(input as Ident);
8
9    let expanded = quote! {
10
11        #[allow(clippy::not_unsafe_ptr_arg_deref)]
12        #[unsafe(no_mangle)]
13        pub extern "C" fn game_create() -> *mut std::ffi::c_void {
14            let game = Box::new(#game_struct::default());
15            Box::into_raw(game) as *mut std::ffi::c_void
16        }
17
18        #[allow(clippy::not_unsafe_ptr_arg_deref)]
19        #[unsafe(no_mangle)]
20        pub extern "C" fn game_destroy(game: *mut std::ffi::c_void) {
21            if !game.is_null() {
22                unsafe {
23                    let _ = Box::from_raw(game as *mut #game_struct);
24                }
25            }
26        }
27
28        #[allow(clippy::not_unsafe_ptr_arg_deref)]
29        #[unsafe(no_mangle)]
30        pub extern "C" fn game_init(game: *mut std::ffi::c_void, engine: *mut ::roast2d::prelude::Engine) {
31            if !game.is_null() && !engine.is_null() {
32                unsafe {
33                    let game = &mut *(game as *mut #game_struct);
34                    let engine = &mut *engine;
35                    game.init(engine);
36                }
37            }
38        }
39
40        #[allow(clippy::not_unsafe_ptr_arg_deref)]
41        #[unsafe(no_mangle)]
42        pub extern "C" fn game_update(game: *mut std::ffi::c_void, engine: *mut ::roast2d::prelude::Engine) {
43            if !game.is_null() && !engine.is_null() {
44                unsafe {
45                    let game = &mut *(game as *mut #game_struct);
46                    let engine = &mut *engine;
47                    game.update(engine);
48                }
49            }
50        }
51
52        #[allow(clippy::not_unsafe_ptr_arg_deref)]
53        #[unsafe(no_mangle)]
54        pub extern "C" fn game_draw(game: *mut std::ffi::c_void, engine: *mut ::roast2d::prelude::Engine) {
55            if !game.is_null() && !engine.is_null() {
56                unsafe {
57                    let game = &mut *(game as *mut #game_struct);
58                    let engine = &mut *engine;
59                    game.draw(engine);
60                }
61            }
62        }
63
64        #[allow(clippy::not_unsafe_ptr_arg_deref)]
65        #[unsafe(no_mangle)]
66        pub extern "C" fn game_cleanup(game: *mut std::ffi::c_void, engine: *mut ::roast2d::prelude::Engine) {
67            if !game.is_null() && !engine.is_null() {
68                unsafe {
69                    let game = &mut *(game as *mut #game_struct);
70                    let engine = &mut *engine;
71                    game.cleanup(engine);
72                }
73            }
74        }
75    };
76
77    TokenStream::from(expanded)
78}