use crate::ffi::{ffi_getter, ffi_vec_stringkey_getters, ffi_vec_value_getters, BorrowedPtr, ExternPointer, OwnedPtr}; use crate::static_data::{Form, LearnableMoves, StaticStatisticSet, TypeIdentifier}; use crate::StringKey; use hashbrown::HashSet; use std::ffi::{c_char, CStr, CString}; use std::ptr::drop_in_place; #[no_mangle] unsafe extern "C" fn form_new( name: *const c_char, height: f32, weight: f32, base_experience: u32, types: *const TypeIdentifier, types_length: usize, base_stats: OwnedPtr>, abilities: *const BorrowedPtr, abilities_length: usize, hidden_abilities: *const BorrowedPtr, hidden_abilities_length: usize, moves: OwnedPtr, flags: *const *const c_char, flags_length: usize, ) -> OwnedPtr
{ let name: StringKey = CStr::from_ptr(name).to_str().unwrap().into(); let abilities = std::slice::from_raw_parts(abilities, abilities_length); let mut abilities_vec = Vec::with_capacity(abilities_length); for ability in abilities { abilities_vec.push(CStr::from_ptr(*ability).into()) } let hidden_abilities = std::slice::from_raw_parts(hidden_abilities, hidden_abilities_length); let mut hidden_abilities_vec = Vec::with_capacity(hidden_abilities_length); for ability in hidden_abilities { hidden_abilities_vec.push(CStr::from_ptr(*ability).into()) } let flags = std::slice::from_raw_parts(flags, flags_length); let mut flags_set: HashSet = HashSet::with_capacity(flags_length); for flag in flags { flags_set.insert(CStr::from_ptr(*flag).to_str().unwrap().into()); } Box::into_raw(Box::new(Form::new( &name, height, weight, base_experience, std::slice::from_raw_parts(types, types_length).to_vec(), *Box::from_raw(base_stats), abilities_vec, hidden_abilities_vec, *Box::from_raw(moves), flags_set, ))) } #[no_mangle] unsafe extern "C" fn form_drop(ptr: OwnedPtr) { drop_in_place(ptr) } #[no_mangle] unsafe extern "C" fn form_name(ptr: ExternPointer) -> OwnedPtr { let name = ptr.as_ref().name(); CString::new(name.str()).unwrap().into_raw() } ffi_getter!(Form, height, f32); ffi_getter!(Form, weight, f32); ffi_getter!(Form, base_experience, u32); ffi_vec_value_getters!(Form, types, TypeIdentifier); ffi_getter!(Form, base_stats, BorrowedPtr>); ffi_vec_stringkey_getters!(Form, abilities); ffi_vec_stringkey_getters!(Form, hidden_abilities); ffi_getter!(Form, moves, BorrowedPtr); #[no_mangle] unsafe extern "C" fn form_has_flag(ptr: ExternPointer, flag: *const c_char) -> u8 { let flag = CStr::from_ptr(flag).into(); if ptr.as_ref().has_flag(&flag) { 1 } else { 0 } }