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}