80 lines
2.7 KiB
Rust
80 lines
2.7 KiB
Rust
use crate::ffi::ffi_handle::{FFIHandle, FromFFIHandle};
|
|
use crate::ffi::{FFIResult, NonOwnedPtrString, OwnedPtrString};
|
|
use crate::static_data::{Nature, NatureLibrary, NatureLibraryImpl};
|
|
use crate::{PkmnError, Random};
|
|
use anyhow::anyhow;
|
|
use std::ffi::{CStr, CString};
|
|
use std::sync::Arc;
|
|
|
|
/// Creates a new nature library with a given capacity.
|
|
#[no_mangle]
|
|
extern "C" fn nature_library_new(capacity: usize) -> FFIHandle<Arc<dyn NatureLibrary>> {
|
|
let b: Arc<dyn NatureLibrary> = Arc::new(NatureLibraryImpl::new(capacity));
|
|
FFIHandle::get_handle(b.into())
|
|
}
|
|
|
|
/// Adds a new nature with name to the library.
|
|
#[no_mangle]
|
|
unsafe extern "C" fn nature_library_load_nature(
|
|
ptr: FFIHandle<Arc<dyn NatureLibrary>>,
|
|
name: NonOwnedPtrString,
|
|
nature: FFIHandle<Arc<dyn Nature>>,
|
|
) -> FFIResult<()> {
|
|
let nature = nature.from_ffi_handle_opt().ok_or(PkmnError::NullReference);
|
|
match nature {
|
|
Ok(nature) => {
|
|
ptr.from_ffi_handle()
|
|
.load_nature(CStr::from_ptr(name).into(), nature.clone());
|
|
FFIResult::ok(())
|
|
}
|
|
Err(e) => FFIResult::err(e.into()),
|
|
}
|
|
}
|
|
|
|
/// Gets a nature by name.
|
|
#[no_mangle]
|
|
unsafe extern "C" fn nature_library_get_nature(
|
|
ptr: FFIHandle<Arc<dyn NatureLibrary>>,
|
|
name: NonOwnedPtrString,
|
|
) -> FFIHandle<Arc<dyn Nature>> {
|
|
if let Some(nature) = ptr.from_ffi_handle().get_nature(&CStr::from_ptr(name).into()) {
|
|
FFIHandle::get_handle(nature.into())
|
|
} else {
|
|
FFIHandle::none()
|
|
}
|
|
}
|
|
|
|
/// Gets a random nature.
|
|
#[no_mangle]
|
|
unsafe extern "C" fn nature_library_get_random_nature(
|
|
ptr: FFIHandle<Arc<dyn NatureLibrary>>,
|
|
seed: u64,
|
|
) -> FFIResult<FFIHandle<Arc<dyn Nature>>> {
|
|
let mut rand = Random::new(seed as u128);
|
|
match ptr.from_ffi_handle().get_random_nature(&mut rand) {
|
|
Ok(nature) => FFIResult::ok(FFIHandle::get_handle(nature.into())),
|
|
Err(e) => FFIResult::err(e),
|
|
}
|
|
}
|
|
|
|
/// Finds a nature name by nature.
|
|
#[no_mangle]
|
|
unsafe extern "C" fn nature_library_get_nature_name(
|
|
ptr: FFIHandle<Arc<dyn NatureLibrary>>,
|
|
nature: FFIHandle<Arc<dyn Nature>>,
|
|
) -> FFIResult<OwnedPtrString> {
|
|
match nature.from_ffi_handle_opt() {
|
|
Some(nature) => {
|
|
let name = ptr.from_ffi_handle().get_nature_name(&nature);
|
|
match name {
|
|
Ok(name) => match CString::new(name.str()) {
|
|
Ok(cstr) => FFIResult::ok(OwnedPtrString(cstr.into_raw())),
|
|
Err(_) => FFIResult::err(anyhow!("Failed to convert nature name to C string")),
|
|
},
|
|
Err(e) => FFIResult::err(e),
|
|
}
|
|
}
|
|
None => FFIResult::err(PkmnError::NullReference.into()),
|
|
}
|
|
}
|