1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
use crate::*; macro_rules! def_api { ( struct GodotApi { core { $( $clabel:ident($cst:ident, $cver_maj:expr, $cver_min: expr) { $( pub $core_name:ident : $core_ty:ty, )* } )* } extensions { $( $elabel:ident($ety_key:ident, $est:ident, $ever_maj:expr, $ever_min: expr) { $( pub $ext_name:ident : $ext_ty:ty, )* } )* } } ) => ( #[derive(Clone)] pub struct GodotApi { $( $( pub $core_name: $core_ty, )* )* $( $( pub $ext_name: $ext_ty, )* )* } impl GodotApi { pub unsafe fn from_raw(api_raw: *const godot_gdnative_core_api_struct) -> GodotApi { $( let mut $clabel: Option<&$cst> = None; )* $( let mut $elabel: Option<&$est> = None; )* let api = &*api_raw; for i in 0 .. api.num_extensions { let ext = api.extensions.offset(i as _); let mut ext_api_ptr = *ext as *const godot_gdnative_api_struct; while !ext_api_ptr.is_null() { $( if (&*ext_api_ptr).type_ == $ety_key as u32 && ((&*ext_api_ptr).version.major == $ever_maj) && ((&*ext_api_ptr).version.minor == $ever_min) { $elabel = Some(&*(ext_api_ptr as *const $est)); } )* ext_api_ptr = (&*ext_api_ptr).next; } } { let mut core_api_ptr = api_raw as *const godot_gdnative_api_struct; while !core_api_ptr.is_null() { $( if ((&*core_api_ptr).version.major == $cver_maj) && ((&*core_api_ptr).version.minor == $cver_min) { $clabel = Some(&*(core_api_ptr as *const $cst)); } )* core_api_ptr = (&*core_api_ptr).next; } } $( let $clabel: &$cst = $clabel.expect(concat!("Missing core API: ", stringify!($clabel))); )* $( let $elabel: &$est = $elabel.expect(concat!("Missing extension: ", stringify!($elabel))); )* GodotApi { $( $( $core_name: $clabel.$core_name.expect(concat!("Missing function: ", stringify!($core_name))), )* )* $( $( $ext_name: $elabel.$ext_name.expect(concat!("Missing function: ", stringify!($ext_name))), )* )* } } } ) } include!(concat!(env!("OUT_DIR"), "/api_wrapper.rs"));