Style and Clippy fixes.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2022-10-14 16:53:30 +02:00
parent 9efe1b4e22
commit 691bf7c12e
56 changed files with 354 additions and 249 deletions

View File

@@ -1,6 +1,7 @@
use crate::dynamic_data::{BattleStatCalculator, Gen7BattleStatCalculator};
use crate::ffi::IdentifiablePointer;
/// Creates a new Gen 7 battle stat calculator
#[no_mangle]
extern "C" fn gen_7_battle_stat_calculator_new() -> IdentifiablePointer<Box<dyn BattleStatCalculator>> {
let v: Box<dyn BattleStatCalculator> = Box::new(Gen7BattleStatCalculator::new());

View File

@@ -1,6 +1,8 @@
use crate::dynamic_data::{DamageLibrary, Gen7DamageLibrary};
use crate::ffi::IdentifiablePointer;
/// Creates a new generation 7 damage library. `has_randomness` defines whether a random damage
/// modifier (0.85x - 1.00x) is applied to the calculated damage.
#[no_mangle]
extern "C" fn gen_7_damage_library_new(randomness: u8) -> IdentifiablePointer<Box<dyn DamageLibrary>> {
let v: Box<dyn DamageLibrary> = Box::new(Gen7DamageLibrary::new(randomness == 1));

View File

@@ -3,6 +3,7 @@ use crate::ffi::{IdentifiablePointer, OwnedPtr};
use crate::static_data::StaticData;
use std::sync::Arc;
/// Instantiates a new DynamicLibrary with given parameters.
#[no_mangle]
extern "C" fn dynamic_library_new(
static_data: OwnedPtr<StaticData>,

View File

@@ -1,6 +1,7 @@
use crate::dynamic_data::{Gen7MiscLibrary, MiscLibrary};
use crate::ffi::IdentifiablePointer;
/// Instantiates a new MiscLibrary.
#[no_mangle]
extern "C" fn gen_7_misc_library_new() -> IdentifiablePointer<Box<dyn MiscLibrary>> {
let v: Box<dyn MiscLibrary> = Box::new(Gen7MiscLibrary::new());

View File

@@ -1,5 +1,10 @@
/// The foreign function interfaces for the battle stat calculator
mod battle_stat_calculator;
/// The foreign function interfaces for the damage library
mod damage_library;
/// The foreign function interfaces for the dynamic library
mod dynamic_library;
/// The foreign function interfaces for the misc library
mod misc_library;
/// The foreign function interfaces for the script resolver
mod script_resolver;

View File

@@ -1,6 +1,7 @@
use crate::dynamic_data::{EmptyScriptResolver, ScriptResolver};
use crate::ffi::IdentifiablePointer;
/// Instantiates a basic empty script resolver, that always returns None.
#[no_mangle]
extern "C" fn empty_script_resolver_new() -> IdentifiablePointer<Box<dyn ScriptResolver>> {
let v: Box<dyn ScriptResolver> = Box::new(EmptyScriptResolver {
@@ -11,12 +12,14 @@ extern "C" fn empty_script_resolver_new() -> IdentifiablePointer<Box<dyn ScriptR
IdentifiablePointer::new(ptr, id)
}
/// Foreign function interfaces for the Webassembly script resolver.
#[cfg(feature = "wasm")]
mod web_assembly_script_resolver {
use crate::dynamic_data::ScriptResolver;
use crate::ffi::{ExternPointer, IdentifiablePointer};
use crate::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver;
/// Instantiates a new WebAssemblyScriptResolver.
#[no_mangle]
extern "C" fn webassembly_script_resolver_new() -> IdentifiablePointer<Box<dyn ScriptResolver>> {
let v: Box<dyn ScriptResolver> = WebAssemblyScriptResolver::new();
@@ -25,17 +28,19 @@ mod web_assembly_script_resolver {
IdentifiablePointer::new(ptr, id)
}
/// Load a compiled WASM module.
#[no_mangle]
extern "C" fn webassembly_script_resolver_load_wasm_from_bytes(
ptr: ExternPointer<Box<WebAssemblyScriptResolver>>,
mut ptr: ExternPointer<Box<WebAssemblyScriptResolver>>,
arr: *const u8,
len: usize,
) {
unsafe { ptr.as_mut().load_wasm_from_bytes(std::slice::from_raw_parts(arr, len)) }
}
/// Tells the script resolver we're done loading wasm modules, and to finalize the resolver.
#[no_mangle]
extern "C" fn webassembly_script_resolver_finalize(ptr: ExternPointer<Box<WebAssemblyScriptResolver>>) {
extern "C" fn webassembly_script_resolver_finalize(mut ptr: ExternPointer<Box<WebAssemblyScriptResolver>>) {
ptr.as_mut().finalize();
}
}

View File

@@ -1,2 +1,4 @@
/// The foreign function interfaces for the dynamic data libraries
mod libraries;
mod models;
/// The foreign function interfaces for the dynamic data models
mod models;

View File

@@ -1 +1,2 @@
/// The foreign function interface for a Pokemon.
mod pokemon;

View File

@@ -8,6 +8,7 @@ use std::ffi::{c_char, CStr, CString};
use std::ptr::drop_in_place;
use std::sync::Arc;
/// Instantiates a new Pokemon.
#[no_mangle]
extern "C" fn pokemon_new(
library: ExternPointer<Arc<DynamicLibrary>>,
@@ -39,34 +40,40 @@ extern "C" fn pokemon_new(
.into()
}
/// Drops an Arc reference held by the FFI.
#[no_mangle]
unsafe extern "C" fn pokemon_drop(ptr: OwnedPtr<Arc<Pokemon>>) {
drop_in_place(ptr);
}
/// The library data of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_library(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<DynamicLibrary>> {
ptr.as_ref().library().clone().into()
}
/// The species of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_species(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Species>> {
ptr.as_ref().species().clone().into()
ptr.as_ref().species().into()
}
/// The form of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_form(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Form>> {
ptr.as_ref().form().clone().into()
ptr.as_ref().form().into()
}
/// The species that should be displayed to the user. This handles stuff like the Illusion ability.
#[no_mangle]
extern "C" fn pokemon_display_species(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Species>> {
ptr.as_ref().display_species().clone().into()
ptr.as_ref().display_species().into()
}
/// The form that should be displayed to the user. This handles stuff like the Illusion ability.
#[no_mangle]
extern "C" fn pokemon_display_form(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Form>> {
ptr.as_ref().display_form().clone().into()
ptr.as_ref().display_form().into()
}
ffi_arc_getter!(Pokemon, level, LevelInt);
@@ -75,6 +82,7 @@ ffi_arc_getter!(Pokemon, unique_identifier, u32);
ffi_arc_getter!(Pokemon, gender, Gender);
ffi_arc_getter!(Pokemon, coloring, u8);
/// Gets the held item of a Pokemon
#[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() {
@@ -84,44 +92,40 @@ extern "C" fn pokemon_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> Identifiabl
}
}
/// Checks whether the Pokemon is holding a specific item.
#[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
}
u8::from(ptr.as_ref().has_held_item(&name))
}
/// Changes the held item of the Pokemon. Returns the previously held item.
#[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()
v.into()
} else {
IdentifiablePointer::none()
}
}
/// Removes the held item from the Pokemon. Returns the previously held item.
#[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()
v.into()
} else {
IdentifiablePointer::none()
}
}
/// Makes the Pokemon uses its held item.
#[no_mangle]
extern "C" fn pokemon_consume_held_item(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
if ptr.as_ref().consume_held_item() {
1
} else {
0
}
u8::from(ptr.as_ref().consume_held_item())
}
ffi_arc_getter!(Pokemon, current_health, u32);
@@ -129,6 +133,7 @@ ffi_arc_getter!(Pokemon, max_health, u32);
ffi_arc_getter!(Pokemon, weight, f32);
ffi_arc_getter!(Pokemon, height, f32);
/// An optional nickname of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_nickname(ptr: ExternPointer<Arc<Pokemon>>) -> *mut c_char {
let name = ptr.as_ref().nickname();
@@ -139,15 +144,13 @@ extern "C" fn pokemon_nickname(ptr: ExternPointer<Arc<Pokemon>>) -> *mut c_char
}
}
/// Whether the actual ability on the form is a hidden ability.
#[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
}
u8::from(ptr.as_ref().real_ability().hidden)
}
/// The index of the actual ability on the form.
#[no_mangle]
extern "C" fn pokemon_real_ability_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
ptr.as_ref().real_ability().index
@@ -155,6 +158,8 @@ extern "C" fn pokemon_real_ability_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8
ffi_vec_value_getters!(Pokemon, types, TypeIdentifier);
/// Gets a learned move of the Pokemon. Index should generally be below [`MAX_MOVES`], you will get
/// a null pointer otherwise.
#[no_mangle]
extern "C" fn pokemon_learned_move_get(
ptr: ExternPointer<Arc<Pokemon>>,
@@ -167,21 +172,25 @@ extern "C" fn pokemon_learned_move_get(
}
}
/// The stats of the Pokemon when disregarding any stat boosts.
#[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()
}
/// The stats of the Pokemon including the stat boosts.
#[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()
}
/// Get the stat boosts for a specific stat.
#[no_mangle]
extern "C" fn pokemon_get_stat_boost(ptr: ExternPointer<Arc<Pokemon>>, statistic: Statistic) -> i8 {
ptr.as_ref().stat_boost(statistic)
}
/// Change a boosted stat by a certain amount.
#[no_mangle]
extern "C" fn pokemon_change_stat_boost(
ptr: ExternPointer<Arc<Pokemon>>,
@@ -189,35 +198,37 @@ extern "C" fn pokemon_change_stat_boost(
diff_amount: i8,
self_inflicted: u8,
) -> u8 {
if ptr.as_ref().change_stat_boost(stat, diff_amount, self_inflicted == 1) {
1
} else {
0
}
u8::from(ptr.as_ref().change_stat_boost(stat, diff_amount, self_inflicted == 1))
}
/// Gets a [individual value](https://bulbapedia.bulbagarden.net/wiki/Individual_values) of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_get_individual_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic) -> u8 {
ptr.as_ref().individual_values().get_stat(stat)
}
/// Modifies a [individual value](https://bulbapedia.bulbagarden.net/wiki/Individual_values) of the Pokemon.
#[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();
}
/// Gets a [effort value](https://bulbapedia.bulbagarden.net/wiki/Effort_values) of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_get_effort_value(ptr: ExternPointer<Arc<Pokemon>>, stat: Statistic) -> u8 {
ptr.as_ref().effort_values().get_stat(stat)
}
/// Modifies a [effort value](https://bulbapedia.bulbagarden.net/wiki/Effort_values) of the Pokemon.
#[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();
}
/// Gets the data for the battle the Pokemon is currently in. If the Pokemon is not in a battle, this
/// returns null.
#[no_mangle]
extern "C" fn pokemon_get_battle(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Battle> {
if let Some(v) = ptr.as_ref().get_battle() {
@@ -227,54 +238,59 @@ extern "C" fn pokemon_get_battle(ptr: ExternPointer<Arc<Pokemon>>) -> Identifiab
}
}
/// Get the index of the side of the battle the Pokemon is in. If the Pokemon
/// is not on the battlefield, this always returns 0.
#[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()
}
/// Get the index of the slot on the side of the battle the Pokemon is in. If the Pokemon
// is not on the battlefield, this always returns 0.
#[no_mangle]
extern "C" fn pokemon_get_battle_index(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
ptr.as_ref().get_battle_index().unwrap_or_default()
}
/// Returns whether something overrides the ability.
#[no_mangle]
extern "C" fn pokemon_is_ability_overriden(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
if ptr.as_ref().is_ability_overriden() {
1
} else {
0
}
u8::from(ptr.as_ref().is_ability_overriden())
}
/// Returns the currently active ability.
#[no_mangle]
extern "C" fn pokemon_active_ability(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Ability> {
(ptr.as_ref().active_ability() as *const Ability).into()
}
/// Whether or not the Pokemon is allowed to gain experience.
#[no_mangle]
extern "C" fn pokemon_allowed_experience_gain(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
if ptr.as_ref().allowed_experience_gain() {
1
} else {
0
}
u8::from(ptr.as_ref().allowed_experience_gain())
}
/// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_nature(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Nature>> {
ptr.as_ref().nature().clone().into()
}
/// Calculates the flat stats on the Pokemon. This should be called when for example the base
/// stats, level, nature, IV, or EV changes. This has a side effect of recalculating the boosted
/// stats, as those depend on the flat stats.
#[no_mangle]
extern "C" fn pokemon_recalculate_flat_stats(ptr: ExternPointer<Arc<Pokemon>>) {
ptr.as_ref().recalculate_flat_stats()
}
/// Calculates the boosted stats on the Pokemon. This should be called when a stat boost changes.
#[no_mangle]
extern "C" fn pokemon_recalculate_boosted_stats(ptr: ExternPointer<Arc<Pokemon>>) {
ptr.as_ref().recalculate_boosted_stats()
}
/// Change the species of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_change_species(
ptr: ExternPointer<Arc<Pokemon>>,
@@ -285,48 +301,44 @@ extern "C" fn pokemon_change_species(
.change_species(species.as_ref().clone(), form.as_ref().clone())
}
/// Change the form of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_change_form(ptr: ExternPointer<Arc<Pokemon>>, form: ExternPointer<Arc<Form>>) {
ptr.as_ref().change_form(form.as_ref())
}
/// Whether or not the Pokemon is useable in a battle.
#[no_mangle]
extern "C" fn pokemon_is_usable(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
if ptr.as_ref().is_usable() {
1
} else {
0
}
u8::from(ptr.as_ref().is_usable())
}
/// Returns whether the Pokemon is fainted.
#[no_mangle]
extern "C" fn pokemon_is_fainted(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
if ptr.as_ref().is_fainted() {
1
} else {
0
}
u8::from(ptr.as_ref().is_fainted())
}
/// Whether or not the Pokemon is on the battlefield.
#[no_mangle]
extern "C" fn pokemon_is_on_battlefield(ptr: ExternPointer<Arc<Pokemon>>) -> u8 {
if ptr.as_ref().is_on_battlefield() {
1
} else {
0
}
u8::from(ptr.as_ref().is_on_battlefield())
}
/// Damages the Pokemon by a certain amount of damage, from a damage source.
#[no_mangle]
extern "C" fn pokemon_damage(ptr: ExternPointer<Arc<Pokemon>>, damage: u32, source: DamageSource) {
ptr.as_ref().damage(damage, source)
}
/// Heals the Pokemon by a specific amount. Unless allow_revive is set to true, this will not
/// heal if the Pokemon has 0 health. If the amount healed is 0, this will return false.
#[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)
}
/// Learn a move.
#[no_mangle]
extern "C" fn pokemon_learn_move(
ptr: ExternPointer<Arc<Pokemon>>,
@@ -336,6 +348,7 @@ extern "C" fn pokemon_learn_move(
unsafe { ptr.as_ref().learn_move(&CStr::from_ptr(move_name).into(), learn_method) }
}
/// Removes the current non-volatile status from the Pokemon.
#[no_mangle]
extern "C" fn pokemon_clear_status(ptr: ExternPointer<Arc<Pokemon>>) {
ptr.as_ref().clear_status()

View File

@@ -1,22 +1,14 @@
/// The foreign function interfaces for the dynamic data
mod dynamic_data;
/// The foreign function interfaces for that static data
mod static_data;
/// Helper type for clearer functions.
type OwnedPtr<T> = *mut T;
/// Helper type for clearer functions.
type BorrowedPtr<T> = *const T;
macro_rules! ffi_getter {
(
$type:ty, $func:ident, $returns: ty
) => {
paste::paste! {
#[no_mangle]
extern "C" fn [< $type:snake _ $func >](ptr: ExternPointer<$type>) -> $returns {
ptr.as_ref().$func()
}
}
};
}
/// Generates a basic getter foreign function interface.
macro_rules! ffi_arc_getter {
(
$type:ty, $func:ident, $returns: ty
@@ -30,6 +22,7 @@ macro_rules! ffi_arc_getter {
};
}
/// Generates a basic getter foreign function interface where the return type is a [`crate::StringKey`].
macro_rules! ffi_arc_stringkey_getter {
(
$type:ty, $func:ident
@@ -43,6 +36,7 @@ macro_rules! ffi_arc_stringkey_getter {
};
}
/// Generates a foreign function interface for a vec. This generates a length function, and a getter.
macro_rules! ffi_vec_value_getters {
(
$type:ty, $func:ident, $returns: ty
@@ -60,6 +54,8 @@ macro_rules! ffi_vec_value_getters {
};
}
/// Generates a foreign function interface for a vec of [`crate::StringKey`]. This generates a
/// length function, and a getter.
macro_rules! ffi_vec_stringkey_getters {
(
$type:ident, $func:ident
@@ -80,57 +76,62 @@ macro_rules! ffi_vec_stringkey_getters {
use crate::{ValueIdentifiable, ValueIdentifier};
pub(self) use ffi_arc_getter;
pub(self) use ffi_arc_stringkey_getter;
pub(self) use ffi_getter;
pub(self) use ffi_vec_stringkey_getters;
pub(self) use ffi_vec_value_getters;
use std::mem::transmute;
use std::sync::Arc;
/// Helper utility class to wrap a pointer for extern functions.
#[repr(C)]
pub(self) struct ExternPointer<T: ?Sized> {
/// The wrapped pointer.
ptr: *mut T,
}
impl<T: ?Sized> ExternPointer<T> {
/// Get the internal pointer as reference.
pub(self) fn as_ref(&self) -> &T {
unsafe {
self.ptr.as_ref().expect(&format!(
"Given pointer of type '{}' was null",
std::any::type_name::<T>()
))
self.ptr
.as_ref()
.unwrap_or_else(|| panic!("Given pointer of type '{}' was null", std::any::type_name::<T>()))
}
}
pub(self) fn as_mut(&self) -> &mut T {
/// Get the internal pointer as mutable reference.
pub(self) fn as_mut(&mut self) -> &mut T {
unsafe {
self.ptr.as_mut().expect(&format!(
"Given pointer of type '{}' was null",
std::any::type_name::<T>()
))
self.ptr
.as_mut()
.unwrap_or_else(|| panic!("Given pointer of type '{}' was null", std::any::type_name::<T>()))
}
}
}
/// Helper utility class to give both the pointer and identifier to a FFI.
#[repr(C)]
pub(self) struct IdentifiablePointer<T> {
/// The wrapped pointer.
pub ptr: *const T,
pub id: ValueIdentifier,
/// The identifier of the pointer.
pub id: usize,
}
impl<T> IdentifiablePointer<T> {
/// Creates a new IdentifiablePointer.
pub(self) fn new(ptr: *const T, id: ValueIdentifier) -> Self {
Self { ptr, id }
unsafe { Self { ptr, id: transmute(id) } }
}
}
impl<T> Into<ExternPointer<T>> for *mut T {
fn into(self) -> ExternPointer<T> {
ExternPointer { ptr: self }
impl<T> From<*mut T> for ExternPointer<T> {
fn from(ptr: *mut T) -> Self {
ExternPointer { ptr }
}
}
impl<T: ValueIdentifiable> From<Arc<T>> for IdentifiablePointer<Arc<T>> {
fn from(v: Arc<T>) -> Self {
let id = v.value_identifier();
let id = unsafe { transmute(v.value_identifier()) };
Self {
ptr: Box::into_raw(Box::new(v)),
id,
@@ -140,7 +141,7 @@ impl<T: ValueIdentifiable> From<Arc<T>> for IdentifiablePointer<Arc<T>> {
impl<T: ValueIdentifiable> From<Box<T>> for IdentifiablePointer<T> {
fn from(v: Box<T>) -> Self {
let id = v.value_identifier();
let id = unsafe { transmute(v.value_identifier()) };
Self {
ptr: Box::into_raw(v),
id,
@@ -150,12 +151,13 @@ impl<T: ValueIdentifiable> From<Box<T>> for IdentifiablePointer<T> {
impl<T: ValueIdentifiable> From<*const T> for IdentifiablePointer<T> {
fn from(v: *const T) -> Self {
let id = unsafe { v.as_ref() }.unwrap().value_identifier();
let id = unsafe { transmute(v.as_ref().unwrap().value_identifier()) };
Self { ptr: v, id }
}
}
impl<T> IdentifiablePointer<T> {
/// Returns an identifiable pointer with null as pointer, and 0 as identifier.
pub fn none() -> Self {
Self {
ptr: std::ptr::null(),

View File

@@ -5,6 +5,7 @@ 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,
@@ -24,26 +25,31 @@ unsafe extern "C" fn ability_new(
Arc::new(Ability::new(&name, &effect, parameters_vec)).into()
}
/// Drops a reference counted ability.
#[no_mangle]
unsafe extern "C" fn ability_drop(ptr: OwnedPtr<Arc<Ability>>) {
drop_in_place(ptr)
}
/// The name of the ability.
#[no_mangle]
unsafe extern "C" fn ability_name(ptr: ExternPointer<Arc<Ability>>) -> OwnedPtr<c_char> {
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<Arc<Ability>>) -> OwnedPtr<c_char> {
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<Arc<Ability>>) -> 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<Arc<Ability>>,

View File

@@ -9,6 +9,7 @@ use std::ffi::{c_char, CStr, CString};
use std::ptr::drop_in_place;
use std::sync::Arc;
/// Instantiates a new form.
#[no_mangle]
unsafe extern "C" fn form_new(
name: *const c_char,
@@ -60,11 +61,13 @@ unsafe extern "C" fn form_new(
.into()
}
/// Drops a reference count for a form.
#[no_mangle]
unsafe extern "C" fn form_drop(ptr: OwnedPtr<Arc<Form>>) {
drop_in_place(ptr)
}
/// The name of the form.
#[no_mangle]
unsafe extern "C" fn form_name(ptr: ExternPointer<Arc<Form>>) -> OwnedPtr<c_char> {
let name = ptr.as_ref().name();
@@ -77,6 +80,7 @@ ffi_arc_getter!(Form, base_experience, u32);
ffi_vec_value_getters!(Form, types, TypeIdentifier);
/// The inherent values of a form of species that are used for the stats of a Pokemon.
#[no_mangle]
unsafe extern "C" fn form_base_stats(ptr: ExternPointer<Arc<Form>>) -> IdentifiablePointer<StaticStatisticSet<u16>> {
(ptr.as_ref().base_stats() as *const StaticStatisticSet<u16>).into()
@@ -87,12 +91,9 @@ ffi_vec_stringkey_getters!(Form, hidden_abilities);
ffi_arc_getter!(Form, moves, BorrowedPtr<LearnableMoves>);
/// Check if the form has a specific flag set.
#[no_mangle]
unsafe extern "C" fn form_has_flag(ptr: ExternPointer<Arc<Form>>, flag: *const c_char) -> u8 {
let flag = CStr::from_ptr(flag).into();
if ptr.as_ref().has_flag(&flag) {
1
} else {
0
}
u8::from(ptr.as_ref().has_flag(&flag))
}

View File

@@ -3,22 +3,27 @@ use crate::ffi::{ExternPointer, OwnedPtr};
use crate::static_data::{GrowthRate, LookupGrowthRate};
use std::ptr::drop_in_place;
/// Instantiates a new lookup growth rate. The experience array should be the amount of experience
/// required per level, with the first element being the experience required for level 1 (generally 0).
#[no_mangle]
unsafe extern "C" fn growth_rate_lookup_new(array: *const u32, length: usize) -> OwnedPtr<Box<dyn GrowthRate>> {
let array = std::slice::from_raw_parts(array, length);
Box::into_raw(Box::new(Box::new(LookupGrowthRate::new(array.to_vec()))))
}
/// Drops the growth rate.
#[no_mangle]
unsafe extern "C" fn growth_rate_lookup_drop(ptr: OwnedPtr<Box<dyn GrowthRate>>) {
drop_in_place(ptr)
}
/// Calculate the level something with this growth rate would have at a certain experience.
#[no_mangle]
extern "C" fn growth_rate_calculate_level(ptr: ExternPointer<Box<dyn GrowthRate>>, experience: u32) -> LevelInt {
ptr.as_ref().calculate_level(experience)
}
/// Calculate the experience something with this growth rate would have at a certain level.
#[no_mangle]
extern "C" fn growth_rate_calculate_experience(ptr: ExternPointer<Box<dyn GrowthRate>>, level: LevelInt) -> u32 {
ptr.as_ref().calculate_experience(level)

View File

@@ -6,6 +6,7 @@ use std::ffi::{c_char, CStr, CString};
use std::ptr::drop_in_place;
use std::sync::Arc;
/// Instantiates an item.
#[no_mangle]
unsafe extern "C" fn item_new(
name: *const c_char,
@@ -24,11 +25,13 @@ unsafe extern "C" fn item_new(
Arc::new(Item::new(&name, category, battle_category, price, flags_set)).into()
}
/// Drops a reference counted item.
#[no_mangle]
unsafe extern "C" fn item_drop(ptr: OwnedPtr<Arc<Item>>) {
drop_in_place(ptr)
}
/// The name of the item.
#[no_mangle]
unsafe extern "C" fn item_name(ptr: ExternPointer<Arc<Item>>) -> OwnedPtr<c_char> {
let name = ptr.as_ref().name();
@@ -39,12 +42,9 @@ ffi_arc_getter!(Item, category, ItemCategory);
ffi_arc_getter!(Item, battle_category, BattleItemCategory);
ffi_arc_getter!(Item, price, i32);
/// Checks whether the item has a specific flag.
#[no_mangle]
unsafe extern "C" fn item_has_flag(ptr: ExternPointer<Arc<Item>>, flag: *const c_char) -> u8 {
let flag = CStr::from_ptr(flag).into();
if ptr.as_ref().has_flag(&flag) {
1
} else {
0
}
u8::from(ptr.as_ref().has_flag(&flag))
}

View File

@@ -4,19 +4,22 @@ use crate::static_data::LearnableMoves;
use std::ffi::{c_char, CStr};
use std::ptr::drop_in_place;
/// Instantiates a new Learnable Moves.
#[no_mangle]
extern "C" fn learnable_moves_new() -> OwnedPtr<LearnableMoves> {
Box::into_raw(Box::new(LearnableMoves::new()))
}
/// drops a learnablemoves struct.
#[no_mangle]
unsafe extern "C" fn learnable_moves_drop(ptr: OwnedPtr<LearnableMoves>) {
drop_in_place(ptr)
}
/// Adds a new level move the Pokemon can learn.
#[no_mangle]
unsafe extern "C" fn learnable_moves_add_level_move(
ptr: ExternPointer<LearnableMoves>,
mut ptr: ExternPointer<LearnableMoves>,
level: LevelInt,
move_name: BorrowedPtr<c_char>,
) {

View File

@@ -4,16 +4,19 @@ use crate::static_data::{GrowthRate, GrowthRateLibrary};
use std::ffi::{c_char, CStr};
use std::ptr::drop_in_place;
/// Instantiates a new growth rate library with a capacity
#[no_mangle]
extern "C" fn growth_rate_library_new(capacity: usize) -> IdentifiablePointer<GrowthRateLibrary> {
Box::new(GrowthRateLibrary::new(capacity)).into()
}
/// Drops the growthrate library.
#[no_mangle]
unsafe extern "C" fn growth_rate_library_drop(ptr: OwnedPtr<GrowthRateLibrary>) {
drop_in_place(ptr)
}
/// Calculates the level for a given growth key name and a certain experience.
#[no_mangle]
unsafe extern "C" fn growth_rate_library_calculate_level(
ptr: ExternPointer<GrowthRateLibrary>,
@@ -24,6 +27,7 @@ unsafe extern "C" fn growth_rate_library_calculate_level(
.calculate_level(&CStr::from_ptr(growth_rate).into(), experience)
}
/// Calculates the experience for a given growth key name and a certain level.
#[no_mangle]
unsafe extern "C" fn growth_rate_library_calculate_experience(
ptr: ExternPointer<GrowthRateLibrary>,
@@ -34,9 +38,10 @@ unsafe extern "C" fn growth_rate_library_calculate_experience(
.calculate_experience(&CStr::from_ptr(growth_rate).into(), level)
}
/// Adds a new growth rate with a name and value.
#[no_mangle]
unsafe extern "C" fn growth_rate_library_add_growth_rate(
ptr: ExternPointer<GrowthRateLibrary>,
mut ptr: ExternPointer<GrowthRateLibrary>,
name: BorrowedPtr<c_char>,
growth_rate: OwnedPtr<Box<dyn GrowthRate>>,
) {

View File

@@ -3,16 +3,19 @@ use crate::ffi::{ExternPointer, IdentifiablePointer, OwnedPtr};
use crate::static_data::LibrarySettings;
use std::ptr::drop_in_place;
/// Creates a new settings library.
#[no_mangle]
extern "C" fn library_settings_new(max_level: LevelInt) -> IdentifiablePointer<LibrarySettings> {
Box::new(LibrarySettings::new(max_level)).into()
}
/// Drop a library settings object.
#[no_mangle]
unsafe extern "C" fn library_settings_drop(ptr: OwnedPtr<LibrarySettings>) {
drop_in_place(ptr)
}
/// The highest level a Pokemon can be.
#[no_mangle]
extern "C" fn library_settings_maximum_level(ptr: ExternPointer<LibrarySettings>) -> LevelInt {
ptr.as_ref().maximum_level()

View File

@@ -1,7 +1,12 @@
/// The foreign function interface for the growth rate library.
mod growth_rate_library;
/// The foreign function interface for the library settings.
mod library_settings;
/// The foreign function interface for the nature library.
mod nature_library;
/// The foreign function interface for the static data.
mod static_data;
/// The foreign function interface for the type library.
mod type_library;
use crate::ffi::{BorrowedPtr, IdentifiablePointer, OwnedPtr};
@@ -10,6 +15,7 @@ use std::ffi::{c_char, CStr};
use std::ptr::drop_in_place;
use std::sync::Arc;
/// Generates foreign function interfaces for a DataLibrary trait implementation.
macro_rules! library_interface {
($library_type:ty, $return_type:ty) => {
paste::paste! {

View File

@@ -4,19 +4,22 @@ use std::ffi::{c_char, CStr, CString};
use std::ptr::drop_in_place;
use std::sync::Arc;
/// Creates a new nature library with a given capacity.
#[no_mangle]
extern "C" fn nature_library_new(capacity: usize) -> IdentifiablePointer<NatureLibrary> {
Box::new(NatureLibrary::new(capacity)).into()
}
/// Drop a nature library.
#[no_mangle]
unsafe extern "C" fn nature_library_drop(ptr: OwnedPtr<NatureLibrary>) {
drop_in_place(ptr);
}
/// Adds a new nature with name to the library.
#[no_mangle]
unsafe extern "C" fn nature_library_load_nature(
ptr: ExternPointer<NatureLibrary>,
mut ptr: ExternPointer<NatureLibrary>,
name: BorrowedPtr<c_char>,
nature: OwnedPtr<Arc<Nature>>,
) {
@@ -24,6 +27,7 @@ unsafe extern "C" fn nature_library_load_nature(
.load_nature(CStr::from_ptr(name).into(), nature.as_ref().unwrap().clone())
}
/// Gets a nature by name.
#[no_mangle]
unsafe extern "C" fn nature_library_get_nature(
ptr: ExternPointer<NatureLibrary>,
@@ -36,6 +40,7 @@ unsafe extern "C" fn nature_library_get_nature(
}
}
/// Finds a nature name by nature.
#[no_mangle]
unsafe extern "C" fn nature_library_get_nature_name(
ptr: ExternPointer<NatureLibrary>,

View File

@@ -5,54 +5,64 @@ use crate::static_data::{
};
use std::ptr::drop_in_place;
/// Instantiates a new data collection.
#[no_mangle]
unsafe extern "C" fn static_data_new(settings: OwnedPtr<LibrarySettings>) -> IdentifiablePointer<StaticData> {
Box::new(StaticData::new(*Box::from_raw(settings))).into()
}
/// Drop a static data.
#[no_mangle]
unsafe extern "C" fn static_data_drop(ptr: OwnedPtr<StaticData>) {
drop_in_place(ptr)
}
/// Several misc settings for the library.
#[no_mangle]
unsafe extern "C" fn static_data_settings(data: ExternPointer<StaticData>) -> IdentifiablePointer<LibrarySettings> {
unsafe extern "C" fn static_data_settings(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<LibrarySettings> {
(data.as_mut().settings() as *const LibrarySettings).into()
}
/// All data for Pokemon species.
#[no_mangle]
unsafe extern "C" fn static_data_species(data: ExternPointer<StaticData>) -> IdentifiablePointer<SpeciesLibrary> {
unsafe extern "C" fn static_data_species(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<SpeciesLibrary> {
(data.as_mut().species_mut() as *const SpeciesLibrary).into()
}
/// All data for the moves.
#[no_mangle]
unsafe extern "C" fn static_data_moves(data: ExternPointer<StaticData>) -> IdentifiablePointer<MoveLibrary> {
unsafe extern "C" fn static_data_moves(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<MoveLibrary> {
(data.as_mut().moves_mut() as *const MoveLibrary).into()
}
/// All data for the items.
#[no_mangle]
unsafe extern "C" fn static_data_items(data: ExternPointer<StaticData>) -> IdentifiablePointer<ItemLibrary> {
unsafe extern "C" fn static_data_items(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<ItemLibrary> {
(data.as_mut().items_mut() as *const ItemLibrary).into()
}
/// All data for growth rates.
#[no_mangle]
unsafe extern "C" fn static_data_growth_rates(
data: ExternPointer<StaticData>,
mut data: ExternPointer<StaticData>,
) -> IdentifiablePointer<GrowthRateLibrary> {
(data.as_mut().growth_rates_mut() as *const GrowthRateLibrary).into()
}
/// All data related to types and type effectiveness.
#[no_mangle]
unsafe extern "C" fn static_data_types(data: ExternPointer<StaticData>) -> IdentifiablePointer<TypeLibrary> {
unsafe extern "C" fn static_data_types(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<TypeLibrary> {
(data.as_mut().types_mut() as *const TypeLibrary).into()
}
/// All data related to natures.
#[no_mangle]
unsafe extern "C" fn static_data_natures(data: ExternPointer<StaticData>) -> IdentifiablePointer<NatureLibrary> {
unsafe extern "C" fn static_data_natures(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<NatureLibrary> {
(data.as_mut().natures_mut() as *const NatureLibrary).into()
}
/// All data related to abilities.
#[no_mangle]
unsafe extern "C" fn static_data_abilities(data: ExternPointer<StaticData>) -> IdentifiablePointer<AbilityLibrary> {
unsafe extern "C" fn static_data_abilities(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<AbilityLibrary> {
(data.as_mut().abilities_mut() as *const AbilityLibrary).into()
}

View File

@@ -3,16 +3,19 @@ use crate::static_data::{TypeIdentifier, TypeLibrary};
use std::ffi::{c_char, CStr, CString};
use std::ptr::drop_in_place;
/// Instantiates a new type library with a specific capacity.
#[no_mangle]
extern "C" fn type_library_new(capacity: usize) -> IdentifiablePointer<TypeLibrary> {
Box::new(TypeLibrary::new(capacity)).into()
}
/// Drops a type library.
#[no_mangle]
unsafe extern "C" fn type_library_drop(ptr: OwnedPtr<TypeLibrary>) {
drop_in_place(ptr);
}
/// Gets the type identifier for a type with a name.
#[no_mangle]
unsafe extern "C" fn type_library_get_type_id(
ptr: ExternPointer<TypeLibrary>,
@@ -28,6 +31,7 @@ unsafe extern "C" fn type_library_get_type_id(
}
}
/// Gets the type name from the type identifier.
#[no_mangle]
unsafe extern "C" fn type_library_get_type_name(
ptr: ExternPointer<TypeLibrary>,
@@ -43,6 +47,7 @@ unsafe extern "C" fn type_library_get_type_name(
}
}
/// Gets the effectiveness for a single attacking type against a single defending type.
#[no_mangle]
extern "C" fn type_library_get_single_effectiveness(
ptr: ExternPointer<TypeLibrary>,
@@ -52,6 +57,9 @@ extern "C" fn type_library_get_single_effectiveness(
ptr.as_ref().get_single_effectiveness(attacking, defending)
}
/// Gets the effectiveness for a single attacking type against an amount of defending types.
/// This is equivalent to running [`type_library_get_single_effectiveness`] on each defending type,
/// and multiplying the results with each other.
#[no_mangle]
unsafe extern "C" fn type_library_get_effectiveness(
ptr: ExternPointer<TypeLibrary>,
@@ -63,17 +71,19 @@ unsafe extern "C" fn type_library_get_effectiveness(
ptr.as_ref().get_effectiveness(attacking, v)
}
/// Registers a new type in the library.
#[no_mangle]
unsafe extern "C" fn type_library_register_type(
ptr: ExternPointer<TypeLibrary>,
mut ptr: ExternPointer<TypeLibrary>,
name: BorrowedPtr<c_char>,
) -> TypeIdentifier {
ptr.as_mut().register_type(&CStr::from_ptr(name).into())
}
/// Sets the effectiveness for an attacking type against a defending type.
#[no_mangle]
unsafe extern "C" fn type_library_set_effectiveness(
ptr: ExternPointer<TypeLibrary>,
mut ptr: ExternPointer<TypeLibrary>,
attacking: TypeIdentifier,
defending: TypeIdentifier,
effectiveness: f32,

View File

@@ -4,43 +4,59 @@ use crate::StringKey;
use std::ffi::{c_char, CStr, CString};
use std::ptr::drop_in_place;
/// The Foreign Function Interface for abilities
mod ability;
/// The Foreign Function Interface for forms
mod form;
/// The Foreign Function Interface for growth rates
mod growth_rate;
/// The Foreign Function Interface for items
mod item;
/// The Foreign Function Interface for learnable moves
mod learnable_moves;
/// The Foreign Function Interface for libraries
mod libraries;
/// The Foreign Function Interface for moves
mod move_data;
/// The Foreign Function Interface for natures
mod nature;
/// The Foreign Function Interface for species
mod species;
/// The Foreign Function Interface for sets of statistics
mod statistic_set;
/// Instantiates an effect parameter with a boolean.
#[no_mangle]
extern "C" fn effect_parameter_new_bool(value: u8) -> OwnedPtr<EffectParameter> {
Box::into_raw(Box::new((value == 1).into()))
}
/// Instantiates an effect parameter with an integer.
#[no_mangle]
extern "C" fn effect_parameter_new_int(value: i64) -> OwnedPtr<EffectParameter> {
Box::into_raw(Box::new(value.into()))
}
/// Instantiates an effect parameter with a float.
#[no_mangle]
extern "C" fn effect_parameter_new_float(value: f32) -> OwnedPtr<EffectParameter> {
Box::into_raw(Box::new(value.into()))
}
/// Instantiates an effect parameter with a string.
#[no_mangle]
unsafe extern "C" fn effect_parameter_new_string(value: *const c_char) -> OwnedPtr<EffectParameter> {
let sk: StringKey = CStr::from_ptr(value).to_str().unwrap().into();
Box::into_raw(Box::new(sk.into()))
}
/// Drop an effect parameter.
#[no_mangle]
unsafe extern "C" fn effect_parameter_drop(ptr: OwnedPtr<EffectParameter>) {
drop_in_place(ptr)
}
/// Get the type of an effect parameter.
#[no_mangle]
extern "C" fn effect_parameter_get_type(ptr: ExternPointer<EffectParameter>) -> u8 {
match ptr.as_ref() {
@@ -51,15 +67,17 @@ extern "C" fn effect_parameter_get_type(ptr: ExternPointer<EffectParameter>) ->
}
}
/// Get the boolean contained in the effect parameter, panics if the effect parameter is not a bool.
#[no_mangle]
extern "C" fn effect_parameter_get_as_bool(ptr: ExternPointer<EffectParameter>) -> u8 {
let p = ptr.as_ref();
if let EffectParameter::Bool(_, b) = p {
return if *b { 1 } else { 0 };
return u8::from(*b);
}
panic!("Unexpected effect parameter. Expected bool, was: {}", p);
}
/// Get the int contained in the effect parameter, panics if the effect parameter is not a int.
#[no_mangle]
extern "C" fn effect_parameter_get_as_int(ptr: ExternPointer<EffectParameter>) -> i64 {
let p = ptr.as_ref();
@@ -69,6 +87,7 @@ extern "C" fn effect_parameter_get_as_int(ptr: ExternPointer<EffectParameter>) -
panic!("Unexpected effect parameter. Expected int, was: {}", p);
}
/// Get the float contained in the effect parameter, panics if the effect parameter is not a float.
#[no_mangle]
extern "C" fn effect_parameter_get_as_float(ptr: ExternPointer<EffectParameter>) -> f32 {
let p = ptr.as_ref();
@@ -78,6 +97,7 @@ extern "C" fn effect_parameter_get_as_float(ptr: ExternPointer<EffectParameter>)
panic!("Unexpected effect parameter. Expected float, was: {}", p);
}
/// Get the string contained in the effect parameter, panics if the effect parameter is not a string.
#[no_mangle]
extern "C" fn effect_parameter_get_as_string(ptr: ExternPointer<EffectParameter>) -> OwnedPtr<c_char> {
let p = ptr.as_ref();

View File

@@ -1,4 +1,4 @@
use crate::ffi::{ffi_arc_getter, ffi_getter, BorrowedPtr, ExternPointer, IdentifiablePointer, OwnedPtr};
use crate::ffi::{ffi_arc_getter, BorrowedPtr, ExternPointer, IdentifiablePointer, OwnedPtr};
use crate::static_data::{EffectParameter, MoveCategory, MoveData, MoveTarget, SecondaryEffect, TypeIdentifier};
use crate::StringKey;
use hashbrown::HashSet;
@@ -6,6 +6,7 @@ use std::ffi::{c_char, CStr, CString};
use std::ptr::drop_in_place;
use std::sync::Arc;
/// Instantiates a new move.
#[no_mangle]
unsafe extern "C" fn move_data_new(
name: *const c_char,
@@ -46,11 +47,13 @@ unsafe extern "C" fn move_data_new(
.into()
}
/// Drops a reference counted move.
#[no_mangle]
unsafe extern "C" fn move_data_drop(ptr: OwnedPtr<Arc<MoveData>>) {
drop_in_place(ptr)
}
/// The name of the move.
#[no_mangle]
unsafe extern "C" fn move_data_name(ptr: ExternPointer<Arc<MoveData>>) -> OwnedPtr<c_char> {
let name = ptr.as_ref().name();
@@ -65,6 +68,7 @@ ffi_arc_getter!(MoveData, base_usages, u8);
ffi_arc_getter!(MoveData, target, MoveTarget);
ffi_arc_getter!(MoveData, priority, i8);
/// The optional secondary effect the move has.
#[no_mangle]
unsafe extern "C" fn move_data_secondary_effect(
ptr: ExternPointer<Arc<MoveData>>,
@@ -77,16 +81,14 @@ unsafe extern "C" fn move_data_secondary_effect(
}
}
/// Arbitrary flags that can be applied to the move.
#[no_mangle]
unsafe extern "C" fn move_data_has_flag(ptr: ExternPointer<Arc<MoveData>>, flag: *const c_char) -> u8 {
let flag = CStr::from_ptr(flag).into();
if ptr.as_ref().has_flag(&flag) {
1
} else {
0
}
u8::from(ptr.as_ref().has_flag(&flag))
}
/// Instantiates a new Secondary Effect.
#[no_mangle]
unsafe extern "C" fn secondary_effect_new(
chance: f32,
@@ -108,23 +110,31 @@ unsafe extern "C" fn secondary_effect_new(
.into()
}
/// Drop a secondary effect.
#[no_mangle]
unsafe extern "C" fn secondary_effect_drop(ptr: OwnedPtr<SecondaryEffect>) {
drop_in_place(ptr)
}
ffi_getter!(SecondaryEffect, chance, f32);
/// The chance the effect triggers.
#[no_mangle]
unsafe extern "C" fn secondary_effect_chance(ptr: ExternPointer<SecondaryEffect>) -> f32 {
ptr.as_ref().chance()
}
/// The name of the effect.
#[no_mangle]
unsafe extern "C" fn secondary_effect_effect_name(ptr: ExternPointer<SecondaryEffect>) -> OwnedPtr<c_char> {
CString::new(ptr.as_ref().effect_name().str()).unwrap().into_raw()
}
/// The length of parameters of the effect.
#[no_mangle]
unsafe extern "C" fn secondary_effect_parameter_length(ptr: ExternPointer<SecondaryEffect>) -> usize {
ptr.as_ref().parameters().len()
}
/// Get a parameter of the effect.
#[no_mangle]
unsafe extern "C" fn secondary_effect_parameter_get(
ptr: ExternPointer<SecondaryEffect>,

View File

@@ -3,6 +3,7 @@ use crate::static_data::{Nature, Statistic};
use std::ptr::drop_in_place;
use std::sync::Arc;
/// Instantiates a new statistic.
#[no_mangle]
extern "C" fn nature_new(
increase_stat: Statistic,
@@ -13,21 +14,26 @@ extern "C" fn nature_new(
Nature::new(increase_stat, decrease_stat, increase_modifier, decrease_modifier).into()
}
/// Reduce the reference count for a nature.
#[no_mangle]
unsafe extern "C" fn nature_drop(ptr: OwnedPtr<Arc<Nature>>) {
drop_in_place(ptr)
}
/// The stat that should receive the increased modifier.
#[no_mangle]
extern "C" fn nature_increased_stat(ptr: ExternPointer<Arc<Nature>>) -> Statistic {
ptr.as_ref().increased_stat()
}
/// The stat that should receive the decreased modifier.
#[no_mangle]
extern "C" fn nature_decreased_stat(ptr: ExternPointer<Arc<Nature>>) -> Statistic {
ptr.as_ref().decreased_stat()
}
/// Calculates the modifier for a given stat. If it's the increased stat, returns the increased
/// modifier, if it's the decreased stat, returns the decreased modifier. Otherwise returns 1.0
#[no_mangle]
extern "C" fn nature_get_stat_modifier(ptr: ExternPointer<Arc<Nature>>, stat: Statistic) -> f32 {
ptr.as_ref().get_stat_modifier(stat)

View File

@@ -6,6 +6,7 @@ use std::ffi::{c_char, CStr};
use std::ptr::drop_in_place;
use std::sync::Arc;
/// Creates a new species.
#[no_mangle]
unsafe extern "C" fn species_new(
id: u16,
@@ -37,6 +38,7 @@ unsafe extern "C" fn species_new(
.into()
}
/// Drop a reference to the species.
#[no_mangle]
unsafe extern "C" fn species_drop(ptr: OwnedPtr<Arc<Species>>) {
drop_in_place(ptr);
@@ -48,9 +50,10 @@ ffi_arc_getter!(Species, gender_rate, f32);
ffi_arc_stringkey_getter!(Species, growth_rate);
ffi_arc_getter!(Species, capture_rate, u8);
/// Adds a new form to the species.
#[no_mangle]
unsafe extern "C" fn species_add_form(
species: ExternPointer<Arc<Species>>,
mut species: ExternPointer<Arc<Species>>,
name: BorrowedPtr<c_char>,
form: OwnedPtr<Arc<Form>>,
) {
@@ -58,6 +61,7 @@ unsafe extern "C" fn species_add_form(
species.as_mut().add_form(CStr::from_ptr(name).into(), form)
}
/// Gets a form by name.
#[no_mangle]
unsafe extern "C" fn species_get_form(
species: ExternPointer<Arc<Species>>,

View File

@@ -2,6 +2,7 @@ use crate::ffi::{ExternPointer, IdentifiablePointer, OwnedPtr};
use crate::static_data::{StaticStatisticSet, Statistic, StatisticSet};
use std::ptr::drop_in_place;
/// Basic foreign function interface for a statistic set.
macro_rules! statistic_set {
($num_type:ident) => {
paste::paste!{
@@ -61,6 +62,7 @@ statistic_set!(i8);
statistic_set!(i16);
statistic_set!(i32);
/// Basic foreign function interface for a static statistic set.
macro_rules! static_statistic_set {
($num_type:ident) => {
paste::paste!{