/// The foreign function interface for the growth rate library. mod growth_rate_library; /// The foreign function interface for the library settings. mod library_settings; /// The foreign function interface for the nature library. mod nature_library; /// The foreign function interface for the static data. mod static_data; /// The foreign function interface for the type library. mod type_library; use crate::ffi::{BorrowedPtr, IdentifiablePointer, OwnedPtr}; use crate::static_data::*; use std::ffi::{c_char, CStr}; use std::ptr::drop_in_place; use std::sync::Arc; /// Generates foreign function interfaces for a DataLibrary trait implementation. macro_rules! library_interface { ($library_type_name:ident, $library_type:ty, $return_type:ty) => { paste::paste! { #[no_mangle] extern "C" fn [< $library_type_name:snake _new >](capacity: usize) -> IdentifiablePointer<$library_type> { let value: $library_type = Box::new([<$library_type_name Impl>]::new(capacity)); value.into() } #[no_mangle] unsafe extern "C" fn [< $library_type_name:snake _drop >](ptr: OwnedPtr<$library_type>) { drop_in_place(ptr); } #[no_mangle] unsafe extern "C" fn [< $library_type_name:snake _add >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr, value: OwnedPtr>) { 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_name: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_name:snake _get >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr) -> IdentifiablePointer> { let lib = ptr.as_mut().unwrap(); let v = lib.get(&CStr::from_ptr(key).into()); if let Some(value) = v { value.clone().into() } else { IdentifiablePointer::none() } } #[no_mangle] unsafe extern "C" fn [< $library_type_name: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_name:snake _len >](ptr: OwnedPtr<$library_type>) -> usize { let lib = ptr.as_mut().unwrap(); lib.len() } } }; } library_interface!(SpeciesLibrary, Box, dyn Species); library_interface!(MoveLibrary, Box, dyn MoveData); library_interface!(AbilityLibrary, Box, dyn Ability); library_interface!(ItemLibrary, Box, dyn Item);