use crate::ffi::{ffi_getter, ExternPointer, OwnedPtr}; use crate::static_data::{BattleItemCategory, Item, ItemCategory}; 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 item_new( name: *const c_char, category: ItemCategory, battle_category: BattleItemCategory, price: i32, flags: *const *const c_char, flags_length: usize, ) -> OwnedPtr { let flags = std::slice::from_raw_parts(flags, flags_length); let name: StringKey = CStr::from_ptr(name).to_str().unwrap().into(); 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(Item::new(&name, category, battle_category, price, flags_set))) } #[no_mangle] unsafe extern "C" fn item_drop(ptr: OwnedPtr) { drop_in_place(ptr) } #[no_mangle] unsafe extern "C" fn item_name(ptr: ExternPointer) -> OwnedPtr { let name = ptr.as_ref().name(); CString::new(name.str()).unwrap().into_raw() } ffi_getter!(Item, category, ItemCategory); ffi_getter!(Item, battle_category, BattleItemCategory); ffi_getter!(Item, price, i32); #[no_mangle] unsafe extern "C" fn item_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 } }