PkmnLib_rs/src/ffi/static_data/libraries/type_library.rs

100 lines
3.2 KiB
Rust

use crate::ffi::{BorrowedPtr, ExternPointer, IdentifiablePointer, NativeResult, OwnedPtr};
use crate::static_data::{TypeIdentifier, TypeLibrary, TypeLibraryImpl};
use std::ffi::{c_char, CStr, CString};
use std::ptr::drop_in_place;
/// Instantiates a new type library with a specific capacity.
#[no_mangle]
extern "C" fn type_library_new(capacity: usize) -> IdentifiablePointer<Box<dyn TypeLibrary>> {
let b: Box<dyn TypeLibrary> = Box::new(TypeLibraryImpl::new(capacity));
b.into()
}
/// Drops a type library.
#[no_mangle]
unsafe extern "C" fn type_library_drop(ptr: OwnedPtr<Box<dyn TypeLibrary>>) {
drop_in_place(ptr);
}
/// Gets the type identifier for a type with a name.
#[no_mangle]
unsafe extern "C" fn type_library_get_type_id(
ptr: ExternPointer<Box<dyn TypeLibrary>>,
key: BorrowedPtr<c_char>,
found: *mut bool,
) -> TypeIdentifier {
if let Some(v) = ptr.as_ref().get_type_id(&CStr::from_ptr(key).into()) {
*found = true;
v
} else {
*found = false;
TypeIdentifier::default()
}
}
/// Gets the type name from the type identifier.
#[no_mangle]
unsafe extern "C" fn type_library_get_type_name(
ptr: ExternPointer<Box<dyn TypeLibrary>>,
type_id: TypeIdentifier,
found: *mut bool,
) -> NativeResult<*mut c_char> {
if let Some(v) = ptr.as_ref().get_type_name(type_id) {
*found = true;
match CString::new(v.str()) {
Ok(v) => NativeResult::ok(v.into_raw()),
Err(e) => NativeResult::err(e.into()),
}
} else {
*found = false;
NativeResult::ok(std::ptr::null_mut())
}
}
/// Gets the effectiveness for a single attacking type against a single defending type.
#[no_mangle]
extern "C" fn type_library_get_single_effectiveness(
ptr: ExternPointer<Box<dyn TypeLibrary>>,
attacking: TypeIdentifier,
defending: TypeIdentifier,
) -> NativeResult<f32> {
ptr.as_ref().get_single_effectiveness(attacking, defending).into()
}
/// Gets the effectiveness for a single attacking type against an amount of defending types.
/// This is equivalent to running [`type_library_get_single_effectiveness`] on each defending type,
/// and multiplying the results with each other.
#[no_mangle]
unsafe extern "C" fn type_library_get_effectiveness(
ptr: ExternPointer<Box<dyn TypeLibrary>>,
attacking: TypeIdentifier,
defending: OwnedPtr<TypeIdentifier>,
defending_length: usize,
) -> NativeResult<f32> {
let v = std::slice::from_raw_parts(defending, defending_length);
ptr.as_ref().get_effectiveness(attacking, v).into()
}
/// Registers a new type in the library.
#[no_mangle]
unsafe extern "C" fn type_library_register_type(
mut ptr: ExternPointer<Box<dyn TypeLibrary>>,
name: BorrowedPtr<c_char>,
) -> TypeIdentifier {
ptr.as_mut().register_type(&CStr::from_ptr(name).into())
}
/// Sets the effectiveness for an attacking type against a defending type.
#[no_mangle]
unsafe extern "C" fn type_library_set_effectiveness(
mut ptr: ExternPointer<Box<dyn TypeLibrary>>,
attacking: TypeIdentifier,
defending: TypeIdentifier,
effectiveness: f32,
) -> NativeResult<()> {
ptr.as_mut()
.set_effectiveness(attacking, defending, effectiveness)
.into()
}