use crate::ffi::{ExternPointer, IdentifiablePointer, OwnedPtr}; use crate::static_data::{Ability, AbilityImpl, EffectParameter}; use crate::StringKey; use std::ffi::{c_char, CStr, CString}; use std::ptr::drop_in_place; use std::sync::Arc; /// Instantiates a new ability. #[no_mangle] unsafe extern "C" fn ability_new( name: *const c_char, effect: *const c_char, parameters: *const OwnedPtr, parameters_length: usize, ) -> IdentifiablePointer> { 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(); let arc: Arc = Arc::new(AbilityImpl::new(&name, &effect, parameters_vec)); arc.into() } /// Drops a reference counted ability. #[no_mangle] unsafe extern "C" fn ability_drop(ptr: OwnedPtr>) { drop_in_place(ptr) } /// The name of the ability. #[no_mangle] unsafe extern "C" fn ability_name(ptr: ExternPointer>) -> OwnedPtr { CString::new(ptr.as_ref().name().str()).unwrap().into_raw() } /// The name of the script effect of the ability. #[no_mangle] unsafe extern "C" fn ability_effect(ptr: ExternPointer>) -> OwnedPtr { CString::new(ptr.as_ref().effect().str()).unwrap().into_raw() } /// The length of the parameters for the script effect of the ability. #[no_mangle] unsafe extern "C" fn ability_parameter_length(ptr: ExternPointer>) -> usize { ptr.as_ref().parameters().len() } /// Gets a parameter for the script effect of the ability. #[no_mangle] unsafe extern "C" fn ability_parameter_get( ptr: ExternPointer>, index: usize, ) -> IdentifiablePointer { if let Some(p) = ptr.as_ref().parameters().get(index) { (p as *const EffectParameter).into() } else { IdentifiablePointer::none() } }