use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Ident};
#[proc_macro]
pub fn hotreload(input: TokenStream) -> TokenStream {
let game_struct = parse_macro_input!(input as Ident);
let expanded = quote! {
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[unsafe(no_mangle)]
pub extern "C" fn game_create() -> *mut std::ffi::c_void {
let game = Box::new(#game_struct::default());
Box::into_raw(game) as *mut std::ffi::c_void
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[unsafe(no_mangle)]
pub extern "C" fn game_destroy(game: *mut std::ffi::c_void) {
if !game.is_null() {
unsafe {
let _ = Box::from_raw(game as *mut #game_struct);
}
}
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[unsafe(no_mangle)]
pub extern "C" fn game_init(game: *mut std::ffi::c_void, engine: *mut ::roast2d::prelude::Engine) {
if !game.is_null() && !engine.is_null() {
unsafe {
let game = &mut *(game as *mut #game_struct);
let engine = &mut *engine;
game.init(engine);
}
}
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[unsafe(no_mangle)]
pub extern "C" fn game_update(game: *mut std::ffi::c_void, engine: *mut ::roast2d::prelude::Engine) {
if !game.is_null() && !engine.is_null() {
unsafe {
let game = &mut *(game as *mut #game_struct);
let engine = &mut *engine;
game.update(engine);
}
}
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[unsafe(no_mangle)]
pub extern "C" fn game_draw(game: *mut std::ffi::c_void, engine: *mut ::roast2d::prelude::Engine) {
if !game.is_null() && !engine.is_null() {
unsafe {
let game = &mut *(game as *mut #game_struct);
let engine = &mut *engine;
game.draw(engine);
}
}
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
#[unsafe(no_mangle)]
pub extern "C" fn game_cleanup(game: *mut std::ffi::c_void, engine: *mut ::roast2d::prelude::Engine) {
if !game.is_null() && !engine.is_null() {
unsafe {
let game = &mut *(game as *mut #game_struct);
let engine = &mut *engine;
game.cleanup(engine);
}
}
}
};
TokenStream::from(expanded)
}