use crate::ffi::{BorrowedPtr, ExternPointer, OwnedPtr}; use crate::static_data::{Ability, EffectParameter}; use crate::StringKey; use std::ffi::{c_char, CStr, CString}; use std::ptr::drop_in_place; #[no_mangle] unsafe extern "C" fn ability_new( name: *const c_char, effect: *const c_char, parameters: *const OwnedPtr, parameters_length: usize, ) -> OwnedPtr { let parameters = std::slice::from_raw_parts(parameters, parameters_length); let mut parameters_vec: Vec = Vec::with_capacity(parameters_length); for parameter in parameters { parameters_vec.push(*Box::from_raw(*parameter)); } let name: StringKey = CStr::from_ptr(name).to_str().unwrap().into(); let effect: StringKey = CStr::from_ptr(effect).to_str().unwrap().into(); Box::into_raw(Box::new(Ability::new(&name, &effect, parameters_vec))) } #[no_mangle] unsafe extern "C" fn ability_drop(ptr: OwnedPtr) { drop_in_place(ptr) } #[no_mangle] unsafe extern "C" fn ability_name(ptr: ExternPointer) -> OwnedPtr { CString::new(ptr.as_ref().name().str()).unwrap().into_raw() } #[no_mangle] unsafe extern "C" fn ability_effect(ptr: ExternPointer) -> OwnedPtr { CString::new(ptr.as_ref().effect().str()).unwrap().into_raw() } #[no_mangle] unsafe extern "C" fn ability_parameter_length(ptr: ExternPointer) -> usize { ptr.as_ref().parameters().len() } #[no_mangle] unsafe extern "C" fn ability_parameter_get(ptr: ExternPointer, index: usize) -> BorrowedPtr { if let Some(p) = ptr.as_ref().parameters().get(index) { p as *const EffectParameter } else { std::ptr::null() } }