From 691bf7c12efc15d36084f556e978127f19ab0afb Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Fri, 14 Oct 2022 16:53:30 +0200 Subject: [PATCH] Style and Clippy fixes. --- .../libraries/battle_stat_calculator.rs | 6 + src/dynamic_data/libraries/damage_library.rs | 6 +- src/dynamic_data/models/battle.rs | 2 +- src/dynamic_data/models/learned_move.rs | 1 - src/dynamic_data/models/pokemon.rs | 9 +- src/dynamic_data/models/pokemon_builder.rs | 2 +- src/dynamic_data/models/pokemon_party.rs | 8 +- src/dynamic_data/script_handling/mod.rs | 8 +- src/dynamic_data/script_handling/script.rs | 25 ++-- .../libraries/battle_stat_calculator.rs | 1 + .../dynamic_data/libraries/damage_library.rs | 2 + .../dynamic_data/libraries/dynamic_library.rs | 1 + .../dynamic_data/libraries/misc_library.rs | 1 + src/ffi/dynamic_data/libraries/mod.rs | 5 + .../dynamic_data/libraries/script_resolver.rs | 9 +- src/ffi/dynamic_data/mod.rs | 4 +- src/ffi/dynamic_data/models/mod.rs | 1 + src/ffi/dynamic_data/models/pokemon.rs | 115 ++++++++++-------- src/ffi/mod.rs | 66 +++++----- src/ffi/static_data/ability.rs | 6 + src/ffi/static_data/form.rs | 11 +- src/ffi/static_data/growth_rate.rs | 5 + src/ffi/static_data/item.rs | 10 +- src/ffi/static_data/learnable_moves.rs | 5 +- .../libraries/growth_rate_library.rs | 7 +- .../static_data/libraries/library_settings.rs | 3 + src/ffi/static_data/libraries/mod.rs | 6 + .../static_data/libraries/nature_library.rs | 7 +- src/ffi/static_data/libraries/static_data.rs | 26 ++-- src/ffi/static_data/libraries/type_library.rs | 14 ++- src/ffi/static_data/mod.rs | 22 +++- src/ffi/static_data/move_data.rs | 24 ++-- src/ffi/static_data/nature.rs | 6 + src/ffi/static_data/species.rs | 6 +- src/ffi/static_data/statistic_set.rs | 2 + .../dynamic_data/battle_side.rs | 6 +- .../dynamic_data/choice_queue.rs | 6 +- .../export_registry/dynamic_data/hit_data.rs | 2 +- .../wasm/export_registry/dynamic_data/mod.rs | 10 +- .../export_registry/dynamic_data/pokemon.rs | 15 +-- .../wasm/export_registry/mod.rs | 8 +- .../wasm/export_registry/static_data/mod.rs | 1 + .../wasm/export_registry/static_data/moves.rs | 12 +- src/script_implementations/wasm/script.rs | 3 +- .../wasm/script_function_cache.rs | 2 + .../wasm/script_resolver.rs | 5 +- src/static_data/growth_rates.rs | 3 +- src/static_data/libraries/ability_library.rs | 2 +- src/static_data/libraries/move_library.rs | 2 +- src/static_data/mod.rs | 24 ++-- src/utils/mod.rs | 1 + src/utils/string_key.rs | 13 +- src/utils/value_identifier.rs | 5 +- tests/common/library_loader.rs | 47 +++---- tests/common/test_case.rs | 2 +- tests/main.rs | 2 +- 56 files changed, 354 insertions(+), 249 deletions(-) diff --git a/src/dynamic_data/libraries/battle_stat_calculator.rs b/src/dynamic_data/libraries/battle_stat_calculator.rs index 3ff69ab..0a79338 100755 --- a/src/dynamic_data/libraries/battle_stat_calculator.rs +++ b/src/dynamic_data/libraries/battle_stat_calculator.rs @@ -24,6 +24,12 @@ pub struct Gen7BattleStatCalculator { identifier: ValueIdentifier, } +impl Default for Gen7BattleStatCalculator { + fn default() -> Self { + Self::new() + } +} + impl Gen7BattleStatCalculator { /// Creates a new Gen 7 battle stat calculator pub fn new() -> Self { diff --git a/src/dynamic_data/libraries/damage_library.rs b/src/dynamic_data/libraries/damage_library.rs index 0e7e8fe..8bb2249 100755 --- a/src/dynamic_data/libraries/damage_library.rs +++ b/src/dynamic_data/libraries/damage_library.rs @@ -224,11 +224,7 @@ impl DamageLibrary for Gen7DamageLibrary { float_damage = (float_damage * hit_data.effectiveness()).floor(); let mut damage = if float_damage <= 0.0 { - if hit_data.effectiveness() == 0.0 { - 0 - } else { - 1 - } + u32::from(hit_data.effectiveness() != 0.0) } else if float_damage >= u32::MAX as f32 { u32::MAX } else { diff --git a/src/dynamic_data/models/battle.rs b/src/dynamic_data/models/battle.rs index 09c83a0..a1db3c8 100755 --- a/src/dynamic_data/models/battle.rs +++ b/src/dynamic_data/models/battle.rs @@ -345,7 +345,7 @@ impl Battle { .library() .load_script(self.into(), ScriptCategory::Weather, &weather) .unwrap() - .expect(format!("Couldn't find weather script by name {}", weather).as_str()); + .unwrap_or_else(|| panic!("Couldn't find weather script by name {}", weather)); self.weather.set(script); } else { self.weather.clear(); diff --git a/src/dynamic_data/models/learned_move.rs b/src/dynamic_data/models/learned_move.rs index d216799..6187aba 100755 --- a/src/dynamic_data/models/learned_move.rs +++ b/src/dynamic_data/models/learned_move.rs @@ -1,7 +1,6 @@ use std::sync::atomic::{AtomicU8, Ordering}; use std::sync::Arc; -use crate::dynamic_data::Pokemon; use crate::static_data::MoveData; use crate::{ValueIdentifiable, ValueIdentifier}; diff --git a/src/dynamic_data/models/pokemon.rs b/src/dynamic_data/models/pokemon.rs index e43c336..e3b65f4 100755 --- a/src/dynamic_data/models/pokemon.rs +++ b/src/dynamic_data/models/pokemon.rs @@ -457,7 +457,8 @@ impl Pokemon { .calculate_flat_stats(self, &self.flat_stats); self.recalculate_boosted_stats(); } - /// Calculates the boosted stats on the Pokemon. This should be called when a stat boost changes. + /// Calculates the boosted stats on the Pokemon, _without_ recalculating the flat stats. + /// This should be called when a stat boost changes. pub fn recalculate_boosted_stats(&self) { self.library .stat_calculator() @@ -516,7 +517,7 @@ impl Pokemon { let ability_script = self .library - .load_script((&*self).into(), ScriptCategory::Ability, self.active_ability().name()) + .load_script(self.into(), ScriptCategory::Ability, self.active_ability().name()) .unwrap(); if let Some(ability_script) = ability_script { self.ability_script @@ -614,7 +615,7 @@ impl Pokemon { } } - /// Damages the Pokemon by a certain amount of damage, from a specific damage source. + /// Damages the Pokemon by a certain amount of damage, from a damage source. pub fn damage(&self, mut damage: u32, source: DamageSource) { if damage > self.current_health() { damage = self.current_health(); @@ -820,7 +821,7 @@ pub mod test { fn construct_pokemon() { let lib = Arc::new(crate::dynamic_data::libraries::dynamic_library::test::build()); let species = lib.static_data().species().get(&"foo".into()).unwrap().clone(); - let form = species.get_form(&"default".into()).unwrap().clone(); + let form = species.get_form(&"default".into()).unwrap(); let pokemon = Pokemon::new( lib, diff --git a/src/dynamic_data/models/pokemon_builder.rs b/src/dynamic_data/models/pokemon_builder.rs index 056e123..7b45872 100755 --- a/src/dynamic_data/models/pokemon_builder.rs +++ b/src/dynamic_data/models/pokemon_builder.rs @@ -47,7 +47,7 @@ impl PokemonBuilder { }; let species = self.library.static_data().species().get(&self.species).unwrap().clone(); - let form = species.get_default_form().clone(); + let form = species.get_default_form(); let p = Pokemon::new( self.library, species, diff --git a/src/dynamic_data/models/pokemon_party.rs b/src/dynamic_data/models/pokemon_party.rs index 2d33460..0c65475 100755 --- a/src/dynamic_data/models/pokemon_party.rs +++ b/src/dynamic_data/models/pokemon_party.rs @@ -93,11 +93,9 @@ impl PokemonParty { /// Checks if the party contains a given pokemon. pub fn has_pokemon(&self, pokemon: &Pokemon) -> bool { - for p in &self.pokemon { - if let Some(p) = p { - if std::ptr::eq(p.as_ref(), pokemon) { - return true; - } + for p in self.pokemon.iter().flatten() { + if std::ptr::eq(p.as_ref(), pokemon) { + return true; } } false diff --git a/src/dynamic_data/script_handling/mod.rs b/src/dynamic_data/script_handling/mod.rs index 54fab5f..426ca40 100755 --- a/src/dynamic_data/script_handling/mod.rs +++ b/src/dynamic_data/script_handling/mod.rs @@ -239,7 +239,7 @@ mod tests { impl TestScript { fn new() -> Self { Self { - name: StringKey::new("test".into()), + name: "test".into(), is_marked_for_deletion: Default::default(), suppressed_count: AtomicUsize::new(0), test_count: AtomicUsize::new(0), @@ -247,7 +247,7 @@ mod tests { } fn new_with_name(name: &str) -> Self { Self { - name: StringKey::new(name.into()), + name: name.into(), is_marked_for_deletion: Default::default(), suppressed_count: AtomicUsize::new(0), test_count: AtomicUsize::new(0), @@ -424,7 +424,7 @@ mod tests { "test_b" ); - set.remove(&StringKey::new("test_c".into())); + set.remove(&"test_c".into()); assert!(aggregator.get_next().is_none()); } @@ -451,7 +451,7 @@ mod tests { "test_a" ); - set.remove(&StringKey::new("test_b".into())); + set.remove(&"test_b".into()); assert_eq!( aggregator diff --git a/src/dynamic_data/script_handling/script.rs b/src/dynamic_data/script_handling/script.rs index 1d8e8ae..d981e1e 100755 --- a/src/dynamic_data/script_handling/script.rs +++ b/src/dynamic_data/script_handling/script.rs @@ -398,7 +398,7 @@ mod tests { impl TestScript { fn new() -> Self { Self { - name: StringKey::new("test".into()), + name: "test".into(), container: AtomicPtr::::default(), suppressed_count: AtomicUsize::new(0), marked_for_deletion: Default::default(), @@ -537,10 +537,7 @@ mod tests { h.join().unwrap(); } - assert_eq!( - container.script.read().as_ref().unwrap().name(), - &StringKey::new("script2".into()) - ); + assert_eq!(container.script.read().as_ref().unwrap().name(), &"script2".into()); } } @@ -556,20 +553,20 @@ pub enum ScriptOwnerData { None, } -impl Into for &Pokemon { - fn into(self) -> ScriptOwnerData { - ScriptOwnerData::Pokemon(AtomicPtr::new(self as *const Pokemon as *mut Pokemon)) +impl From<&Pokemon> for ScriptOwnerData { + fn from(p: &Pokemon) -> Self { + ScriptOwnerData::Pokemon(AtomicPtr::new(p as *const Pokemon as *mut Pokemon)) } } -impl Into for &BattleSide { - fn into(self) -> ScriptOwnerData { - ScriptOwnerData::BattleSide(AtomicPtr::new(self as *const BattleSide as *mut BattleSide)) +impl From<&BattleSide> for ScriptOwnerData { + fn from(p: &BattleSide) -> Self { + ScriptOwnerData::BattleSide(AtomicPtr::new(p as *const BattleSide as *mut BattleSide)) } } -impl Into for &Battle { - fn into(self) -> ScriptOwnerData { - ScriptOwnerData::Battle(AtomicPtr::new(self as *const Battle as *mut Battle)) +impl From<&Battle> for ScriptOwnerData { + fn from(p: &Battle) -> Self { + ScriptOwnerData::Battle(AtomicPtr::new(p as *const Battle as *mut Battle)) } } diff --git a/src/ffi/dynamic_data/libraries/battle_stat_calculator.rs b/src/ffi/dynamic_data/libraries/battle_stat_calculator.rs index aec9e8d..6f2401e 100644 --- a/src/ffi/dynamic_data/libraries/battle_stat_calculator.rs +++ b/src/ffi/dynamic_data/libraries/battle_stat_calculator.rs @@ -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> { let v: Box = Box::new(Gen7BattleStatCalculator::new()); diff --git a/src/ffi/dynamic_data/libraries/damage_library.rs b/src/ffi/dynamic_data/libraries/damage_library.rs index d4dd9da..35e462e 100644 --- a/src/ffi/dynamic_data/libraries/damage_library.rs +++ b/src/ffi/dynamic_data/libraries/damage_library.rs @@ -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> { let v: Box = Box::new(Gen7DamageLibrary::new(randomness == 1)); diff --git a/src/ffi/dynamic_data/libraries/dynamic_library.rs b/src/ffi/dynamic_data/libraries/dynamic_library.rs index fd86e9e..48a2733 100644 --- a/src/ffi/dynamic_data/libraries/dynamic_library.rs +++ b/src/ffi/dynamic_data/libraries/dynamic_library.rs @@ -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, diff --git a/src/ffi/dynamic_data/libraries/misc_library.rs b/src/ffi/dynamic_data/libraries/misc_library.rs index a9b1f26..25a875d 100644 --- a/src/ffi/dynamic_data/libraries/misc_library.rs +++ b/src/ffi/dynamic_data/libraries/misc_library.rs @@ -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> { let v: Box = Box::new(Gen7MiscLibrary::new()); diff --git a/src/ffi/dynamic_data/libraries/mod.rs b/src/ffi/dynamic_data/libraries/mod.rs index 698ee5d..18d8b92 100644 --- a/src/ffi/dynamic_data/libraries/mod.rs +++ b/src/ffi/dynamic_data/libraries/mod.rs @@ -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; diff --git a/src/ffi/dynamic_data/libraries/script_resolver.rs b/src/ffi/dynamic_data/libraries/script_resolver.rs index 5da1e01..75966ae 100644 --- a/src/ffi/dynamic_data/libraries/script_resolver.rs +++ b/src/ffi/dynamic_data/libraries/script_resolver.rs @@ -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> { let v: Box = Box::new(EmptyScriptResolver { @@ -11,12 +12,14 @@ extern "C" fn empty_script_resolver_new() -> IdentifiablePointer IdentifiablePointer> { let v: Box = 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>, + mut ptr: ExternPointer>, 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>) { + extern "C" fn webassembly_script_resolver_finalize(mut ptr: ExternPointer>) { ptr.as_mut().finalize(); } } diff --git a/src/ffi/dynamic_data/mod.rs b/src/ffi/dynamic_data/mod.rs index b8f1f0a..df1e5ff 100644 --- a/src/ffi/dynamic_data/mod.rs +++ b/src/ffi/dynamic_data/mod.rs @@ -1,2 +1,4 @@ +/// The foreign function interfaces for the dynamic data libraries mod libraries; -mod models; \ No newline at end of file +/// The foreign function interfaces for the dynamic data models +mod models; diff --git a/src/ffi/dynamic_data/models/mod.rs b/src/ffi/dynamic_data/models/mod.rs index f801f25..c984a1c 100644 --- a/src/ffi/dynamic_data/models/mod.rs +++ b/src/ffi/dynamic_data/models/mod.rs @@ -1 +1,2 @@ +/// The foreign function interface for a Pokemon. mod pokemon; diff --git a/src/ffi/dynamic_data/models/pokemon.rs b/src/ffi/dynamic_data/models/pokemon.rs index 18dcfe1..e6fb2c9 100644 --- a/src/ffi/dynamic_data/models/pokemon.rs +++ b/src/ffi/dynamic_data/models/pokemon.rs @@ -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>, @@ -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>) { drop_in_place(ptr); } +/// The library data of the Pokemon. #[no_mangle] extern "C" fn pokemon_library(ptr: ExternPointer>) -> IdentifiablePointer> { ptr.as_ref().library().clone().into() } +/// The species of the Pokemon. #[no_mangle] extern "C" fn pokemon_species(ptr: ExternPointer>) -> IdentifiablePointer> { - 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>) -> IdentifiablePointer> { - 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>) -> IdentifiablePointer> { - 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>) -> IdentifiablePointer> { - 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>) -> IdentifiablePointer> { if let Some(v) = ptr.as_ref().held_item().read().as_ref() { @@ -84,44 +92,40 @@ extern "C" fn pokemon_held_item(ptr: ExternPointer>) -> Identifiabl } } +/// Checks whether the Pokemon is holding a specific item. #[no_mangle] extern "C" fn pokemon_has_held_item(ptr: ExternPointer>, 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>, item: ExternPointer>, ) -> IdentifiablePointer> { 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>) -> IdentifiablePointer> { 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>) -> 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>) -> *mut c_char { let name = ptr.as_ref().nickname(); @@ -139,15 +144,13 @@ extern "C" fn pokemon_nickname(ptr: ExternPointer>) -> *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>) -> 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>) -> u8 { ptr.as_ref().real_ability().index @@ -155,6 +158,8 @@ extern "C" fn pokemon_real_ability_index(ptr: ExternPointer>) -> 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>, @@ -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>) -> IdentifiablePointer> { (ptr.as_ref().flat_stats() as *const StatisticSet).into() } +/// The stats of the Pokemon including the stat boosts. #[no_mangle] extern "C" fn pokemon_boosted_stats(ptr: ExternPointer>) -> IdentifiablePointer> { (ptr.as_ref().boosted_stats() as *const StatisticSet).into() } +/// Get the stat boosts for a specific stat. #[no_mangle] extern "C" fn pokemon_get_stat_boost(ptr: ExternPointer>, 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>, @@ -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>, 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>, 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>, 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>, 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>) -> IdentifiablePointer { if let Some(v) = ptr.as_ref().get_battle() { @@ -227,54 +238,59 @@ extern "C" fn pokemon_get_battle(ptr: ExternPointer>) -> 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>) -> 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>) -> 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>) -> 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>) -> IdentifiablePointer { (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>) -> 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>) -> IdentifiablePointer> { 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>) { 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>) { ptr.as_ref().recalculate_boosted_stats() } +/// Change the species of the Pokemon. #[no_mangle] extern "C" fn pokemon_change_species( ptr: ExternPointer>, @@ -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>, form: ExternPointer>) { 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>) -> 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>) -> 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>) -> 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>, 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>, 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>, @@ -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>) { ptr.as_ref().clear_status() diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 6a029d7..d455397 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -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 = *mut T; +/// Helper type for clearer functions. type BorrowedPtr = *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 { + /// The wrapped pointer. ptr: *mut T, } impl ExternPointer { + /// 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::() - )) + self.ptr + .as_ref() + .unwrap_or_else(|| panic!("Given pointer of type '{}' was null", std::any::type_name::())) } } - - 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::() - )) + self.ptr + .as_mut() + .unwrap_or_else(|| panic!("Given pointer of type '{}' was null", std::any::type_name::())) } } } +/// Helper utility class to give both the pointer and identifier to a FFI. #[repr(C)] pub(self) struct IdentifiablePointer { + /// The wrapped pointer. pub ptr: *const T, - pub id: ValueIdentifier, + /// The identifier of the pointer. + pub id: usize, } impl IdentifiablePointer { + /// Creates a new IdentifiablePointer. pub(self) fn new(ptr: *const T, id: ValueIdentifier) -> Self { - Self { ptr, id } + unsafe { Self { ptr, id: transmute(id) } } } } -impl Into> for *mut T { - fn into(self) -> ExternPointer { - ExternPointer { ptr: self } +impl From<*mut T> for ExternPointer { + fn from(ptr: *mut T) -> Self { + ExternPointer { ptr } } } impl From> for IdentifiablePointer> { fn from(v: Arc) -> 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 From> for IdentifiablePointer> { impl From> for IdentifiablePointer { fn from(v: Box) -> 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 From> for IdentifiablePointer { impl From<*const T> for IdentifiablePointer { 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 IdentifiablePointer { + /// Returns an identifiable pointer with null as pointer, and 0 as identifier. pub fn none() -> Self { Self { ptr: std::ptr::null(), diff --git a/src/ffi/static_data/ability.rs b/src/ffi/static_data/ability.rs index 0f657e5..d38b796 100644 --- a/src/ffi/static_data/ability.rs +++ b/src/ffi/static_data/ability.rs @@ -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>) { 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>, diff --git a/src/ffi/static_data/form.rs b/src/ffi/static_data/form.rs index ccb20f3..8b37d37 100644 --- a/src/ffi/static_data/form.rs +++ b/src/ffi/static_data/form.rs @@ -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>) { drop_in_place(ptr) } +/// The name of the form. #[no_mangle] unsafe extern "C" fn form_name(ptr: ExternPointer>) -> OwnedPtr { 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>) -> IdentifiablePointer> { (ptr.as_ref().base_stats() as *const StaticStatisticSet).into() @@ -87,12 +91,9 @@ ffi_vec_stringkey_getters!(Form, hidden_abilities); ffi_arc_getter!(Form, moves, BorrowedPtr); +/// Check if the form has a specific flag set. #[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 - } + u8::from(ptr.as_ref().has_flag(&flag)) } diff --git a/src/ffi/static_data/growth_rate.rs b/src/ffi/static_data/growth_rate.rs index e789165..18bd282 100644 --- a/src/ffi/static_data/growth_rate.rs +++ b/src/ffi/static_data/growth_rate.rs @@ -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> { 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>) { 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>, 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>, level: LevelInt) -> u32 { ptr.as_ref().calculate_experience(level) diff --git a/src/ffi/static_data/item.rs b/src/ffi/static_data/item.rs index bfac537..e0dd060 100644 --- a/src/ffi/static_data/item.rs +++ b/src/ffi/static_data/item.rs @@ -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>) { drop_in_place(ptr) } +/// The name of the item. #[no_mangle] unsafe extern "C" fn item_name(ptr: ExternPointer>) -> OwnedPtr { 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>, 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)) } diff --git a/src/ffi/static_data/learnable_moves.rs b/src/ffi/static_data/learnable_moves.rs index 7cbd2b5..7ff25a1 100644 --- a/src/ffi/static_data/learnable_moves.rs +++ b/src/ffi/static_data/learnable_moves.rs @@ -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 { Box::into_raw(Box::new(LearnableMoves::new())) } +/// drops a learnablemoves struct. #[no_mangle] unsafe extern "C" fn learnable_moves_drop(ptr: OwnedPtr) { 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, + mut ptr: ExternPointer, level: LevelInt, move_name: BorrowedPtr, ) { diff --git a/src/ffi/static_data/libraries/growth_rate_library.rs b/src/ffi/static_data/libraries/growth_rate_library.rs index 299af6c..77a6bba 100644 --- a/src/ffi/static_data/libraries/growth_rate_library.rs +++ b/src/ffi/static_data/libraries/growth_rate_library.rs @@ -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 { Box::new(GrowthRateLibrary::new(capacity)).into() } +/// Drops the growthrate library. #[no_mangle] unsafe extern "C" fn growth_rate_library_drop(ptr: OwnedPtr) { 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, @@ -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, @@ -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, + mut ptr: ExternPointer, name: BorrowedPtr, growth_rate: OwnedPtr>, ) { diff --git a/src/ffi/static_data/libraries/library_settings.rs b/src/ffi/static_data/libraries/library_settings.rs index a83c139..64dd4e8 100644 --- a/src/ffi/static_data/libraries/library_settings.rs +++ b/src/ffi/static_data/libraries/library_settings.rs @@ -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 { Box::new(LibrarySettings::new(max_level)).into() } +/// Drop a library settings object. #[no_mangle] unsafe extern "C" fn library_settings_drop(ptr: OwnedPtr) { drop_in_place(ptr) } +/// The highest level a Pokemon can be. #[no_mangle] extern "C" fn library_settings_maximum_level(ptr: ExternPointer) -> LevelInt { ptr.as_ref().maximum_level() diff --git a/src/ffi/static_data/libraries/mod.rs b/src/ffi/static_data/libraries/mod.rs index 6bd0440..47bb230 100644 --- a/src/ffi/static_data/libraries/mod.rs +++ b/src/ffi/static_data/libraries/mod.rs @@ -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! { diff --git a/src/ffi/static_data/libraries/nature_library.rs b/src/ffi/static_data/libraries/nature_library.rs index 1b64ec7..e999f53 100644 --- a/src/ffi/static_data/libraries/nature_library.rs +++ b/src/ffi/static_data/libraries/nature_library.rs @@ -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 { Box::new(NatureLibrary::new(capacity)).into() } +/// Drop a nature library. #[no_mangle] unsafe extern "C" fn nature_library_drop(ptr: OwnedPtr) { 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, + mut ptr: ExternPointer, name: BorrowedPtr, nature: OwnedPtr>, ) { @@ -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, @@ -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, diff --git a/src/ffi/static_data/libraries/static_data.rs b/src/ffi/static_data/libraries/static_data.rs index e71a1d9..c99f337 100644 --- a/src/ffi/static_data/libraries/static_data.rs +++ b/src/ffi/static_data/libraries/static_data.rs @@ -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) -> IdentifiablePointer { Box::new(StaticData::new(*Box::from_raw(settings))).into() } +/// Drop a static data. #[no_mangle] unsafe extern "C" fn static_data_drop(ptr: OwnedPtr) { drop_in_place(ptr) } +/// Several misc settings for the library. #[no_mangle] -unsafe extern "C" fn static_data_settings(data: ExternPointer) -> IdentifiablePointer { +unsafe extern "C" fn static_data_settings(mut data: ExternPointer) -> IdentifiablePointer { (data.as_mut().settings() as *const LibrarySettings).into() } +/// All data for Pokemon species. #[no_mangle] -unsafe extern "C" fn static_data_species(data: ExternPointer) -> IdentifiablePointer { +unsafe extern "C" fn static_data_species(mut data: ExternPointer) -> IdentifiablePointer { (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) -> IdentifiablePointer { +unsafe extern "C" fn static_data_moves(mut data: ExternPointer) -> IdentifiablePointer { (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) -> IdentifiablePointer { +unsafe extern "C" fn static_data_items(mut data: ExternPointer) -> IdentifiablePointer { (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, + mut data: ExternPointer, ) -> IdentifiablePointer { (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) -> IdentifiablePointer { +unsafe extern "C" fn static_data_types(mut data: ExternPointer) -> IdentifiablePointer { (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) -> IdentifiablePointer { +unsafe extern "C" fn static_data_natures(mut data: ExternPointer) -> IdentifiablePointer { (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) -> IdentifiablePointer { +unsafe extern "C" fn static_data_abilities(mut data: ExternPointer) -> IdentifiablePointer { (data.as_mut().abilities_mut() as *const AbilityLibrary).into() } diff --git a/src/ffi/static_data/libraries/type_library.rs b/src/ffi/static_data/libraries/type_library.rs index d23302d..9b08b6c 100644 --- a/src/ffi/static_data/libraries/type_library.rs +++ b/src/ffi/static_data/libraries/type_library.rs @@ -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 { Box::new(TypeLibrary::new(capacity)).into() } +/// Drops a type library. #[no_mangle] unsafe extern "C" fn type_library_drop(ptr: OwnedPtr) { 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, @@ -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, @@ -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, @@ -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, @@ -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, + mut ptr: ExternPointer, name: BorrowedPtr, ) -> 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, + mut ptr: ExternPointer, attacking: TypeIdentifier, defending: TypeIdentifier, effectiveness: f32, diff --git a/src/ffi/static_data/mod.rs b/src/ffi/static_data/mod.rs index ebd5e67..09a1620 100644 --- a/src/ffi/static_data/mod.rs +++ b/src/ffi/static_data/mod.rs @@ -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 { 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 { 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 { 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 { 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) { drop_in_place(ptr) } +/// Get the type of an effect parameter. #[no_mangle] extern "C" fn effect_parameter_get_type(ptr: ExternPointer) -> u8 { match ptr.as_ref() { @@ -51,15 +67,17 @@ extern "C" fn effect_parameter_get_type(ptr: ExternPointer) -> } } +/// 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) -> 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) -> i64 { let p = ptr.as_ref(); @@ -69,6 +87,7 @@ extern "C" fn effect_parameter_get_as_int(ptr: ExternPointer) - 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) -> f32 { let p = ptr.as_ref(); @@ -78,6 +97,7 @@ extern "C" fn effect_parameter_get_as_float(ptr: ExternPointer) 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) -> OwnedPtr { let p = ptr.as_ref(); diff --git a/src/ffi/static_data/move_data.rs b/src/ffi/static_data/move_data.rs index e28233a..fd7a92e 100644 --- a/src/ffi/static_data/move_data.rs +++ b/src/ffi/static_data/move_data.rs @@ -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>) { drop_in_place(ptr) } +/// The name of the move. #[no_mangle] unsafe extern "C" fn move_data_name(ptr: ExternPointer>) -> OwnedPtr { 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>, @@ -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>, 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) { 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) -> f32 { + ptr.as_ref().chance() +} +/// The name of the effect. #[no_mangle] unsafe extern "C" fn secondary_effect_effect_name(ptr: ExternPointer) -> OwnedPtr { 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) -> usize { ptr.as_ref().parameters().len() } +/// Get a parameter of the effect. #[no_mangle] unsafe extern "C" fn secondary_effect_parameter_get( ptr: ExternPointer, diff --git a/src/ffi/static_data/nature.rs b/src/ffi/static_data/nature.rs index 50bb171..22c7625 100644 --- a/src/ffi/static_data/nature.rs +++ b/src/ffi/static_data/nature.rs @@ -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>) { drop_in_place(ptr) } +/// The stat that should receive the increased modifier. #[no_mangle] extern "C" fn nature_increased_stat(ptr: ExternPointer>) -> Statistic { ptr.as_ref().increased_stat() } +/// The stat that should receive the decreased modifier. #[no_mangle] extern "C" fn nature_decreased_stat(ptr: ExternPointer>) -> 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>, stat: Statistic) -> f32 { ptr.as_ref().get_stat_modifier(stat) diff --git a/src/ffi/static_data/species.rs b/src/ffi/static_data/species.rs index 7b79478..af8d605 100644 --- a/src/ffi/static_data/species.rs +++ b/src/ffi/static_data/species.rs @@ -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>) { 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>, + mut species: ExternPointer>, name: BorrowedPtr, form: OwnedPtr>, ) { @@ -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>, diff --git a/src/ffi/static_data/statistic_set.rs b/src/ffi/static_data/statistic_set.rs index 92f4e02..7b36e2f 100644 --- a/src/ffi/static_data/statistic_set.rs +++ b/src/ffi/static_data/statistic_set.rs @@ -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!{ diff --git a/src/script_implementations/wasm/export_registry/dynamic_data/battle_side.rs b/src/script_implementations/wasm/export_registry/dynamic_data/battle_side.rs index cb2b98a..1081a51 100755 --- a/src/script_implementations/wasm/export_registry/dynamic_data/battle_side.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/battle_side.rs @@ -12,14 +12,14 @@ register! { env: FunctionEnvMut, side: ExternRef, ) -> u8 { - if side.value_func(&env).unwrap().has_fled_battle() { 1 } else { 0 } + u8::from(side.value_func(&env).unwrap().has_fled_battle()) } fn battleside_is_defeated( env: FunctionEnvMut, side: ExternRef, ) -> u8 { - if side.value_func(&env).unwrap().is_defeated() { 1 } else { 0 } + u8::from(side.value_func(&env).unwrap().is_defeated()) } fn battleside_get_side_index( @@ -102,7 +102,7 @@ register! { ) -> u8 { unsafe { let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr)); - if side.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into()) { 1 } else { 0 } + u8::from(side.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into())) } } diff --git a/src/script_implementations/wasm/export_registry/dynamic_data/choice_queue.rs b/src/script_implementations/wasm/export_registry/dynamic_data/choice_queue.rs index ecbac83..4df32ef 100755 --- a/src/script_implementations/wasm/export_registry/dynamic_data/choice_queue.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/choice_queue.rs @@ -10,10 +10,6 @@ register! { battle_random: ExternRef, pokemon: ExternRef ) -> u8 { - if battle_random.value_func(&env).unwrap().move_pokemon_choice_next(pokemon.value_func(&env).unwrap()) { - 1 - } else { - 0 - } + u8::from(battle_random.value_func(&env).unwrap().move_pokemon_choice_next(pokemon.value_func(&env).unwrap())) } } diff --git a/src/script_implementations/wasm/export_registry/dynamic_data/hit_data.rs b/src/script_implementations/wasm/export_registry/dynamic_data/hit_data.rs index b2e0026..c09417c 100755 --- a/src/script_implementations/wasm/export_registry/dynamic_data/hit_data.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/hit_data.rs @@ -16,7 +16,7 @@ register! { env: FunctionEnvMut, hit: ExternRef, ) -> u8 { - if hit.value_func(&env).unwrap().is_critical() { 1 } else { 0 } + u8::from(hit.value_func(&env).unwrap().is_critical()) } fn hit_data_fail( diff --git a/src/script_implementations/wasm/export_registry/dynamic_data/mod.rs b/src/script_implementations/wasm/export_registry/dynamic_data/mod.rs index b297070..233846c 100755 --- a/src/script_implementations/wasm/export_registry/dynamic_data/mod.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/mod.rs @@ -7,20 +7,26 @@ use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut}; use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv; use crate::static_data::StaticData; +/// The battle registration +mod battle; +/// Battle random registration mod battle_random; /// Battle side registration mod battle_side; +/// Choice queue registration. mod choice_queue; +/// The executing move registration/ mod executing_move; +/// The hit data registration/ +mod hit_data; /// Learned move registration mod learned_move; +/// The party registration. mod party; /// Pokemon registration mod pokemon; /// Turn choice registration mod turn_choice; -mod hit_data; -mod battle; register! { fn dynamic_library_get_static_data( diff --git a/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs b/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs index 38015d3..cb08e61 100755 --- a/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs @@ -7,7 +7,7 @@ use crate::script_implementations::wasm::script::WebAssemblyScript; use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv; use crate::static_data::{ClampedStatisticSet, Species}; use crate::static_data::{Item, StatisticSet}; -use crate::{ScriptCategory, StringKey}; +use crate::ScriptCategory; use std::ffi::{c_char, CStr}; use wasmer::FunctionEnvMut; @@ -134,11 +134,7 @@ register! { self_inflicted: u8 ) -> u8 { unsafe{ - if pokemon.value_func(&env).unwrap().change_stat_boost(transmute(stat), amount, self_inflicted == 1) { - 1 - } else { - 0 - } + u8::from(pokemon.value_func(&env).unwrap().change_stat_boost(transmute(stat), amount, self_inflicted == 1)) } } @@ -194,8 +190,7 @@ register! { ) -> u8 { let name : *mut c_char = env.data().data().get_raw_pointer(name); let name = unsafe { CStr::from_ptr(name) }; - let key = StringKey::new(name.to_str().unwrap().into()); - if pokemon.value_func(&env).unwrap().has_held_item(&key) { 1 } else { 0 } + u8::from(pokemon.value_func(&env).unwrap().has_held_item(&name.into())) } fn pokemon_heal( @@ -204,7 +199,7 @@ register! { amount: u32, allow_revive: u8 ) -> u8 { - if pokemon.value_func(&env).unwrap().heal(amount, allow_revive == 1) { 1 } else { 0 } + u8::from(pokemon.value_func(&env).unwrap().heal(amount, allow_revive == 1)) } fn pokemon_clear_status( @@ -261,7 +256,7 @@ register! { ) -> u8 { unsafe { let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr)); - if pokemon.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into()) { 1 } else { 0 } + u8::from(pokemon.value_func(&env).unwrap().has_volatile_script(&c_name.as_ref().into())) } } diff --git a/src/script_implementations/wasm/export_registry/mod.rs b/src/script_implementations/wasm/export_registry/mod.rs index 0e4c1e2..e814f86 100755 --- a/src/script_implementations/wasm/export_registry/mod.rs +++ b/src/script_implementations/wasm/export_registry/mod.rs @@ -149,13 +149,7 @@ fn effect_parameter_get_type(env: FunctionEnvMut, parameter: Ext fn effect_parameter_as_bool(env: FunctionEnvMut, parameter: ExternRef) -> u8 { let v = parameter.value_func(&env).unwrap(); match v { - EffectParameter::Bool(_, b) => { - if *b { - 1 - } else { - 0 - } - } + EffectParameter::Bool(_, b) => u8::from(*b), _ => panic!("Unexpected parameter type!"), } } diff --git a/src/script_implementations/wasm/export_registry/static_data/mod.rs b/src/script_implementations/wasm/export_registry/static_data/mod.rs index 7a2fe94..d8ca752 100755 --- a/src/script_implementations/wasm/export_registry/static_data/mod.rs +++ b/src/script_implementations/wasm/export_registry/static_data/mod.rs @@ -9,6 +9,7 @@ use crate::static_data::{ ItemLibrary, LibrarySettings, MoveLibrary, SpeciesLibrary, StaticData, StatisticSet, TypeLibrary, }; +/// Item registration. mod item; /// Moves data registration mod moves; diff --git a/src/script_implementations/wasm/export_registry/static_data/moves.rs b/src/script_implementations/wasm/export_registry/static_data/moves.rs index 3d2ebda..9b96bed 100755 --- a/src/script_implementations/wasm/export_registry/static_data/moves.rs +++ b/src/script_implementations/wasm/export_registry/static_data/moves.rs @@ -56,17 +56,9 @@ fn move_data_get_priority(env: FunctionEnvMut, move_data: Extern move_data.value_func(&env).unwrap().priority() } fn move_data_has_flag(env: FunctionEnvMut, move_data: ExternRef, flag: ExternRef) -> u8 { - if move_data.value_func(&env).unwrap().has_flag(flag.value_func(&env).unwrap()) { - 1 - } else { - 0 - } + u8::from(move_data.value_func(&env).unwrap().has_flag(flag.value_func(&env).unwrap())) } fn move_data_has_flag_by_hash(env: FunctionEnvMut, move_data: ExternRef, flag_hash: u32) -> u8 { - if move_data.value_func(&env).unwrap().has_flag_by_hash(flag_hash) { - 1 - } else { - 0 - } + u8::from(move_data.value_func(&env).unwrap().has_flag_by_hash(flag_hash)) } } diff --git a/src/script_implementations/wasm/script.rs b/src/script_implementations/wasm/script.rs index 9765bf9..f2e7274 100755 --- a/src/script_implementations/wasm/script.rs +++ b/src/script_implementations/wasm/script.rs @@ -54,6 +54,7 @@ impl WebAssemblyScript { } } + /// Get a pointer inside the WASM memory. pub(crate) fn get_wasm_pointer(&self) -> u32 { self.self_ptr } @@ -569,7 +570,7 @@ impl Script for WebAssemblyScript { let env = &self.environment; if let Some(func) = env.script_function_cache().prevent_stat_boost_change(env) { let ptr = env.allocate_temp(*prevent); - let self_inflicted = if self_inflicted { 1_u8 } else { 0_u8 }; + let self_inflicted = u8::from(self_inflicted); call_func!( func, env, diff --git a/src/script_implementations/wasm/script_function_cache.rs b/src/script_implementations/wasm/script_function_cache.rs index 892c827..00ae6d0 100755 --- a/src/script_implementations/wasm/script_function_cache.rs +++ b/src/script_implementations/wasm/script_function_cache.rs @@ -173,6 +173,7 @@ script_function_cache! { } impl ScriptFunctionCache { + /// Get the name of a script. pub(crate) fn script_get_name(&self, env: &Arc) -> Option> { { let read_lock = self.script_get_name.read(); @@ -191,6 +192,7 @@ impl ScriptFunctionCache { self.script_get_name.read().as_ref().cloned() } + /// Drop the memory of a CString inside the WASM memory. pub(crate) fn dealloc_cstring(&self, env: &Arc) -> Option> { { let read_lock = self.dealloc_cstring.read(); diff --git a/src/script_implementations/wasm/script_resolver.rs b/src/script_implementations/wasm/script_resolver.rs index 8f5d2c0..46beaef 100755 --- a/src/script_implementations/wasm/script_resolver.rs +++ b/src/script_implementations/wasm/script_resolver.rs @@ -93,18 +93,15 @@ impl WebAssemblyScriptResolver { self.modules.push(module); } - /// Initialise all the data we need. + /// Tells the script resolver we're done loading wasm modules, and to finalize the resolver. pub fn finalize(&mut self) { let mut imports = Imports::new(); - //let mut exports = Exports::new(); let env = FunctionEnv::new( &mut self.store_mut(), WebAssemblyEnv::new(Arc::downgrade(&self.environment_data)), ); register_webassembly_funcs(&mut imports, &mut self.store_mut(), &env); - //imports.register("env", exports); - for module in &self.modules { for import in module.imports() { if imports.get_export("env", import.name()).is_none() { diff --git a/src/static_data/growth_rates.rs b/src/static_data/growth_rates.rs index 6b78586..f6321ec 100755 --- a/src/static_data/growth_rates.rs +++ b/src/static_data/growth_rates.rs @@ -15,7 +15,8 @@ pub struct LookupGrowthRate { } impl LookupGrowthRate { - /// Instantiates a new lookup growth rate. + /// Instantiates a new lookup growth rate. The experience vec should be the amount of experience + /// required per level, with the first element being the experience required for level 1 (generally 0). pub fn new(experience: Vec) -> LookupGrowthRate { LookupGrowthRate { experience } } diff --git a/src/static_data/libraries/ability_library.rs b/src/static_data/libraries/ability_library.rs index bca6768..0dd6a87 100755 --- a/src/static_data/libraries/ability_library.rs +++ b/src/static_data/libraries/ability_library.rs @@ -51,7 +51,7 @@ pub mod tests { pub fn build() -> AbilityLibrary { let mut lib = AbilityLibrary::new(1); lib.add( - &StringKey::new("test_ability".into()), + &StringKey::new("test_ability"), Arc::new(Ability::new(&"test_ability".into(), &"test_ability".into(), Vec::new())), ); // Drops borrow as mut diff --git a/src/static_data/libraries/move_library.rs b/src/static_data/libraries/move_library.rs index 15b3aba..e35b929 100755 --- a/src/static_data/libraries/move_library.rs +++ b/src/static_data/libraries/move_library.rs @@ -71,7 +71,7 @@ pub mod tests { let m = build_move(); // Borrow as mut so we can insert let w = &mut lib; - w.add(&StringKey::new("foo".into()), Arc::new(m)); + w.add(&StringKey::new("foo"), Arc::new(m)); // Drops borrow as mut lib diff --git a/src/static_data/mod.rs b/src/static_data/mod.rs index 0c23e8b..eac374e 100755 --- a/src/static_data/mod.rs +++ b/src/static_data/mod.rs @@ -49,27 +49,27 @@ pub enum EffectParameter { String(ValueIdentifier, StringKey), } -impl Into for bool { - fn into(self) -> EffectParameter { - EffectParameter::Bool(Default::default(), self) +impl From for EffectParameter { + fn from(b: bool) -> Self { + EffectParameter::Bool(Default::default(), b) } } -impl Into for i64 { - fn into(self) -> EffectParameter { - EffectParameter::Int(Default::default(), self) +impl From for EffectParameter { + fn from(i: i64) -> Self { + EffectParameter::Int(Default::default(), i) } } -impl Into for f32 { - fn into(self) -> EffectParameter { - EffectParameter::Float(Default::default(), self) +impl From for EffectParameter { + fn from(f: f32) -> Self { + EffectParameter::Float(Default::default(), f) } } -impl Into for StringKey { - fn into(self) -> EffectParameter { - EffectParameter::String(Default::default(), self) +impl From for EffectParameter { + fn from(s: StringKey) -> Self { + EffectParameter::String(Default::default(), s) } } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index ec89cf6..513efac 100755 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -10,4 +10,5 @@ mod random; /// The string_key module defines a custom string handling for reduced allocations and fast lookups /// and equality checks. mod string_key; +/// Helper tool to keep track of moving memory for FFI. mod value_identifier; diff --git a/src/utils/string_key.rs b/src/utils/string_key.rs index d475cfa..11cce62 100755 --- a/src/utils/string_key.rs +++ b/src/utils/string_key.rs @@ -116,11 +116,12 @@ impl Display for StringKey { } } -impl Into for &CStr { - fn into(self) -> StringKey { - StringKey::new(self.to_str().unwrap()) +impl From<&CStr> for StringKey { + fn from(s: &CStr) -> Self { + StringKey::new(s.to_str().unwrap()) } } + /// Converts a character to lowercased in a const safe way. const fn to_lower(c: u8) -> u8 { if c >= b'A' && c <= b'Z' { @@ -170,7 +171,7 @@ mod tests { #[test] fn create_empty_stringkey() { - let sk = StringKey::new("".into()); + let sk = StringKey::new(""); assert_eq!(sk.str(), ""); assert_eq!(sk.hash(), 0); assert_eq!(sk.hash(), StringKey::get_hash("")); @@ -178,7 +179,7 @@ mod tests { #[test] fn create_stringkey_foo() { - let sk = StringKey::new("foo".into()); + let sk = StringKey::new("foo"); assert_eq!(sk.str(), "foo"); assert_eq!(sk.hash(), 2356372769); assert_eq!(sk.hash(), StringKey::get_hash("foo")); @@ -187,7 +188,7 @@ mod tests { #[test] fn create_stringkey_bar() { - let sk = StringKey::new("bar".into()); + let sk = StringKey::new("bar"); assert_eq!(sk.str(), "bar"); assert_eq!(sk.hash(), 1996459178); assert_eq!(sk.hash(), StringKey::get_hash("bar")); diff --git a/src/utils/value_identifier.rs b/src/utils/value_identifier.rs index f4efd75..60cd3e6 100644 --- a/src/utils/value_identifier.rs +++ b/src/utils/value_identifier.rs @@ -1,5 +1,6 @@ use std::sync::atomic::{AtomicUsize, Ordering}; +/// The current index for the value counter. static CURRENT: AtomicUsize = AtomicUsize::new(1); /// An extremely basic way to identify a piece of data. @@ -9,9 +10,7 @@ pub struct ValueIdentifier(usize); impl Default for ValueIdentifier { fn default() -> Self { - Self { - 0: CURRENT.fetch_add(1, Ordering::SeqCst), - } + Self(CURRENT.fetch_add(1, Ordering::SeqCst)) } } diff --git a/tests/common/library_loader.rs b/tests/common/library_loader.rs index 7f6cc9f..cacabbb 100755 --- a/tests/common/library_loader.rs +++ b/tests/common/library_loader.rs @@ -53,15 +53,13 @@ pub fn load_types(path: &String, type_library: &mut TypeLibrary) { .unwrap(); let headers = reader.headers().unwrap(); for header in headers.iter().skip(1) { - type_library.register_type(&StringKey::new(header.into())); + type_library.register_type(&header.into()); } for record in reader.records() { let record = record.unwrap(); let offensive_type = record.get(0).unwrap(); - let offensive_type_id = type_library - .get_type_id(&StringKey::new(offensive_type.into())) - .unwrap(); + let offensive_type_id = type_library.get_type_id(&offensive_type.into()).unwrap(); for (i, v) in record.iter().skip(1).enumerate() { let effectiveness = v.parse::().unwrap(); @@ -78,7 +76,7 @@ pub fn load_natures(path: &String, nature_library: &mut NatureLibrary) { for record in reader.records() { let record = record.unwrap(); - let nature_name = StringKey::new(record.get(0).unwrap().into()); + let nature_name = record.get(0).unwrap().into(); let increased_statistic_str = record.get(1).unwrap(); let decreased_statistic_str = record.get(2).unwrap(); if increased_statistic_str.is_empty() || decreased_statistic_str.is_empty() { @@ -102,7 +100,7 @@ pub fn load_items(path: &String, lib: &mut ItemLibrary) { let json_array = json.as_array().unwrap(); for v in json_array { - let name = StringKey::new(v.get("name").unwrap().as_str().unwrap().into()); + let name = v.get("name").unwrap().as_str().unwrap().into(); let category = serde_json::from_value(v.get("itemType").unwrap().clone()).unwrap(); let mut battle_category = BattleItemCategory::None; if let Some(c) = v.get("battleType") { @@ -113,7 +111,7 @@ pub fn load_items(path: &String, lib: &mut ItemLibrary) { if let Some(f) = v.get("flags") { let a = f.as_array().unwrap(); for flag in a { - flags.insert(StringKey::new(flag.as_str().unwrap().into())); + flags.insert(flag.as_str().unwrap().into()); } } @@ -154,7 +152,7 @@ pub fn load_abilities(path: &String, ability_library: &mut AbilityLibrary) { let name = StringKey::new(key); let mut effect = StringKey::empty(); if let Some(e) = value.get("effect") { - effect = StringKey::new(e.as_str().unwrap().into()); + effect = e.as_str().unwrap().into(); } let mut parameters = Vec::new(); if let Some(p) = value.get("parameters") { @@ -175,8 +173,8 @@ pub fn load_moves(path: &String, lib: &mut StaticData) { let data = json.as_object().unwrap().get("data").unwrap().as_array().unwrap(); for move_data in data { let move_data = move_data.as_object().unwrap(); - let move_name = StringKey::new(move_data.get("name").unwrap().as_str().unwrap().into()); - let move_type = StringKey::new(move_data.get("type").unwrap().as_str().unwrap().into()); + let move_name = move_data.get("name").unwrap().as_str().unwrap().into(); + let move_type = move_data.get("type").unwrap().as_str().unwrap().into(); let move_type_id = lib.types().get_type_id(&move_type).unwrap(); let move_category = serde_json::from_value(move_data.get("category").unwrap().clone()).unwrap(); let base_power = move_data.get("power").unwrap().as_i64().unwrap() as u8; @@ -199,7 +197,7 @@ pub fn load_moves(path: &String, lib: &mut StaticData) { Some(SecondaryEffect::new( chance, - StringKey::new(v.get("name").unwrap().as_str().unwrap().into()), + v.get("name").unwrap().as_str().unwrap().into(), parameters, )) } else { @@ -210,7 +208,7 @@ pub fn load_moves(path: &String, lib: &mut StaticData) { if let Some(f) = move_data.get("flags") { let f = f.as_array().unwrap(); for flag in f { - flags.insert(StringKey::new(flag.as_str().unwrap().into())); + flags.insert(flag.as_str().unwrap().into()); } } @@ -246,7 +244,7 @@ pub fn load_species(path: &String, library: &mut StaticData) { let name = StringKey::new(key); let id = value.get("id").unwrap().as_i64().unwrap(); let gender_rate = value.get("genderRatio").unwrap().as_f64().unwrap(); - let growth_rate_name = StringKey::new(value.get("growthRate").unwrap().as_str().unwrap().into()); + let growth_rate_name = value.get("growthRate").unwrap().as_str().unwrap().into(); let _base_happiness = value.get("baseHappiness").unwrap().as_i64().unwrap(); let catch_rate = value.get("catchRate").unwrap().as_i64().unwrap(); let _color = value.get("color").unwrap().as_str().unwrap(); @@ -289,13 +287,13 @@ fn load_wasm(path: &String, library: &mut WebAssemblyScriptResolver) { fn parse_form(name: StringKey, value: &Value, library: &mut StaticData) -> Arc
{ let mut abilities = Vec::new(); for a in value.get("abilities").unwrap().as_array().unwrap() { - abilities.push(StringKey::new(a.as_str().unwrap().into())); + abilities.push(a.as_str().unwrap().into()); } let mut hidden_abilities = Vec::new(); for a in value.get("hiddenAbilities").unwrap().as_array().unwrap() { - hidden_abilities.push(StringKey::new(a.as_str().unwrap().into())); + hidden_abilities.push(a.as_str().unwrap().into()); } - let base_stats = parse_statistics(&value.get("baseStats").unwrap()); + let base_stats = parse_statistics(value.get("baseStats").unwrap()); // TODO: ev reward let height = value.get("height").unwrap().as_f64().unwrap(); let weight = value.get("weight").unwrap().as_f64().unwrap(); @@ -306,15 +304,10 @@ fn parse_form(name: StringKey, value: &Value, library: &mut StaticData) -> Arc LearnableMoves { let level_moves = value.get("levelMoves").unwrap().as_array().unwrap(); for level_move in level_moves { - let name = StringKey::new(level_move.get("name").unwrap().as_str().unwrap().into()); + let name = level_move.get("name").unwrap().as_str().unwrap().into(); let level = level_move.get("level").unwrap().as_u64().unwrap() as LevelInt; assert!(move_library.get(&name).is_some()); moves.add_level_move(level, &name); @@ -401,7 +394,7 @@ fn parse_effect_parameter(value: &Value) -> EffectParameter { n.as_i64().unwrap().into() } } - Value::String(s) => StringKey::new(s.as_str().into()).into(), + Value::String(s) => StringKey::new(s.as_str()).into(), Value::Array(_) => { panic!("Unexpected type") } @@ -421,8 +414,8 @@ fn test_type_library_loaded() { assert_eq!( lib.get_effectiveness( - lib.get_type_id(&StringKey::new("fire".into())).unwrap(), - &[lib.get_type_id(&StringKey::new("grass".into())).unwrap()], + lib.get_type_id(&"fire".into()).unwrap(), + &[lib.get_type_id(&"grass".into()).unwrap()], ), 2.0 ); diff --git a/tests/common/test_case.rs b/tests/common/test_case.rs index 1e61351..030afa1 100755 --- a/tests/common/test_case.rs +++ b/tests/common/test_case.rs @@ -74,7 +74,7 @@ impl TestCase { impl TestPokemon { fn to_pokemon(&self, library: Arc) -> Pokemon { - let mut builder = PokemonBuilder::new(library, StringKey::new(self.species.as_str().into()), self.level); + let mut builder = PokemonBuilder::new(library, self.species.as_str().into(), self.level); for move_name in &self.moves { builder = builder.learn_move(StringKey::new(move_name)); } diff --git a/tests/main.rs b/tests/main.rs index 13b6504..12e0939 100755 --- a/tests/main.rs +++ b/tests/main.rs @@ -83,7 +83,7 @@ fn validate_assurance() { let executing_move = ExecutingMove::new( vec![], 1, - p1.clone(), + p1, mv.clone(), mv.move_data().clone(), ScriptContainer::default(),