FFI for Pokemon class
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
use crate::dynamic_data::{BattleStatCalculator, DamageLibrary, DynamicLibrary, MiscLibrary, ScriptResolver};
|
||||
use crate::ffi::{IdentifiablePointer, OwnedPtr};
|
||||
use crate::static_data::StaticData;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn dynamic_library_new(
|
||||
@@ -9,9 +10,9 @@ extern "C" fn dynamic_library_new(
|
||||
damage_library: OwnedPtr<Box<dyn DamageLibrary>>,
|
||||
misc_library: OwnedPtr<Box<dyn MiscLibrary>>,
|
||||
script_resolver: OwnedPtr<Box<dyn ScriptResolver>>,
|
||||
) -> IdentifiablePointer<DynamicLibrary> {
|
||||
) -> IdentifiablePointer<Arc<DynamicLibrary>> {
|
||||
unsafe {
|
||||
Box::new(DynamicLibrary::new(
|
||||
Arc::new(DynamicLibrary::new(
|
||||
*Box::from_raw(static_data),
|
||||
*Box::from_raw(stat_calculator),
|
||||
*Box::from_raw(damage_library),
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
mod libraries;
|
||||
mod libraries;
|
||||
mod models;
|
||||
1
src/ffi/dynamic_data/models/mod.rs
Normal file
1
src/ffi/dynamic_data/models/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
mod pokemon;
|
||||
342
src/ffi/dynamic_data/models/pokemon.rs
Normal file
342
src/ffi/dynamic_data/models/pokemon.rs
Normal file
@@ -0,0 +1,342 @@
|
||||
use crate::defines::LevelInt;
|
||||
use crate::dynamic_data::{Battle, DamageSource, DynamicLibrary, LearnedMove, MoveLearnMethod, Pokemon};
|
||||
use crate::ffi::{ffi_arc_getter, ffi_vec_value_getters, ExternPointer, IdentifiablePointer, OwnedPtr};
|
||||
use crate::static_data::{
|
||||
Ability, AbilityIndex, Form, Gender, Item, Nature, Species, Statistic, StatisticSet, TypeIdentifier,
|
||||
};
|
||||
use std::ffi::{c_char, CStr, CString};
|
||||
use std::ptr::drop_in_place;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_new(
|
||||
library: ExternPointer<Arc<DynamicLibrary>>,
|
||||
species: ExternPointer<Arc<Species>>,
|
||||
form: ExternPointer<Arc<Form>>,
|
||||
hidden_ability: bool,
|
||||
ability_index: u8,
|
||||
level: LevelInt,
|
||||
unique_identifier: u32,
|
||||
gender: Gender,
|
||||
coloring: u8,
|
||||
nature: *const c_char,
|
||||
) -> IdentifiablePointer<Arc<Pokemon>> {
|
||||
let nature = unsafe { CStr::from_ptr(nature) }.into();
|
||||
Arc::new(Pokemon::new(
|
||||
library.as_ref().clone(),
|
||||
species.as_ref().clone(),
|
||||
form.as_ref(),
|
||||
AbilityIndex {
|
||||
hidden: hidden_ability,
|
||||
index: ability_index,
|
||||
},
|
||||
level,
|
||||
unique_identifier,
|
||||
gender,
|
||||
coloring,
|
||||
&nature,
|
||||
))
|
||||
.into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn pokemon_drop(ptr: OwnedPtr<Arc<Pokemon>>) {
|
||||
drop_in_place(ptr);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_library(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<DynamicLibrary>> {
|
||||
ptr.as_ref().library().clone().into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_species(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Species>> {
|
||||
ptr.as_ref().species().clone().into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_form(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Form>> {
|
||||
ptr.as_ref().form().clone().into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_display_species(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Species>> {
|
||||
ptr.as_ref().display_species().clone().into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_display_form(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Form>> {
|
||||
ptr.as_ref().display_form().clone().into()
|
||||
}
|
||||
|
||||
ffi_arc_getter!(Pokemon, level, LevelInt);
|
||||
ffi_arc_getter!(Pokemon, experience, u32);
|
||||
ffi_arc_getter!(Pokemon, unique_identifier, u32);
|
||||
ffi_arc_getter!(Pokemon, gender, Gender);
|
||||
ffi_arc_getter!(Pokemon, coloring, u8);
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Item>> {
|
||||
if let Some(v) = ptr.as_ref().held_item().read().as_ref() {
|
||||
v.clone().into()
|
||||
} else {
|
||||
IdentifiablePointer::none()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_has_held_item(ptr: ExternPointer<Arc<Pokemon>>, name: *const c_char) -> u8 {
|
||||
let name = unsafe { CStr::from_ptr(name) }.into();
|
||||
if ptr.as_ref().has_held_item(&name) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_set_held_item(
|
||||
ptr: ExternPointer<Arc<Pokemon>>,
|
||||
item: ExternPointer<Arc<Item>>,
|
||||
) -> IdentifiablePointer<Arc<Item>> {
|
||||
if let Some(v) = ptr.as_ref().set_held_item(item.as_ref()) {
|
||||
v.clone().into()
|
||||
} else {
|
||||
IdentifiablePointer::none()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_remove_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Item>> {
|
||||
if let Some(v) = ptr.as_ref().remove_held_item() {
|
||||
v.clone().into()
|
||||
} else {
|
||||
IdentifiablePointer::none()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_consume_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||
if ptr.as_ref().consume_held_item() {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
ffi_arc_getter!(Pokemon, current_health, u32);
|
||||
ffi_arc_getter!(Pokemon, max_health, u32);
|
||||
ffi_arc_getter!(Pokemon, weight, f32);
|
||||
ffi_arc_getter!(Pokemon, height, f32);
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_nickname(ptr: ExternPointer<Arc<Pokemon>>) -> *mut c_char {
|
||||
let name = ptr.as_ref().nickname();
|
||||
if let Some(v) = name {
|
||||
CString::new(v.as_str()).unwrap().into_raw()
|
||||
} else {
|
||||
std::ptr::null_mut()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_real_ability_is_hidden(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||
if ptr.as_ref().real_ability().hidden {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_real_ability_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||
ptr.as_ref().real_ability().index
|
||||
}
|
||||
|
||||
ffi_vec_value_getters!(Pokemon, types, TypeIdentifier);
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_learned_move_get(
|
||||
ptr: ExternPointer<Arc<Pokemon>>,
|
||||
index: usize,
|
||||
) -> IdentifiablePointer<Arc<LearnedMove>> {
|
||||
if let Some(Some(v)) = ptr.as_ref().learned_moves().read().get(index) {
|
||||
v.clone().into()
|
||||
} else {
|
||||
IdentifiablePointer::none()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_flat_stats(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<StatisticSet<u32>> {
|
||||
(ptr.as_ref().flat_stats() as *const StatisticSet<u32>).into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_boosted_stats(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<StatisticSet<u32>> {
|
||||
(ptr.as_ref().boosted_stats() as *const StatisticSet<u32>).into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_get_stat_boost(ptr: ExternPointer<Arc<Pokemon>>, statistic: Statistic) -> i8 {
|
||||
ptr.as_ref().stat_boost(statistic)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_change_stat_boost(
|
||||
ptr: ExternPointer<Arc<Pokemon>>,
|
||||
stat: Statistic,
|
||||
diff_amount: i8,
|
||||
self_inflicted: u8,
|
||||
) -> u8 {
|
||||
if ptr.as_ref().change_stat_boost(stat, diff_amount, self_inflicted == 1) {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_get_individual_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic) -> u8 {
|
||||
ptr.as_ref().individual_values().get_stat(stat)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_set_individual_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic, value: u8) {
|
||||
ptr.as_ref().individual_values().set_stat(stat, value);
|
||||
ptr.as_ref().recalculate_flat_stats();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_get_effort_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic) -> u8 {
|
||||
ptr.as_ref().effort_values().get_stat(stat)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_set_effort_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic, value: u8) {
|
||||
ptr.as_ref().effort_values().set_stat(stat, value);
|
||||
ptr.as_ref().recalculate_flat_stats();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_get_battle(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Battle> {
|
||||
if let Some(v) = ptr.as_ref().get_battle() {
|
||||
(v as *const Battle).into()
|
||||
} else {
|
||||
IdentifiablePointer::none()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_get_battle_side_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||
ptr.as_ref().get_battle_side_index().unwrap_or_default()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_get_battle_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||
ptr.as_ref().get_battle_index().unwrap_or_default()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_is_ability_overriden(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||
if ptr.as_ref().is_ability_overriden() {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_active_ability(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Ability> {
|
||||
(ptr.as_ref().active_ability() as *const Ability).into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_allowed_experience_gain(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||
if ptr.as_ref().allowed_experience_gain() {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_nature(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Nature>> {
|
||||
ptr.as_ref().nature().clone().into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_recalculate_flat_stats(ptr: ExternPointer<Arc<Pokemon>>) {
|
||||
ptr.as_ref().recalculate_flat_stats()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_recalculate_boosted_stats(ptr: ExternPointer<Arc<Pokemon>>) {
|
||||
ptr.as_ref().recalculate_boosted_stats()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_change_species(
|
||||
ptr: ExternPointer<Arc<Pokemon>>,
|
||||
species: ExternPointer<Arc<Species>>,
|
||||
form: ExternPointer<Arc<Form>>,
|
||||
) {
|
||||
ptr.as_ref()
|
||||
.change_species(species.as_ref().clone(), form.as_ref().clone())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_change_form(ptr: ExternPointer<Arc<Pokemon>>, form: ExternPointer<Arc<Form>>) {
|
||||
ptr.as_ref().change_form(form.as_ref())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_is_usable(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||
if ptr.as_ref().is_usable() {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_is_fainted(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||
if ptr.as_ref().is_fainted() {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_is_on_battlefield(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
|
||||
if ptr.as_ref().is_on_battlefield() {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_damage(ptr: ExternPointer<Arc<Pokemon>>, damage: u32, source: DamageSource) {
|
||||
ptr.as_ref().damage(damage, source)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_heal(ptr: ExternPointer<Arc<Pokemon>>, amount: u32, allow_revive: u8) -> bool {
|
||||
ptr.as_ref().heal(amount, allow_revive == 1)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_learn_move(
|
||||
ptr: ExternPointer<Arc<Pokemon>>,
|
||||
move_name: *const c_char,
|
||||
learn_method: MoveLearnMethod,
|
||||
) {
|
||||
unsafe { ptr.as_ref().learn_move(&CStr::from_ptr(move_name).into(), learn_method) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn pokemon_clear_status(ptr: ExternPointer<Arc<Pokemon>>) {
|
||||
ptr.as_ref().clear_status()
|
||||
}
|
||||
@@ -110,12 +110,6 @@ impl<T: ?Sized> ExternPointer<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Into<ExternPointer<T>> for *mut T {
|
||||
fn into(self) -> ExternPointer<T> {
|
||||
ExternPointer { ptr: self }
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub(self) struct IdentifiablePointer<T> {
|
||||
pub ptr: *const T,
|
||||
@@ -128,6 +122,12 @@ impl<T> IdentifiablePointer<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Into<ExternPointer<T>> for *mut T {
|
||||
fn into(self) -> ExternPointer<T> {
|
||||
ExternPointer { ptr: self }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ValueIdentifiable> From<Arc<T>> for IdentifiablePointer<Arc<T>> {
|
||||
fn from(v: Arc<T>) -> Self {
|
||||
let id = v.value_identifier();
|
||||
|
||||
Reference in New Issue
Block a user