use crate::ffi::ffi_handle::{FFIHandle, FromFFIHandle}; use crate::ffi::{FFIResult, NonOwnedPtrString}; use crate::static_data::{TypeIdentifier, TypeLibrary, TypeLibraryImpl}; use std::ffi::{c_char, CStr, CString}; use std::sync::Arc; /// Instantiates a new type library with a specific capacity. #[no_mangle] extern "C" fn type_library_new(capacity: usize) -> FFIHandle> { let b: Arc = Arc::new(TypeLibraryImpl::new(capacity)); FFIHandle::get_handle(b.into()) } /// Gets the type identifier for a type with a name. #[no_mangle] unsafe extern "C" fn type_library_get_type_id( ptr: FFIHandle>, key: NonOwnedPtrString, found: *mut bool, ) -> TypeIdentifier { if let Some(v) = ptr.from_ffi_handle().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: FFIHandle>, type_id: TypeIdentifier, found: *mut bool, ) -> FFIResult<*mut c_char> { if let Some(v) = ptr.from_ffi_handle().get_type_name(type_id) { *found = true; match CString::new(v.str()) { Ok(v) => FFIResult::ok(v.into_raw()), Err(e) => FFIResult::err(e.into()), } } else { *found = false; FFIResult::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: FFIHandle>, attacking: TypeIdentifier, defending: TypeIdentifier, ) -> FFIResult { ptr.from_ffi_handle() .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: FFIHandle>, attacking: TypeIdentifier, defending: *const TypeIdentifier, defending_length: usize, ) -> FFIResult { let v = std::slice::from_raw_parts(defending, defending_length); ptr.from_ffi_handle().get_effectiveness(attacking, v).into() } /// Registers a new type in the library. #[no_mangle] unsafe extern "C" fn type_library_register_type( ptr: FFIHandle>, name: NonOwnedPtrString, ) -> TypeIdentifier { ptr.from_ffi_handle().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( ptr: FFIHandle>, attacking: TypeIdentifier, defending: TypeIdentifier, effectiveness: f32, ) -> FFIResult<()> { ptr.from_ffi_handle() .set_effectiveness(attacking, defending, effectiveness) .into() }