mod growth_rate_library; mod library_settings; mod nature_library; mod static_data; mod type_library; use crate::ffi::{BorrowedPtr, OwnedPtr}; use crate::static_data::*; use std::ffi::{c_char, CStr}; use std::ptr::drop_in_place; use std::sync::Arc; macro_rules! library_interface { ($library_type:ty, $return_type:ty) => { paste::paste! { #[no_mangle] extern "C" fn [< $library_type:snake _new >](capacity: usize) -> OwnedPtr<$library_type> { Box::into_raw(Box::new($library_type::new(capacity))) } #[no_mangle] unsafe extern "C" fn [< $library_type:snake _drop >](ptr: OwnedPtr<$library_type>) { drop_in_place(ptr); } #[no_mangle] unsafe extern "C" fn [< $library_type:snake _add >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr, value: OwnedPtr<$return_type>) { let lib = ptr.as_mut().unwrap(); lib.add(&CStr::from_ptr(key).into(), *Box::from_raw(value)); } #[no_mangle] unsafe extern "C" fn [< $library_type:snake _remove >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr) { let lib = ptr.as_mut().unwrap(); lib.remove(&CStr::from_ptr(key).into()); } #[no_mangle] unsafe extern "C" fn [< $library_type:snake _get >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr) -> BorrowedPtr<$return_type> { let lib = ptr.as_mut().unwrap(); let v = lib.get(&CStr::from_ptr(key).into()); if let Some(value) = v { Arc::as_ptr(value) } else { std::ptr::null() } } #[no_mangle] unsafe extern "C" fn [< $library_type:snake _get_key_by_index >](ptr: OwnedPtr<$library_type>, index: usize) -> OwnedPtr { let lib = ptr.as_mut().unwrap(); let v = lib.get_key_by_index(index); if let Some(value) = v { std::ffi::CString::new(value.str()).unwrap().into_raw() } else { std::ptr::null_mut() } } #[no_mangle] unsafe extern "C" fn [< $library_type:snake _len >](ptr: OwnedPtr<$library_type>) -> usize { let lib = ptr.as_mut().unwrap(); lib.len() } } }; } library_interface!(SpeciesLibrary, Species); library_interface!(MoveLibrary, MoveData); library_interface!(AbilityLibrary, Ability); library_interface!(ItemLibrary, Item);