diff --git a/src/dynamic_data/flow/choice_queue.rs b/src/dynamic_data/flow/choice_queue.rs index 7908d1f..8d1f7df 100755 --- a/src/dynamic_data/flow/choice_queue.rs +++ b/src/dynamic_data/flow/choice_queue.rs @@ -132,8 +132,8 @@ impl ValueIdentifiable for ChoiceQueue { mod tests { use super::*; use crate::defines::LevelInt; - use crate::dynamic_data::PassChoice; - use crate::static_data::{AbilityIndex, DataLibrary, Gender}; + use crate::dynamic_data::{DynamicLibrary, PassChoice}; + use crate::static_data::{AbilityIndex, Gender}; use std::sync::Arc; #[test] diff --git a/src/dynamic_data/flow/turn_runner.rs b/src/dynamic_data/flow/turn_runner.rs index b976efa..e2fe9c4 100755 --- a/src/dynamic_data/flow/turn_runner.rs +++ b/src/dynamic_data/flow/turn_runner.rs @@ -9,7 +9,7 @@ use crate::dynamic_data::Battle; use crate::dynamic_data::DamageSource; use crate::dynamic_data::ExecutingMove; use crate::dynamic_data::Pokemon; -use crate::static_data::{DataLibrary, MoveCategory}; +use crate::static_data::MoveCategory; use crate::{run_scripts, script_hook, PkmnResult}; impl Battle { diff --git a/src/dynamic_data/libraries/battle_stat_calculator.rs b/src/dynamic_data/libraries/battle_stat_calculator.rs index 0a79338..7fde222 100755 --- a/src/dynamic_data/libraries/battle_stat_calculator.rs +++ b/src/dynamic_data/libraries/battle_stat_calculator.rs @@ -137,3 +137,23 @@ impl ValueIdentifiable for Gen7BattleStatCalculator { self.identifier } } +#[cfg(test)] +pub mod tests { + use super::*; + + mockall::mock! { + #[derive(Debug)] + pub BattleStatCalculator{} + impl BattleStatCalculator for BattleStatCalculator { + fn calculate_flat_stats(&self, pokemon: &Pokemon, stats: &StatisticSet); + fn calculate_flat_stat(&self, pokemon: &Pokemon, stat: Statistic) -> u32; + fn calculate_boosted_stats(&self, pokemon: &Pokemon, stats: &StatisticSet); + fn calculate_boosted_stat(&self, pokemon: &Pokemon, stat: Statistic) -> u32; + } + impl ValueIdentifiable for BattleStatCalculator { + fn value_identifier(&self) -> ValueIdentifier{ + ValueIdentifier::new(0) + } + } + } +} diff --git a/src/dynamic_data/libraries/dynamic_library.rs b/src/dynamic_data/libraries/dynamic_library.rs index fa710bb..0b7182c 100755 --- a/src/dynamic_data/libraries/dynamic_library.rs +++ b/src/dynamic_data/libraries/dynamic_library.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::ops::Deref; use std::sync::Arc; @@ -11,14 +12,42 @@ use crate::static_data::Item; use crate::static_data::StaticData; use crate::{PkmnResult, StringKey, ValueIdentifiable, ValueIdentifier}; +/// The dynamic library stores a static data library, as well as holding different libraries and +/// calculators that might be customized between different generations and implementations. +pub trait DynamicLibrary: Debug + ValueIdentifiable { + /// The static data is the immutable storage data for this library. + fn static_data(&self) -> &Box; + /// The stat calculator deals with the calculation of flat and boosted stats, based on the + /// Pokemons attributes. + fn stat_calculator(&self) -> &dyn BattleStatCalculator; + /// The damage calculator deals with the calculation of things relating to damage. + fn damage_calculator(&self) -> &dyn DamageLibrary; + /// The Misc Library holds minor functions that do not fall in any of the other libraries and + /// calculators. + fn misc_library(&self) -> &dyn MiscLibrary; + + /// Loads a standard script with a given unique combination of category and key. If no script + /// can be created with this combination, returns None. + fn load_script( + &self, + owner: ScriptOwnerData, + _category: ScriptCategory, + _key: &StringKey, + ) -> PkmnResult>>; + /// Loads an item script with the given unique key. If no script can be created with this + /// combinations, returns None. Note that ItemScripts are immutable, as their script should be + /// shared between all different usages. + fn load_item_script(&self, _key: &Arc) -> PkmnResult>>; +} + /// The dynamic library stores a static data library, as well as holding different libraries and /// calculators that might be customized between different generations and implementations. #[derive(Debug)] -pub struct DynamicLibrary { +pub struct DynamicLibraryImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The static data is the immutable storage data for this library. - static_data: StaticData, + static_data: Box, /// The stat calculator deals with the calculation of flat and boosted stats, based on the /// Pokemons attributes. stat_calculator: Box, @@ -32,13 +61,10 @@ pub struct DynamicLibrary { script_resolver: Box, } -unsafe impl Sync for DynamicLibrary {} -unsafe impl Send for DynamicLibrary {} - -impl DynamicLibrary { +impl DynamicLibraryImpl { /// Instantiates a new DynamicLibrary with given parameters. pub fn new( - static_data: StaticData, + static_data: Box, stat_calculator: Box, damage_calculator: Box, misc_library: Box, @@ -53,29 +79,31 @@ impl DynamicLibrary { script_resolver, } } +} +impl DynamicLibrary for DynamicLibraryImpl { /// The static data is the immutable storage data for this library. - pub fn static_data(&self) -> &StaticData { + fn static_data(&self) -> &Box { &self.static_data } /// The stat calculator deals with the calculation of flat and boosted stats, based on the /// Pokemons attributes. - pub fn stat_calculator(&self) -> &dyn BattleStatCalculator { + fn stat_calculator(&self) -> &dyn BattleStatCalculator { self.stat_calculator.deref() } /// The damage calculator deals with the calculation of things relating to damage. - pub fn damage_calculator(&self) -> &dyn DamageLibrary { + fn damage_calculator(&self) -> &dyn DamageLibrary { self.damage_calculator.deref() } /// The Misc Library holds minor functions that do not fall in any of the other libraries and /// calculators. - pub fn misc_library(&self) -> &dyn MiscLibrary { + fn misc_library(&self) -> &dyn MiscLibrary { self.misc_library.deref() } /// Loads a standard script with a given unique combination of category and key. If no script /// can be created with this combination, returns None. - pub fn load_script( + fn load_script( &self, owner: ScriptOwnerData, _category: ScriptCategory, @@ -86,12 +114,12 @@ impl DynamicLibrary { /// Loads an item script with the given unique key. If no script can be created with this /// combinations, returns None. Note that ItemScripts are immutable, as their script should be /// shared between all different usages. - pub fn load_item_script(&self, _key: &Arc) -> PkmnResult>> { + fn load_item_script(&self, _key: &Arc) -> PkmnResult>> { todo!() } } -impl ValueIdentifiable for DynamicLibrary { +impl ValueIdentifiable for DynamicLibraryImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } @@ -99,16 +127,39 @@ impl ValueIdentifiable for DynamicLibrary { #[cfg(test)] pub mod test { + use super::*; use crate::dynamic_data::libraries::battle_stat_calculator::Gen7BattleStatCalculator; use crate::dynamic_data::libraries::damage_library::Gen7DamageLibrary; - use crate::dynamic_data::libraries::dynamic_library::DynamicLibrary; use crate::dynamic_data::libraries::misc_library::Gen7MiscLibrary; use crate::dynamic_data::EmptyScriptResolver; - pub fn build() -> DynamicLibrary { - DynamicLibrary { + mockall::mock! { + #[derive(Debug)] + pub DynamicLibrary{} + impl DynamicLibrary for DynamicLibrary { + fn static_data(&self) -> &Box; + fn stat_calculator(&self) -> &dyn BattleStatCalculator; + fn damage_calculator(&self) -> &dyn DamageLibrary; + fn misc_library(&self) -> &dyn MiscLibrary; + fn load_script( + &self, + owner: ScriptOwnerData, + _category: ScriptCategory, + _key: &StringKey, + ) -> PkmnResult>>; + fn load_item_script(&self, _key: &Arc) -> PkmnResult>>; + } + impl ValueIdentifiable for DynamicLibrary{ + fn value_identifier(&self) -> ValueIdentifier{ + ValueIdentifier::new(0) + } + } + } + + pub fn build() -> DynamicLibraryImpl { + DynamicLibraryImpl { identifier: Default::default(), - static_data: crate::static_data::libraries::static_data::test::build(), + static_data: Box::new(crate::static_data::libraries::static_data::test::build()), stat_calculator: Box::new(Gen7BattleStatCalculator::new()), damage_calculator: Box::new(Gen7DamageLibrary::new(false)), misc_library: Box::new(Gen7MiscLibrary::new()), diff --git a/src/dynamic_data/libraries/misc_library.rs b/src/dynamic_data/libraries/misc_library.rs index 60c4a59..adf9d76 100755 --- a/src/dynamic_data/libraries/misc_library.rs +++ b/src/dynamic_data/libraries/misc_library.rs @@ -47,7 +47,7 @@ impl Gen7MiscLibrary { ))), HashSet::new(), )); - let struggle_learned_move = Arc::new(LearnedMove::new(&struggle_data, MoveLearnMethod::Unknown)); + let struggle_learned_move = Arc::new(LearnedMove::new(struggle_data, MoveLearnMethod::Unknown)); Self { identifier: Default::default(), struggle_learned_move, diff --git a/src/dynamic_data/models/battle.rs b/src/dynamic_data/models/battle.rs index d60247a..749c871 100755 --- a/src/dynamic_data/models/battle.rs +++ b/src/dynamic_data/models/battle.rs @@ -26,7 +26,7 @@ pub struct Battle { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The library the battle uses for handling. - library: Arc, + library: Arc, /// A list of all different parties in the battle. parties: Vec, /// Whether or not Pokemon can flee from the battle. @@ -62,7 +62,7 @@ pub struct Battle { impl Battle { /// Initializes a new battle. pub fn new( - library: Arc, + library: Arc, parties: Vec, can_flee: bool, number_of_sides: u8, @@ -110,7 +110,7 @@ impl Battle { } /// The library the battle uses for handling. - pub fn library(&self) -> &Arc { + pub fn library(&self) -> &Arc { &self.library } /// A list of all different parties in the battle. diff --git a/src/dynamic_data/models/learned_move.rs b/src/dynamic_data/models/learned_move.rs index 4b9239f..e8e0d78 100755 --- a/src/dynamic_data/models/learned_move.rs +++ b/src/dynamic_data/models/learned_move.rs @@ -33,12 +33,13 @@ pub enum MoveLearnMethod { impl LearnedMove { /// Instantiate a new learned move. - pub fn new(move_data: &Arc, learn_method: MoveLearnMethod) -> Self { + pub fn new(move_data: Arc, learn_method: MoveLearnMethod) -> Self { + let max_pp = move_data.base_usages(); Self { identifier: Default::default(), - move_data: move_data.clone(), - max_pp: move_data.base_usages(), - remaining_pp: AtomicU8::new(move_data.base_usages()), + move_data, + max_pp, + remaining_pp: AtomicU8::new(max_pp), learn_method, } } @@ -107,7 +108,7 @@ mod tests { let mut mock = MockMoveData::new(); mock.expect_base_usages().return_const(30); let data: Arc = Arc::new(mock); - let learned_move = LearnedMove::new(&data, MoveLearnMethod::Level); + let learned_move = LearnedMove::new(data, MoveLearnMethod::Level); assert!(learned_move.try_use(15)); learned_move.restore_uses(5); assert_eq!(20, learned_move.remaining_pp()); diff --git a/src/dynamic_data/models/pokemon.rs b/src/dynamic_data/models/pokemon.rs index e634356..1c53ad1 100755 --- a/src/dynamic_data/models/pokemon.rs +++ b/src/dynamic_data/models/pokemon.rs @@ -12,6 +12,7 @@ use crate::dynamic_data::models::battle::Battle; use crate::dynamic_data::models::learned_move::{LearnedMove, MoveLearnMethod}; use crate::dynamic_data::script_handling::{ScriptSource, ScriptSourceData, ScriptWrapper}; use crate::dynamic_data::{DynamicLibrary, Script, ScriptCategory, ScriptContainer, ScriptSet, VolatileScriptsOwner}; +use crate::static_data::AbilityIndex; use crate::static_data::Form; use crate::static_data::Gender; use crate::static_data::Item; @@ -19,7 +20,6 @@ use crate::static_data::Nature; use crate::static_data::Species; use crate::static_data::TypeIdentifier; use crate::static_data::{Ability, Statistic}; -use crate::static_data::{AbilityIndex, DataLibrary}; use crate::static_data::{ClampedStatisticSet, StatisticSet}; use crate::utils::Random; use crate::{script_hook, PkmnResult, StringKey, ValueIdentifiable, ValueIdentifier}; @@ -30,7 +30,7 @@ pub struct Pokemon { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The library data of the Pokemon. - library: Arc, + library: Arc, /// The species of the Pokemon. species: RwLock>, /// The form of the Pokemon. @@ -120,7 +120,7 @@ pub struct Pokemon { impl Pokemon { /// Instantiates a new Pokemon. pub fn new( - library: Arc, + library: Arc, species: Arc, form: &Arc, ability: AbilityIndex, @@ -188,7 +188,7 @@ impl Pokemon { } /// The library data of the Pokemon. - pub fn library(&self) -> &Arc { + pub fn library(&self) -> &Arc { &self.library } /// The species of the Pokemon. @@ -416,9 +416,9 @@ impl Pokemon { self.override_ability.is_some() } /// Returns the currently active ability. - pub fn active_ability(&self) -> &Arc { + pub fn active_ability(&self) -> Arc { if let Some(v) = &self.override_ability { - return v; + return v.clone(); } self.library .static_data() @@ -523,7 +523,7 @@ impl Pokemon { .set(ability_script) .as_ref() // Ensure the ability script gets initialized with the parameters for the ability. - .on_initialize(self.library.as_ref(), self.active_ability().parameters().to_vec()) + .on_initialize(&self.library, self.active_ability().parameters().to_vec()) } else { self.ability_script.clear(); } @@ -829,14 +829,69 @@ pub enum DamageSource { #[cfg(test)] pub mod test { + use crate::dynamic_data::libraries::test::MockDynamicLibrary; use crate::dynamic_data::models::pokemon::Pokemon; - use crate::static_data::Gender; - use crate::static_data::{AbilityIndex, DataLibrary}; + use crate::dynamic_data::tests::MockBattleStatCalculator; + use crate::dynamic_data::DynamicLibrary; + use crate::static_data::growth_rate_library::tests::MockGrowthRateLibrary; + use crate::static_data::nature_library::tests::MockNatureLibrary; + use crate::static_data::species_library::tests::MockSpeciesLibrary; + use crate::static_data::test::MockStaticData; + use crate::static_data::tests::{MockForm, MockNature, MockSpecies}; + use crate::static_data::{AbilityIndex, Species}; + use crate::static_data::{Form, Gender}; + use crate::StringKey; use std::sync::Arc; + pub fn mock_library() -> Arc { + let mut species_lib = MockSpeciesLibrary::new(); + species_lib.expect_get().return_once(|_| { + let mut species = MockSpecies::new(); + species.expect_get_form().return_once(|_| { + let mut form = MockForm::new(); + form.expect_name().return_const(StringKey::new("default")); + form.expect_weight().return_const(100.0); + form.expect_height().return_const(20.0); + form.expect_types().return_const(vec![0u8.into()]); + let a: Arc = Arc::new(form); + Some(a) + }); + species.expect_growth_rate().return_const(StringKey::empty()); + species.expect_name().return_const(StringKey::new("test_species")); + + let s: Arc = Arc::new(species); + Some(s) + }); + + let mut static_lib = MockStaticData::new(); + static_lib.expect_species().return_const(Box::new(species_lib)); + + let mut growth_rate_lib = MockGrowthRateLibrary::new(); + growth_rate_lib.expect_calculate_experience().return_const(1000u32); + + let mut nature_lib = MockNatureLibrary::new(); + nature_lib.expect_get_nature().returning(|_| { + let n = MockNature::new(); + Some(Arc::new(n)) + }); + + static_lib.expect_growth_rates().return_const(Box::new(growth_rate_lib)); + static_lib.expect_natures().return_const(Box::new(nature_lib)); + + let mut stat_calculator = MockBattleStatCalculator::new(); + stat_calculator.expect_calculate_flat_stats().returning(|_, _| {}); + stat_calculator.expect_calculate_boosted_stats().returning(|_, _| {}); + + let mut lib = MockDynamicLibrary::new(); + lib.expect_static_data().return_const(Box::new(static_lib)); + lib.expect_stat_calculator().return_const(Box::new(stat_calculator)); + + Arc::new(lib) + } + #[test] fn construct_pokemon() { - let lib = Arc::new(crate::dynamic_data::libraries::dynamic_library::test::build()); + let lib = mock_library(); let species = lib.static_data().species().get(&"foo".into()).unwrap().clone(); let form = species.get_form(&"default".into()).unwrap(); @@ -854,7 +909,7 @@ pub mod test { 0, &"test_nature".into(), ); - assert_eq!(pokemon.species().name(), &"foo".into()); + assert_eq!(pokemon.species().name(), &"test_species".into()); assert_eq!(pokemon.form().name(), &"default".into()); } } diff --git a/src/dynamic_data/models/pokemon_builder.rs b/src/dynamic_data/models/pokemon_builder.rs index 7b45872..7462aa1 100755 --- a/src/dynamic_data/models/pokemon_builder.rs +++ b/src/dynamic_data/models/pokemon_builder.rs @@ -4,13 +4,13 @@ use crate::defines::LevelInt; use crate::dynamic_data::models::learned_move::MoveLearnMethod; use crate::dynamic_data::models::pokemon::Pokemon; use crate::dynamic_data::DynamicLibrary; -use crate::static_data::{AbilityIndex, DataLibrary, Gender}; +use crate::static_data::{AbilityIndex, Gender}; use crate::{Random, StringKey}; /// This allows for the easy chain building of a Pokemon. pub struct PokemonBuilder { /// The library of the Pokemon. - library: Arc, + library: Arc, /// The name of the species of the Pokemon. species: StringKey, /// The level of the Pokemon. @@ -23,7 +23,7 @@ pub struct PokemonBuilder { impl PokemonBuilder { /// Creates a new PokemonBuilder with a library, species, and level. - pub fn new(library: Arc, species: StringKey, level: LevelInt) -> Self { + pub fn new(library: Arc, species: StringKey, level: LevelInt) -> Self { Self { library, species, diff --git a/src/dynamic_data/script_handling/script.rs b/src/dynamic_data/script_handling/script.rs index 9fd2647..401584d 100755 --- a/src/dynamic_data/script_handling/script.rs +++ b/src/dynamic_data/script_handling/script.rs @@ -64,7 +64,7 @@ pub trait Script: Send + Sync { /// This function is ran when this script stops being in effect, and is removed from its owner. fn on_remove(&self) {} /// This function is ran when this script starts being in effect. - fn on_initialize(&self, _library: &DynamicLibrary, _pars: Vec) {} + fn on_initialize(&self, _library: &Arc, _pars: Vec) {} /// This function is ran just before the start of the turn. Everyone has made its choices here, /// and the turn is about to start. This is a great place to initialize data if you need to know /// something has happened during a turn. diff --git a/src/ffi/dynamic_data/libraries/dynamic_library.rs b/src/ffi/dynamic_data/libraries/dynamic_library.rs index 48a2733..aeab133 100644 --- a/src/ffi/dynamic_data/libraries/dynamic_library.rs +++ b/src/ffi/dynamic_data/libraries/dynamic_library.rs @@ -1,4 +1,6 @@ -use crate::dynamic_data::{BattleStatCalculator, DamageLibrary, DynamicLibrary, MiscLibrary, ScriptResolver}; +use crate::dynamic_data::{ + BattleStatCalculator, DamageLibrary, DynamicLibrary, DynamicLibraryImpl, MiscLibrary, ScriptResolver, +}; use crate::ffi::{IdentifiablePointer, OwnedPtr}; use crate::static_data::StaticData; use std::sync::Arc; @@ -6,20 +8,20 @@ use std::sync::Arc; /// Instantiates a new DynamicLibrary with given parameters. #[no_mangle] extern "C" fn dynamic_library_new( - static_data: OwnedPtr, + static_data: OwnedPtr>, stat_calculator: OwnedPtr>, damage_library: OwnedPtr>, misc_library: OwnedPtr>, script_resolver: OwnedPtr>, -) -> IdentifiablePointer> { +) -> IdentifiablePointer> { unsafe { - Arc::new(DynamicLibrary::new( + let a: Arc = Arc::new(DynamicLibraryImpl::new( *Box::from_raw(static_data), *Box::from_raw(stat_calculator), *Box::from_raw(damage_library), *Box::from_raw(misc_library), *Box::from_raw(script_resolver), - )) - .into() + )); + a.into() } } diff --git a/src/ffi/dynamic_data/models/battle.rs b/src/ffi/dynamic_data/models/battle.rs index 3e7a952..69423fd 100644 --- a/src/ffi/dynamic_data/models/battle.rs +++ b/src/ffi/dynamic_data/models/battle.rs @@ -9,7 +9,7 @@ use std::sync::Arc; /// Initializes a new battle. #[no_mangle] extern "C" fn battle_new( - library: ExternPointer>, + library: ExternPointer>, parties: *const OwnedPtr, parties_length: usize, can_flee: u8, @@ -46,7 +46,7 @@ extern "C" fn battle_new( /// The library the battle uses for handling. #[no_mangle] -extern "C" fn battle_library(ptr: ExternPointer>) -> IdentifiablePointer> { +extern "C" fn battle_library(ptr: ExternPointer>) -> IdentifiablePointer> { ptr.as_ref().library().clone().into() } diff --git a/src/ffi/dynamic_data/models/learned_move.rs b/src/ffi/dynamic_data/models/learned_move.rs index 6b3048c..803a2fa 100644 --- a/src/ffi/dynamic_data/models/learned_move.rs +++ b/src/ffi/dynamic_data/models/learned_move.rs @@ -10,7 +10,7 @@ extern "C" fn learned_move_new( move_data: ExternPointer>, learn_method: MoveLearnMethod, ) -> IdentifiablePointer> { - Arc::new(LearnedMove::new(move_data.as_ref(), learn_method)).into() + Arc::new(LearnedMove::new(move_data.as_ref().clone(), learn_method)).into() } /// Drops a learned move. diff --git a/src/ffi/dynamic_data/models/pokemon.rs b/src/ffi/dynamic_data/models/pokemon.rs index ce100c6..0cfe86c 100644 --- a/src/ffi/dynamic_data/models/pokemon.rs +++ b/src/ffi/dynamic_data/models/pokemon.rs @@ -11,7 +11,7 @@ use std::sync::Arc; /// Instantiates a new Pokemon. #[no_mangle] extern "C" fn pokemon_new( - library: ExternPointer>, + library: ExternPointer>, species: ExternPointer>, form: ExternPointer>, hidden_ability: bool, @@ -48,7 +48,7 @@ unsafe extern "C" fn pokemon_drop(ptr: OwnedPtr>) { /// The library data of the Pokemon. #[no_mangle] -extern "C" fn pokemon_library(ptr: ExternPointer>) -> IdentifiablePointer> { +extern "C" fn pokemon_library(ptr: ExternPointer>) -> IdentifiablePointer> { ptr.as_ref().library().clone().into() } diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 0acb584..ded4755 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -163,6 +163,16 @@ impl From> for IdentifiablePointer> } } +impl From<&Box> for IdentifiablePointer> { + fn from(v: &Box) -> Self { + let id = unsafe { transmute(v.value_identifier()) }; + Self { + ptr: v as *const Box, + id, + } + } +} + impl From>> for IdentifiablePointer> { fn from(v: Option>) -> Self { if let Some(v) = v { diff --git a/src/ffi/static_data/libraries/growth_rate_library.rs b/src/ffi/static_data/libraries/growth_rate_library.rs index 77a6bba..ffd9774 100644 --- a/src/ffi/static_data/libraries/growth_rate_library.rs +++ b/src/ffi/static_data/libraries/growth_rate_library.rs @@ -1,25 +1,26 @@ use crate::defines::LevelInt; use crate::ffi::{BorrowedPtr, ExternPointer, IdentifiablePointer, OwnedPtr}; -use crate::static_data::{GrowthRate, GrowthRateLibrary}; +use crate::static_data::{GrowthRate, GrowthRateLibrary, GrowthRateLibraryImpl}; 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() +extern "C" fn growth_rate_library_new(capacity: usize) -> IdentifiablePointer> { + let b: Box = Box::new(GrowthRateLibraryImpl::new(capacity)); + b.into() } /// Drops the growthrate library. #[no_mangle] -unsafe extern "C" fn growth_rate_library_drop(ptr: OwnedPtr) { +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, + ptr: ExternPointer>, growth_rate: BorrowedPtr, experience: u32, ) -> LevelInt { @@ -30,7 +31,7 @@ unsafe extern "C" fn growth_rate_library_calculate_level( /// 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, + ptr: ExternPointer>, growth_rate: BorrowedPtr, level: LevelInt, ) -> u32 { @@ -41,7 +42,7 @@ unsafe extern "C" fn growth_rate_library_calculate_experience( /// Adds a new growth rate with a name and value. #[no_mangle] unsafe extern "C" fn growth_rate_library_add_growth_rate( - mut 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 64dd4e8..a5b7b8d 100644 --- a/src/ffi/static_data/libraries/library_settings.rs +++ b/src/ffi/static_data/libraries/library_settings.rs @@ -1,22 +1,23 @@ use crate::defines::LevelInt; use crate::ffi::{ExternPointer, IdentifiablePointer, OwnedPtr}; -use crate::static_data::LibrarySettings; +use crate::static_data::{LibrarySettings, LibrarySettingsImpl}; 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() +extern "C" fn library_settings_new(max_level: LevelInt) -> IdentifiablePointer> { + let b: Box = Box::new(LibrarySettingsImpl::new(max_level)); + b.into() } /// Drop a library settings object. #[no_mangle] -unsafe extern "C" fn library_settings_drop(ptr: OwnedPtr) { +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 { +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 1b54cac..6c04091 100644 --- a/src/ffi/static_data/libraries/mod.rs +++ b/src/ffi/static_data/libraries/mod.rs @@ -17,32 +17,33 @@ use std::sync::Arc; /// Generates foreign function interfaces for a DataLibrary trait implementation. macro_rules! library_interface { - ($library_type:ty, $return_type:ty) => { + ($library_type_name:ident, $library_type:ty, $return_type:ty) => { paste::paste! { #[no_mangle] - extern "C" fn [< $library_type:snake _new >](capacity: usize) -> IdentifiablePointer<$library_type> { - Box::new($library_type::new(capacity)).into() + extern "C" fn [< $library_type_name:snake _new >](capacity: usize) -> IdentifiablePointer<$library_type> { + let value: $library_type = Box::new([<$library_type_name Impl>]::new(capacity)); + value.into() } #[no_mangle] - unsafe extern "C" fn [< $library_type:snake _drop >](ptr: OwnedPtr<$library_type>) { + unsafe extern "C" fn [< $library_type_name:snake _drop >](ptr: OwnedPtr<$library_type>) { drop_in_place(ptr); } #[no_mangle] - unsafe extern "C" fn [< $library_type:snake _add >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr, value: OwnedPtr>) { + unsafe extern "C" fn [< $library_type_name:snake _add >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr, value: OwnedPtr>) { let lib = ptr.as_mut().unwrap(); lib.add(&CStr::from_ptr(key).into(), *Box::from_raw(value)); } #[no_mangle] - unsafe extern "C" fn [< $library_type:snake _remove >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr) { + unsafe extern "C" fn [< $library_type_name:snake _remove >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr) { let lib = ptr.as_mut().unwrap(); lib.remove(&CStr::from_ptr(key).into()); } #[no_mangle] - unsafe extern "C" fn [< $library_type:snake _get >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr) -> IdentifiablePointer> { + unsafe extern "C" fn [< $library_type_name:snake _get >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr) -> IdentifiablePointer> { let lib = ptr.as_mut().unwrap(); let v = lib.get(&CStr::from_ptr(key).into()); if let Some(value) = v { @@ -53,7 +54,7 @@ macro_rules! library_interface { } #[no_mangle] - unsafe extern "C" fn [< $library_type:snake _get_key_by_index >](ptr: OwnedPtr<$library_type>, index: usize) -> OwnedPtr { + unsafe extern "C" fn [< $library_type_name:snake _get_key_by_index >](ptr: OwnedPtr<$library_type>, index: usize) -> OwnedPtr { let lib = ptr.as_mut().unwrap(); let v = lib.get_key_by_index(index); if let Some(value) = v { @@ -64,7 +65,7 @@ macro_rules! library_interface { } #[no_mangle] - unsafe extern "C" fn [< $library_type:snake _len >](ptr: OwnedPtr<$library_type>) -> usize { + unsafe extern "C" fn [< $library_type_name:snake _len >](ptr: OwnedPtr<$library_type>) -> usize { let lib = ptr.as_mut().unwrap(); lib.len() } @@ -72,7 +73,7 @@ macro_rules! library_interface { }; } -library_interface!(SpeciesLibrary, dyn Species); -library_interface!(MoveLibrary, dyn MoveData); -library_interface!(AbilityLibrary, dyn Ability); -library_interface!(ItemLibrary, dyn Item); +library_interface!(SpeciesLibrary, Box, dyn Species); +library_interface!(MoveLibrary, Box, dyn MoveData); +library_interface!(AbilityLibrary, Box, dyn Ability); +library_interface!(ItemLibrary, Box, dyn Item); diff --git a/src/ffi/static_data/libraries/nature_library.rs b/src/ffi/static_data/libraries/nature_library.rs index 602decf..5d93739 100644 --- a/src/ffi/static_data/libraries/nature_library.rs +++ b/src/ffi/static_data/libraries/nature_library.rs @@ -1,25 +1,26 @@ use crate::ffi::{BorrowedPtr, ExternPointer, IdentifiablePointer, OwnedPtr}; -use crate::static_data::{Nature, NatureLibrary}; +use crate::static_data::{Nature, NatureLibrary, NatureLibraryImpl}; 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() +extern "C" fn nature_library_new(capacity: usize) -> IdentifiablePointer> { + let b: Box = Box::new(NatureLibraryImpl::new(capacity)); + b.into() } /// Drop a nature library. #[no_mangle] -unsafe extern "C" fn nature_library_drop(ptr: OwnedPtr) { +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( - mut ptr: ExternPointer, + mut ptr: ExternPointer>, name: BorrowedPtr, nature: OwnedPtr>, ) { @@ -30,7 +31,7 @@ unsafe extern "C" fn nature_library_load_nature( /// Gets a nature by name. #[no_mangle] unsafe extern "C" fn nature_library_get_nature( - ptr: ExternPointer, + ptr: ExternPointer>, name: BorrowedPtr, ) -> IdentifiablePointer> { if let Some(nature) = ptr.as_ref().get_nature(&CStr::from_ptr(name).into()) { @@ -43,7 +44,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, + ptr: ExternPointer>, nature: BorrowedPtr>, ) -> OwnedPtr { CString::new(ptr.as_ref().get_nature_name(nature.as_ref().unwrap()).str()) diff --git a/src/ffi/static_data/libraries/static_data.rs b/src/ffi/static_data/libraries/static_data.rs index c99f337..8bb377d 100644 --- a/src/ffi/static_data/libraries/static_data.rs +++ b/src/ffi/static_data/libraries/static_data.rs @@ -1,68 +1,85 @@ use crate::ffi::{ExternPointer, IdentifiablePointer, OwnedPtr}; use crate::static_data::{ AbilityLibrary, GrowthRateLibrary, ItemLibrary, LibrarySettings, MoveLibrary, NatureLibrary, SpeciesLibrary, - StaticData, TypeLibrary, + StaticData, StaticDataImpl, TypeLibrary, }; 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() +unsafe extern "C" fn static_data_new( + settings: OwnedPtr>, +) -> IdentifiablePointer> { + let b: Box = Box::new(StaticDataImpl::new(*Box::from_raw(settings))); + b.into() } /// Drop a static data. #[no_mangle] -unsafe extern "C" fn static_data_drop(ptr: OwnedPtr) { +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(mut data: ExternPointer) -> IdentifiablePointer { - (data.as_mut().settings() as *const LibrarySettings).into() +unsafe extern "C" fn static_data_settings( + mut data: ExternPointer>, +) -> IdentifiablePointer> { + data.as_mut().settings().into() } /// All data for Pokemon species. #[no_mangle] -unsafe extern "C" fn static_data_species(mut data: ExternPointer) -> IdentifiablePointer { - (data.as_mut().species_mut() as *const SpeciesLibrary).into() +unsafe extern "C" fn static_data_species( + mut data: ExternPointer>, +) -> IdentifiablePointer> { + data.as_mut().species().into() } /// All data for the moves. #[no_mangle] -unsafe extern "C" fn static_data_moves(mut data: ExternPointer) -> IdentifiablePointer { - (data.as_mut().moves_mut() as *const MoveLibrary).into() +unsafe extern "C" fn static_data_moves( + mut data: ExternPointer>, +) -> IdentifiablePointer> { + data.as_mut().moves().into() } /// All data for the items. #[no_mangle] -unsafe extern "C" fn static_data_items(mut data: ExternPointer) -> IdentifiablePointer { - (data.as_mut().items_mut() as *const ItemLibrary).into() +unsafe extern "C" fn static_data_items( + mut data: ExternPointer>, +) -> IdentifiablePointer> { + (data.as_mut().items()).into() } /// All data for growth rates. #[no_mangle] unsafe extern "C" fn static_data_growth_rates( - mut data: ExternPointer, -) -> IdentifiablePointer { - (data.as_mut().growth_rates_mut() as *const GrowthRateLibrary).into() + mut data: ExternPointer>, +) -> IdentifiablePointer> { + data.as_mut().growth_rates().into() } /// All data related to types and type effectiveness. #[no_mangle] -unsafe extern "C" fn static_data_types(mut data: ExternPointer) -> IdentifiablePointer { - (data.as_mut().types_mut() as *const TypeLibrary).into() +unsafe extern "C" fn static_data_types( + mut data: ExternPointer>, +) -> IdentifiablePointer> { + data.as_mut().types().into() } /// All data related to natures. #[no_mangle] -unsafe extern "C" fn static_data_natures(mut data: ExternPointer) -> IdentifiablePointer { - (data.as_mut().natures_mut() as *const NatureLibrary).into() +unsafe extern "C" fn static_data_natures( + data: ExternPointer>, +) -> IdentifiablePointer> { + data.as_ref().natures().into() } /// All data related to abilities. #[no_mangle] -unsafe extern "C" fn static_data_abilities(mut data: ExternPointer) -> IdentifiablePointer { - (data.as_mut().abilities_mut() as *const AbilityLibrary).into() +unsafe extern "C" fn static_data_abilities( + mut data: ExternPointer>, +) -> IdentifiablePointer> { + (data.as_mut().abilities()).into() } diff --git a/src/ffi/static_data/libraries/type_library.rs b/src/ffi/static_data/libraries/type_library.rs index 9b08b6c..5a9c5ae 100644 --- a/src/ffi/static_data/libraries/type_library.rs +++ b/src/ffi/static_data/libraries/type_library.rs @@ -1,24 +1,25 @@ use crate::ffi::{BorrowedPtr, ExternPointer, IdentifiablePointer, OwnedPtr}; -use crate::static_data::{TypeIdentifier, TypeLibrary}; +use crate::static_data::{TypeIdentifier, TypeLibrary, TypeLibraryImpl}; 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() +extern "C" fn type_library_new(capacity: usize) -> IdentifiablePointer> { + let b: Box = Box::new(TypeLibraryImpl::new(capacity)); + b.into() } /// Drops a type library. #[no_mangle] -unsafe extern "C" fn type_library_drop(ptr: OwnedPtr) { +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, + ptr: ExternPointer>, key: BorrowedPtr, found: *mut bool, ) -> TypeIdentifier { @@ -34,7 +35,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, + ptr: ExternPointer>, type_id: TypeIdentifier, found: *mut bool, ) -> *mut c_char { @@ -50,7 +51,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, + ptr: ExternPointer>, attacking: TypeIdentifier, defending: TypeIdentifier, ) -> f32 { @@ -62,7 +63,7 @@ extern "C" fn type_library_get_single_effectiveness( /// and multiplying the results with each other. #[no_mangle] unsafe extern "C" fn type_library_get_effectiveness( - ptr: ExternPointer, + ptr: ExternPointer>, attacking: TypeIdentifier, defending: OwnedPtr, defending_length: usize, @@ -74,7 +75,7 @@ unsafe extern "C" fn type_library_get_effectiveness( /// Registers a new type in the library. #[no_mangle] unsafe extern "C" fn type_library_register_type( - mut ptr: ExternPointer, + mut ptr: ExternPointer>, name: BorrowedPtr, ) -> TypeIdentifier { ptr.as_mut().register_type(&CStr::from_ptr(name).into()) @@ -83,7 +84,7 @@ unsafe extern "C" fn type_library_register_type( /// Sets the effectiveness for an attacking type against a defending type. #[no_mangle] unsafe extern "C" fn type_library_set_effectiveness( - mut ptr: ExternPointer, + mut ptr: ExternPointer>, attacking: TypeIdentifier, defending: TypeIdentifier, effectiveness: f32, diff --git a/src/lib.rs b/src/lib.rs index 09d3f7f..1ef6a34 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ #![allow(clippy::too_many_arguments, clippy::needless_range_loop)] #![allow(clippy::not_unsafe_ptr_arg_deref)] +#![allow(clippy::borrowed_box)] #![allow(incomplete_features)] #![deny(missing_docs)] #![deny(clippy::missing_docs_in_private_items)] diff --git a/src/script_implementations/wasm/export_registry/dynamic_data/battle.rs b/src/script_implementations/wasm/export_registry/dynamic_data/battle.rs index 52d8512..a81ef6d 100755 --- a/src/script_implementations/wasm/export_registry/dynamic_data/battle.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/battle.rs @@ -37,8 +37,8 @@ register! { fn battle_get_library( env: FunctionEnvMut, battle: ExternRef, - ) -> ExternRef { - ExternRef::func_new(&env, battle.value_func(&env).unwrap().library().as_ref()) + ) -> ExternRef { + ExternRef::func_new(&env, &battle.value_func_arc(&env).unwrap().library().clone()) } fn battle_get_sides( 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 f8fd4a8..2eb5444 100755 --- a/src/script_implementations/wasm/export_registry/dynamic_data/mod.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/mod.rs @@ -31,9 +31,9 @@ mod turn_choice; register! { fn dynamic_library_get_static_data( env: FunctionEnvMut, - dynamic_lib: ExternRef, - ) -> ExternRef { - ExternRef::func_new(&env, dynamic_lib.value_func(&env).unwrap().static_data()) + dynamic_lib: ExternRef, + ) -> ExternRef { + ExternRef::func_new(&env, dynamic_lib.value_func_arc(&env).unwrap().static_data()) } fn script_get_owner( 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 79d6294..4379150 100755 --- a/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs @@ -15,9 +15,9 @@ register! { fn pokemon_get_library( env: FunctionEnvMut, pokemon: ExternRef, - ) -> ExternRef { - let lib = pokemon.value_func(&env).unwrap().library().as_ref(); - ExternRef::func_new(&env, lib) + ) -> ExternRef { + let lib = pokemon.value_func(&env).unwrap().library().clone(); + ExternRef::func_new(&env, &lib) } fn pokemon_get_boosted_stats( diff --git a/src/script_implementations/wasm/export_registry/static_data/item.rs b/src/script_implementations/wasm/export_registry/static_data/item.rs index b51f087..67221e3 100755 --- a/src/script_implementations/wasm/export_registry/static_data/item.rs +++ b/src/script_implementations/wasm/export_registry/static_data/item.rs @@ -1,7 +1,8 @@ use crate::script_implementations::wasm::export_registry::register; use crate::script_implementations::wasm::extern_ref::ExternRef; use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv; -use crate::static_data::{DataLibrary, Item, ItemLibrary}; +use crate::static_data::Item; +use crate::static_data::ItemLibrary; use crate::StringKey; use std::mem::transmute; use wasmer::FunctionEnvMut; @@ -9,23 +10,23 @@ use wasmer::FunctionEnvMut; register! { fn item_library_get_item( env: FunctionEnvMut, - lib: ExternRef, + lib: ExternRef, string_key: ExternRef, ) -> ExternRef { - let lib = lib.value_func(&env).unwrap(); + let lib = lib.value_func_box(&env).unwrap(); let m = lib.get(string_key.value_func(&env).unwrap()); if let Some(v) = m { - ExternRef::func_new(&env, v) + ExternRef::func_new(&env, &v) } else { ExternRef::null() } } - fn item_library_get_item_by_hash(env: FunctionEnvMut, lib: ExternRef, hash: u32) -> ExternRef { - let lib = lib.value_func(&env).unwrap(); + fn item_library_get_item_by_hash(env: FunctionEnvMut, lib: ExternRef, hash: u32) -> ExternRef { + let lib = lib.value_func_box(&env).unwrap(); let m = lib.get_by_hash(hash); if let Some(v) = m { - ExternRef::func_new(&env, v) + ExternRef::func_new(&env, &v) } else { ExternRef::null() } 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 d8ca752..ea0e88d 100755 --- a/src/script_implementations/wasm/export_registry/static_data/mod.rs +++ b/src/script_implementations/wasm/export_registry/static_data/mod.rs @@ -17,34 +17,34 @@ mod moves; mod species; register! { - fn static_data_get_move_library(env: FunctionEnvMut, data_library: ExternRef) -> ExternRef { - ExternRef::func_new(&env, data_library.value_func(&env).unwrap().moves()) + fn static_data_get_move_library(env: FunctionEnvMut, data_library: ExternRef) -> ExternRef { + ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().moves()) } fn static_data_get_species_library( env: FunctionEnvMut, - data_library: ExternRef, - ) -> ExternRef { - ExternRef::func_new(&env, data_library.value_func(&env).unwrap().species()) + data_library: ExternRef, + ) -> ExternRef { + ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().species()) } - fn static_data_get_item_library(env: FunctionEnvMut, data_library: ExternRef) -> ExternRef { - ExternRef::func_new(&env, data_library.value_func(&env).unwrap().items()) + fn static_data_get_item_library(env: FunctionEnvMut, data_library: ExternRef) -> ExternRef { + ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().items()) } - fn static_data_get_type_library(env: FunctionEnvMut, data_library: ExternRef) -> ExternRef { - ExternRef::func_new(&env, data_library.value_func(&env).unwrap().types()) + fn static_data_get_type_library(env: FunctionEnvMut, data_library: ExternRef) -> ExternRef { + ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().types()) } fn static_data_get_library_settings( env: FunctionEnvMut, - data_library: ExternRef, - ) -> ExternRef { - ExternRef::func_new(&env, data_library.value_func(&env).unwrap().settings()) + data_library: ExternRef, + ) -> ExternRef { + ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().settings()) } - fn library_settings_get_maximum_level(env: FunctionEnvMut, data_library: ExternRef) -> LevelInt { - data_library.value_func(&env).unwrap().maximum_level() + fn library_settings_get_maximum_level(env: FunctionEnvMut, data_library: ExternRef) -> LevelInt { + data_library.value_func_box(&env).unwrap().maximum_level() } fn statistic_set_get(env: FunctionEnvMut, statistics_set: ExternRef>, stat: u8) -> i64 { 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 b75a4fb..aaec1cd 100755 --- a/src/script_implementations/wasm/export_registry/static_data/moves.rs +++ b/src/script_implementations/wasm/export_registry/static_data/moves.rs @@ -1,30 +1,30 @@ use crate::script_implementations::wasm::export_registry::register; use crate::script_implementations::wasm::extern_ref::ExternRef; use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv; -use crate::static_data::{DataLibrary, MoveData, MoveLibrary}; +use crate::static_data::{MoveData, MoveLibrary}; use crate::StringKey; use wasmer::FunctionEnvMut; register! { fn move_library_get_move( env: FunctionEnvMut, - lib: ExternRef, + lib: ExternRef, string_key: ExternRef, ) -> ExternRef { - let lib = lib.value_func(&env).unwrap(); + let lib = lib.value_func_box(&env).unwrap(); let m = lib.get(string_key.value_func(&env).unwrap()); if let Some(v) = m { - ExternRef::func_new(&env, v) + ExternRef::func_new(&env, &v) } else { ExternRef::null() } } -fn move_library_get_move_by_hash(env: FunctionEnvMut, lib: ExternRef, hash: u32) -> ExternRef { - let lib = lib.value_func(&env).unwrap(); +fn move_library_get_move_by_hash(env: FunctionEnvMut, lib: ExternRef, hash: u32) -> ExternRef { + let lib = lib.value_func_box(&env).unwrap(); let m = lib.get_by_hash(hash); if let Some(v) = m { - ExternRef::func_new(&env, v) + ExternRef::func_new(&env, &v) } else { ExternRef::null() } diff --git a/src/script_implementations/wasm/export_registry/static_data/species.rs b/src/script_implementations/wasm/export_registry/static_data/species.rs index 02ef3e1..68aea50 100755 --- a/src/script_implementations/wasm/export_registry/static_data/species.rs +++ b/src/script_implementations/wasm/export_registry/static_data/species.rs @@ -1,7 +1,8 @@ use crate::script_implementations::wasm::export_registry::register; use crate::script_implementations::wasm::extern_ref::ExternRef; use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv; -use crate::static_data::{DataLibrary, Species, SpeciesLibrary}; +use crate::static_data::Species; +use crate::static_data::SpeciesLibrary; use crate::StringKey; use wasmer::FunctionEnvMut; @@ -9,13 +10,13 @@ register! { fn species_library_get_species( env: FunctionEnvMut, - lib: ExternRef, + lib: ExternRef, string_key: ExternRef, ) -> ExternRef { - let lib = lib.value_func(&env).unwrap(); + let lib = lib.value_func_box(&env).unwrap(); let m = lib.get(string_key.value_func(&env).unwrap()); if let Some(v) = m { - ExternRef::func_new(&env, v) + ExternRef::func_new(&env, &v) } else { ExternRef::null() } diff --git a/src/script_implementations/wasm/extern_ref.rs b/src/script_implementations/wasm/extern_ref.rs index 7e0e242..bb3b766 100755 --- a/src/script_implementations/wasm/extern_ref.rs +++ b/src/script_implementations/wasm/extern_ref.rs @@ -74,6 +74,15 @@ impl ExternRef { self.value_arc(&env.data().data()) } + /// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the + /// value when it was passed before. If these types do not match, this will panic. + pub fn value_func_box(&self, env: &FunctionEnvMut) -> Option<&Box> + where + T: 'static, + { + self.value_box(&env.data().data()) + } + /// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the /// value when it was passed before. If these types do not match, this will panic. pub fn value<'a, 'b, 'c>(&'a self, env: &'b Arc) -> Option<&'c T> @@ -93,6 +102,15 @@ impl ExternRef { .downcast_ref::>() .cloned() } + + /// Returns the real value for a given ExternRef. Note that the requested type must be the same as the type of the + /// value when it was passed before. If these types do not match, this will panic. + pub fn value_box(&self, env: &Arc) -> Option<&Box> + where + T: 'static, + { + env.get_extern_ref_value::(self.index).downcast_ref::>() + } } unsafe impl FromToNativeWasmType for ExternRef { diff --git a/src/script_implementations/wasm/script.rs b/src/script_implementations/wasm/script.rs index 36b800f..1896eb7 100755 --- a/src/script_implementations/wasm/script.rs +++ b/src/script_implementations/wasm/script.rs @@ -125,7 +125,7 @@ impl Script for WebAssemblyScript { } } - fn on_initialize(&self, library: &DynamicLibrary, pars: Vec) { + fn on_initialize(&self, library: &Arc, pars: Vec) { if !self.has_capability(&WebAssemblyScriptCapabilities::Initialize) { return; } diff --git a/src/script_implementations/wasm/script_function_cache.rs b/src/script_implementations/wasm/script_function_cache.rs index 212bd4a..a2ca70f 100755 --- a/src/script_implementations/wasm/script_function_cache.rs +++ b/src/script_implementations/wasm/script_function_cache.rs @@ -117,7 +117,7 @@ unsafe impl FromToNativeWasmType for WasmPtr { script_function_cache! { stack() on_remove() - on_initialize(ExternRef, VecExternRef) + on_initialize(ExternRef, VecExternRef) on_before_turn(ExternRef) change_speed(ExternRef, WasmPtr) change_priority(ExternRef, WasmPtr) diff --git a/src/static_data/libraries/ability_library.rs b/src/static_data/libraries/ability_library.rs index d6d244e..3e1fce6 100755 --- a/src/static_data/libraries/ability_library.rs +++ b/src/static_data/libraries/ability_library.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::sync::Arc; use indexmap::IndexMap; @@ -6,26 +7,31 @@ use crate::static_data::Ability; use crate::static_data::DataLibrary; use crate::{StringKey, ValueIdentifiable, ValueIdentifier}; +/// A storage for all abilities that can be used in this data library. +pub trait AbilityLibrary: DataLibrary + ValueIdentifiable + Debug {} + /// A storage for all abilities that can be used in this data library. #[derive(Debug)] -pub struct AbilityLibrary { +pub struct AbilityLibraryImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The underlying map for the library. map: IndexMap>, } -impl AbilityLibrary { +impl AbilityLibraryImpl { /// Instantiates a new ability library. - pub fn new(capacity: usize) -> AbilityLibrary { - AbilityLibrary { + pub fn new(capacity: usize) -> Self { + Self { identifier: Default::default(), map: IndexMap::with_capacity(capacity), } } } -impl DataLibrary for AbilityLibrary { +impl AbilityLibrary for AbilityLibraryImpl {} + +impl DataLibrary for AbilityLibraryImpl { fn map(&self) -> &IndexMap> { &self.map } @@ -34,7 +40,7 @@ impl DataLibrary for AbilityLibrary { } } -impl ValueIdentifiable for AbilityLibrary { +impl ValueIdentifiable for AbilityLibraryImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } @@ -42,14 +48,14 @@ impl ValueIdentifiable for AbilityLibrary { #[cfg(test)] pub mod tests { + use crate::static_data::libraries::ability_library::AbilityLibraryImpl; use crate::static_data::AbilityImpl; - use crate::static_data::AbilityLibrary; use crate::static_data::DataLibrary; use crate::StringKey; use std::sync::Arc; - pub fn build() -> AbilityLibrary { - let mut lib = AbilityLibrary::new(1); + pub fn build() -> AbilityLibraryImpl { + let mut lib = AbilityLibraryImpl::new(1); lib.add( &StringKey::new("test_ability"), Arc::new(AbilityImpl::new( diff --git a/src/static_data/libraries/data_library.rs b/src/static_data/libraries/data_library.rs index b483320..c0441f9 100755 --- a/src/static_data/libraries/data_library.rs +++ b/src/static_data/libraries/data_library.rs @@ -24,13 +24,13 @@ pub trait DataLibrary { } /// Gets a value from the library. - fn get(&self, key: &StringKey) -> Option<&Arc> { - self.map().get::(key) + fn get(&self, key: &StringKey) -> Option> { + self.map().get::(key).cloned() } /// Gets a value from the library. - fn get_by_hash(&self, key: u32) -> Option<&Arc> { - self.map().get::(&key) + fn get_by_hash(&self, key: u32) -> Option> { + self.map().get::(&key).cloned() } /// Gets a value from the library by the index where it is stored. diff --git a/src/static_data/libraries/growth_rate_library.rs b/src/static_data/libraries/growth_rate_library.rs index 4ac29a1..6b5579e 100755 --- a/src/static_data/libraries/growth_rate_library.rs +++ b/src/static_data/libraries/growth_rate_library.rs @@ -8,44 +8,56 @@ use crate::static_data::GrowthRate; use crate::{StringKey, ValueIdentifiable, ValueIdentifier}; /// A library to store all growth rates. -pub struct GrowthRateLibrary { +pub trait GrowthRateLibrary: Debug + ValueIdentifiable { + /// Calculates the level for a given growth key name and a certain experience. + fn calculate_level(&self, growth_rate: &StringKey, experience: u32) -> LevelInt; + /// Calculates the experience for a given growth key name and a certain level. + fn calculate_experience(&self, growth_rate: &StringKey, level: LevelInt) -> u32; + /// Adds a new growth rate with a name and value. + fn add_growth_rate(&mut self, key: &StringKey, value: Box); +} + +/// A library to store all growth rates. +pub struct GrowthRateLibraryImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The underlying data structure. growth_rates: HashMap>, } -impl GrowthRateLibrary { +impl GrowthRateLibraryImpl { /// Instantiates a new growth rate library with a capacity. - pub fn new(capacity: usize) -> GrowthRateLibrary { - GrowthRateLibrary { + pub fn new(capacity: usize) -> Self { + Self { identifier: Default::default(), growth_rates: HashMap::with_capacity(capacity), } } +} +impl GrowthRateLibrary for GrowthRateLibraryImpl { /// Calculates the level for a given growth key name and a certain experience. - pub fn calculate_level(&self, growth_rate: &StringKey, experience: u32) -> LevelInt { + fn calculate_level(&self, growth_rate: &StringKey, experience: u32) -> LevelInt { self.growth_rates[growth_rate].calculate_level(experience) } /// Calculates the experience for a given growth key name and a certain level. - pub fn calculate_experience(&self, growth_rate: &StringKey, level: LevelInt) -> u32 { + fn calculate_experience(&self, growth_rate: &StringKey, level: LevelInt) -> u32 { self.growth_rates[growth_rate].calculate_experience(level) } /// Adds a new growth rate with a name and value. - pub fn add_growth_rate(&mut self, key: &StringKey, value: Box) { + fn add_growth_rate(&mut self, key: &StringKey, value: Box) { self.growth_rates.insert(key.clone(), value); } } -impl ValueIdentifiable for GrowthRateLibrary { +impl ValueIdentifiable for GrowthRateLibraryImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } } -impl Debug for GrowthRateLibrary { +impl Debug for GrowthRateLibraryImpl { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { f.debug_struct("GrowthRateLibrary").finish() } @@ -53,11 +65,13 @@ impl Debug for GrowthRateLibrary { #[cfg(test)] pub mod tests { + use super::*; use crate::static_data::growth_rates::LookupGrowthRate; use crate::static_data::libraries::growth_rate_library::GrowthRateLibrary; + use crate::static_data::GrowthRateLibraryImpl; - pub fn build() -> GrowthRateLibrary { - let mut lib = GrowthRateLibrary::new(1); + pub fn build() -> GrowthRateLibraryImpl { + let mut lib = GrowthRateLibraryImpl::new(1); // Borrow as mut so we can insert let w = &mut lib; @@ -70,6 +84,21 @@ pub mod tests { lib } + mockall::mock! { + #[derive(Debug)] + pub GrowthRateLibrary{} + impl GrowthRateLibrary for GrowthRateLibrary { + fn calculate_level(&self, growth_rate: &StringKey, experience: u32) -> LevelInt; + fn calculate_experience(&self, growth_rate: &StringKey, level: LevelInt) -> u32; + fn add_growth_rate(&mut self, key: &StringKey, value: Box); + } + impl ValueIdentifiable for GrowthRateLibrary { + fn value_identifier(&self) -> ValueIdentifier{ + ValueIdentifier::new(0) + } + } + } + #[test] fn add_growth_rate_to_library_and_calculate_level() { let lib = build(); diff --git a/src/static_data/libraries/item_library.rs b/src/static_data/libraries/item_library.rs index ee27b47..9053b66 100755 --- a/src/static_data/libraries/item_library.rs +++ b/src/static_data/libraries/item_library.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::sync::Arc; use indexmap::IndexMap; @@ -7,26 +8,30 @@ use crate::static_data::Item; use crate::{StringKey, ValueIdentifiable, ValueIdentifier}; /// A library to store all items. -#[derive(Debug)] +pub trait ItemLibrary: DataLibrary + ValueIdentifiable + Debug {} -pub struct ItemLibrary { +/// A library to store all items. +#[derive(Debug)] +pub struct ItemLibraryImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The underlying data structure. map: IndexMap>, } -impl ItemLibrary { +impl ItemLibraryImpl { /// Instantiates a new Item Library. - pub fn new(capacity: usize) -> ItemLibrary { - ItemLibrary { + pub fn new(capacity: usize) -> Self { + Self { identifier: Default::default(), map: IndexMap::with_capacity(capacity), } } } -impl DataLibrary for ItemLibrary { +impl ItemLibrary for ItemLibraryImpl {} + +impl DataLibrary for ItemLibraryImpl { fn map(&self) -> &IndexMap> { &self.map } @@ -36,7 +41,7 @@ impl DataLibrary for ItemLibrary { } } -impl ValueIdentifiable for ItemLibrary { +impl ValueIdentifiable for ItemLibraryImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } @@ -49,8 +54,8 @@ pub mod tests { use crate::static_data::libraries::data_library::DataLibrary; use crate::static_data::libraries::item_library::ItemLibrary; - use crate::static_data::ItemImpl; use crate::static_data::{BattleItemCategory, ItemCategory}; + use crate::static_data::{ItemImpl, ItemLibraryImpl}; fn build_item() -> ItemImpl { ItemImpl::new( @@ -62,14 +67,14 @@ pub mod tests { ) } - pub fn build() -> ItemLibrary { - let mut lib = ItemLibrary::new(1); + pub fn build() -> Box { + let mut lib = ItemLibraryImpl::new(1); let m = build_item(); // Borrow as mut so we can insert let w = &mut lib; w.add(&"foo".into(), Arc::new(m)); // Drops borrow as mut - lib + Box::new(lib) } } diff --git a/src/static_data/libraries/library_settings.rs b/src/static_data/libraries/library_settings.rs index 298cabf..5526911 100755 --- a/src/static_data/libraries/library_settings.rs +++ b/src/static_data/libraries/library_settings.rs @@ -1,16 +1,23 @@ use crate::defines::LevelInt; use crate::{ValueIdentifiable, ValueIdentifier}; +use std::fmt::Debug; + +/// This library holds several misc settings for the library. +pub trait LibrarySettings: Debug + ValueIdentifiable { + /// The highest level a Pokemon can be. + fn maximum_level(&self) -> LevelInt; +} /// This library holds several misc settings for the library. #[derive(Debug)] -pub struct LibrarySettings { +pub struct LibrarySettingsImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The highest level a Pokemon can be. maximum_level: LevelInt, } -impl LibrarySettings { +impl LibrarySettingsImpl { /// Creates a new settings library. pub fn new(maximum_level: LevelInt) -> Self { Self { @@ -18,14 +25,16 @@ impl LibrarySettings { maximum_level, } } +} +impl LibrarySettings for LibrarySettingsImpl { /// The highest level a Pokemon can be. - pub fn maximum_level(&self) -> LevelInt { + fn maximum_level(&self) -> LevelInt { self.maximum_level } } -impl ValueIdentifiable for LibrarySettings { +impl ValueIdentifiable for LibrarySettingsImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } diff --git a/src/static_data/libraries/mod.rs b/src/static_data/libraries/mod.rs index 374108c..1504ce4 100755 --- a/src/static_data/libraries/mod.rs +++ b/src/static_data/libraries/mod.rs @@ -1,21 +1,21 @@ #[doc(inline)] -pub use ability_library::AbilityLibrary; +pub use ability_library::*; #[doc(inline)] -pub use data_library::DataLibrary; +pub use data_library::*; #[doc(inline)] -pub use growth_rate_library::GrowthRateLibrary; +pub use growth_rate_library::*; #[doc(inline)] -pub use item_library::ItemLibrary; +pub use item_library::*; #[doc(inline)] -pub use library_settings::LibrarySettings; +pub use library_settings::*; #[doc(inline)] -pub use move_library::MoveLibrary; +pub use move_library::*; #[doc(inline)] pub use nature_library::*; #[doc(inline)] -pub use species_library::SpeciesLibrary; +pub use species_library::*; #[doc(inline)] -pub use static_data::StaticData; +pub use static_data::*; #[doc(inline)] pub use type_library::*; @@ -23,22 +23,22 @@ pub use type_library::*; pub(crate) mod tests {} /// The library data for abilities. -mod ability_library; +pub(crate) mod ability_library; /// Basic helper trait for libraries. -mod data_library; +pub(crate) mod data_library; /// The library data for groth rates. -mod growth_rate_library; +pub(crate) mod growth_rate_library; /// The library data for items. -mod item_library; +pub(crate) mod item_library; /// The library data for misc settings. -mod library_settings; +pub(crate) mod library_settings; /// The library data for moves. -mod move_library; +pub(crate) mod move_library; /// The library data for natures. -mod nature_library; +pub(crate) mod nature_library; /// The library data for species. -mod species_library; +pub(crate) mod species_library; /// The combination of all libraries. pub(crate) mod static_data; /// The library data for types. -mod type_library; +pub(crate) mod type_library; diff --git a/src/static_data/libraries/move_library.rs b/src/static_data/libraries/move_library.rs index 81fa76e..16db077 100755 --- a/src/static_data/libraries/move_library.rs +++ b/src/static_data/libraries/move_library.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::sync::Arc; use indexmap::IndexMap; @@ -7,26 +8,30 @@ use crate::static_data::MoveData; use crate::{StringKey, ValueIdentifiable, ValueIdentifier}; /// A library to store all data for moves. -#[derive(Debug)] +pub trait MoveLibrary: DataLibrary + ValueIdentifiable + Debug {} -pub struct MoveLibrary { +/// A library to store all data for moves. +#[derive(Debug)] +pub struct MoveLibraryImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The underlying map. map: IndexMap>, } -impl MoveLibrary { +impl MoveLibraryImpl { /// Instantiates a new Move Library. - pub fn new(capacity: usize) -> MoveLibrary { - MoveLibrary { + pub fn new(capacity: usize) -> Self { + Self { identifier: Default::default(), map: IndexMap::with_capacity(capacity), } } } -impl DataLibrary for MoveLibrary { +impl MoveLibrary for MoveLibraryImpl {} + +impl DataLibrary for MoveLibraryImpl { fn map(&self) -> &IndexMap> { &self.map } @@ -35,7 +40,7 @@ impl DataLibrary for MoveLibrary { } } -impl ValueIdentifiable for MoveLibrary { +impl ValueIdentifiable for MoveLibraryImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } @@ -48,7 +53,7 @@ pub mod tests { use crate::static_data::libraries::data_library::DataLibrary; use crate::static_data::libraries::move_library::MoveLibrary; - use crate::static_data::{MoveCategory, MoveDataImpl, MoveTarget}; + use crate::static_data::{MoveCategory, MoveDataImpl, MoveLibraryImpl, MoveTarget}; use crate::StringKey; fn build_move() -> MoveDataImpl { @@ -66,14 +71,14 @@ pub mod tests { ) } - pub fn build() -> MoveLibrary { - let mut lib = MoveLibrary::new(1); + pub fn build() -> Box { + let mut lib = MoveLibraryImpl::new(1); let m = build_move(); // Borrow as mut so we can insert let w = &mut lib; w.add(&StringKey::new("foo"), Arc::new(m)); // Drops borrow as mut - lib + Box::new(lib) } } diff --git a/src/static_data/libraries/nature_library.rs b/src/static_data/libraries/nature_library.rs index a71ce60..158e65e 100644 --- a/src/static_data/libraries/nature_library.rs +++ b/src/static_data/libraries/nature_library.rs @@ -1,38 +1,51 @@ use crate::static_data::Nature; use crate::{StringKey, ValueIdentifiable, ValueIdentifier}; use hashbrown::HashMap; +use std::fmt::Debug; use std::sync::Arc; +/// A library of all natures that can be used, stored by their names. +pub trait NatureLibrary: Debug + ValueIdentifiable { + /// Adds a new nature with name to the library. + fn load_nature(&mut self, name: StringKey, nature: Arc); + /// Gets a nature by name. + fn get_nature(&self, key: &StringKey) -> Option>; + /// Finds a nature name by nature. + fn get_nature_name(&self, nature: &Arc) -> StringKey; +} + /// A library of all natures that can be used, stored by their names. #[derive(Debug)] -pub struct NatureLibrary { +pub struct NatureLibraryImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The underlying data structure. map: HashMap>, } -impl NatureLibrary { +impl NatureLibraryImpl { /// Creates a new nature library with a given capacity. pub fn new(capacity: usize) -> Self { - NatureLibrary { + Self { identifier: Default::default(), map: HashMap::with_capacity(capacity), } } +} +impl NatureLibrary for NatureLibraryImpl { /// Adds a new nature with name to the library. - pub fn load_nature(&mut self, name: StringKey, nature: Arc) { + fn load_nature(&mut self, name: StringKey, nature: Arc) { self.map.insert(name, nature); } /// Gets a nature by name. - pub fn get_nature(&self, key: &StringKey) -> Option<&Arc> { - self.map.get(key) + fn get_nature(&self, key: &StringKey) -> Option> { + self.map.get(key).cloned() } /// Finds a nature name by nature. - pub fn get_nature_name(&self, nature: &Arc) -> StringKey { + fn get_nature_name(&self, nature: &Arc) -> StringKey { for kv in &self.map { // As natures can't be copied, and should always be the same reference as the value // in the map, we just compare by reference. @@ -44,7 +57,7 @@ impl NatureLibrary { } } -impl ValueIdentifiable for NatureLibrary { +impl ValueIdentifiable for NatureLibraryImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } @@ -52,11 +65,12 @@ impl ValueIdentifiable for NatureLibrary { #[cfg(test)] pub mod tests { + use super::*; use crate::static_data::statistics::Statistic; - use crate::static_data::{NatureImpl, NatureLibrary}; + use crate::static_data::{NatureImpl, NatureLibrary, NatureLibraryImpl}; - pub fn build() -> NatureLibrary { - let mut lib = NatureLibrary::new(2); + pub fn build() -> NatureLibraryImpl { + let mut lib = NatureLibraryImpl::new(2); lib.load_nature( "test_nature".into(), @@ -66,9 +80,24 @@ pub mod tests { lib } + mockall::mock! { + #[derive(Debug)] + pub NatureLibrary{} + impl NatureLibrary for NatureLibrary { + fn load_nature(&mut self, name: StringKey, nature: Arc); + fn get_nature(&self, key: &StringKey) -> Option>; + fn get_nature_name(&self, nature: &Arc) -> StringKey; + } + impl ValueIdentifiable for NatureLibrary { + fn value_identifier(&self) -> ValueIdentifier{ + ValueIdentifier::new(0) + } + } + } + #[test] fn create_nature_library_insert_and_retrieve() { - let mut lib = NatureLibrary::new(2); + let mut lib = NatureLibraryImpl::new(2); lib.load_nature( "foo".into(), NatureImpl::new(Statistic::HP, Statistic::Attack, 1.1, 0.9), @@ -86,7 +115,7 @@ pub mod tests { #[test] fn create_nature_library_insert_and_get_name() { - let mut lib = NatureLibrary::new(2); + let mut lib = NatureLibraryImpl::new(2); lib.load_nature( "foo".into(), NatureImpl::new(Statistic::HP, Statistic::Attack, 1.1, 0.9), @@ -97,10 +126,10 @@ pub mod tests { ); let n1 = lib.get_nature(&"foo".into()).expect("Nature was not found"); - let name = lib.get_nature_name(n1); + let name = lib.get_nature_name(&n1); assert_eq!(name, "foo".into()); let n2 = lib.get_nature(&"bar".into()).expect("Nature was not found"); - let name2 = lib.get_nature_name(n2); + let name2 = lib.get_nature_name(&n2); assert_eq!(name2, "bar".into()); } } diff --git a/src/static_data/libraries/species_library.rs b/src/static_data/libraries/species_library.rs index 31a9682..d382210 100755 --- a/src/static_data/libraries/species_library.rs +++ b/src/static_data/libraries/species_library.rs @@ -1,3 +1,4 @@ +use std::fmt::Debug; use std::sync::Arc; use indexmap::IndexMap; @@ -7,26 +8,30 @@ use crate::static_data::Species; use crate::{StringKey, ValueIdentifiable, ValueIdentifier}; /// A library to store all data for Pokemon species. -#[derive(Debug)] +pub trait SpeciesLibrary: DataLibrary + ValueIdentifiable + Debug {} -pub struct SpeciesLibrary { +/// A library to store all data for Pokemon species. +#[derive(Debug)] +pub struct SpeciesLibraryImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// The underlying map. map: IndexMap>, } -impl SpeciesLibrary { +impl SpeciesLibraryImpl { /// Instantiates a new Species Library. - pub fn new(capacity: usize) -> SpeciesLibrary { - SpeciesLibrary { + pub fn new(capacity: usize) -> Self { + Self { identifier: Default::default(), map: IndexMap::with_capacity(capacity), } } } -impl DataLibrary for SpeciesLibrary { +impl SpeciesLibrary for SpeciesLibraryImpl {} + +impl DataLibrary for SpeciesLibraryImpl { fn map(&self) -> &IndexMap> { &self.map } @@ -35,7 +40,7 @@ impl DataLibrary for SpeciesLibrary { } } -impl ValueIdentifiable for SpeciesLibrary { +impl ValueIdentifiable for SpeciesLibraryImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } @@ -43,14 +48,27 @@ impl ValueIdentifiable for SpeciesLibrary { #[cfg(test)] pub mod tests { + use super::*; + use crate::static_data::{FormImpl, LearnableMovesImpl, SpeciesImpl, StaticStatisticSet}; use hashbrown::HashSet; use std::sync::Arc; - use crate::static_data::libraries::data_library::DataLibrary; - use crate::static_data::libraries::species_library::SpeciesLibrary; - use crate::static_data::LearnableMovesImpl; - use crate::static_data::{FormImpl, StaticStatisticSet}; - use crate::static_data::{Species, SpeciesImpl}; + mockall::mock! { + #[derive(Debug)] + pub SpeciesLibrary{} + impl SpeciesLibrary for SpeciesLibrary {} + impl DataLibrary for SpeciesLibrary { + fn get<'a, 'b>(&'a self, key: &'b StringKey) -> Option> ; + fn get_by_hash<'a>(&'a self, key: u32) -> Option>; + fn map(&self) -> &IndexMap>; + fn get_modify(&mut self) -> &mut IndexMap>; + } + impl ValueIdentifiable for SpeciesLibrary { + fn value_identifier(&self) -> ValueIdentifier{ + ValueIdentifier::new(0) + } + } + } fn build_species() -> Arc { Arc::new(SpeciesImpl::new( @@ -75,15 +93,15 @@ pub mod tests { )) } - pub fn build() -> SpeciesLibrary { - let mut lib = SpeciesLibrary::new(1); + pub fn build() -> Box { + let mut lib = SpeciesLibraryImpl::new(1); let species = build_species(); // Borrow as mut so we can insert let w = &mut lib; w.add(&"foo".into(), species); // Drops borrow as mut - lib + Box::new(lib) } #[test] @@ -94,8 +112,9 @@ pub mod tests { let r = &lib; let mon = r.get(&"foo".into()); assert!(mon.is_some()); - assert_eq!(mon.unwrap().id(), 0_u16); - assert_eq!(mon.unwrap().as_ref().name(), &"foo".into()); + let mon = mon.unwrap(); + assert_eq!(mon.id(), 0_u16); + assert_eq!(mon.name(), &"foo".into()); assert_eq!(r.len(), 1); } diff --git a/src/static_data/libraries/static_data.rs b/src/static_data/libraries/static_data.rs index 115e98d..1d7886d 100755 --- a/src/static_data/libraries/static_data.rs +++ b/src/static_data/libraries/static_data.rs @@ -1,115 +1,154 @@ -use crate::static_data::AbilityLibrary; -use crate::static_data::GrowthRateLibrary; -use crate::static_data::ItemLibrary; -use crate::static_data::LibrarySettings; use crate::static_data::MoveLibrary; use crate::static_data::NatureLibrary; use crate::static_data::SpeciesLibrary; use crate::static_data::TypeLibrary; +use crate::static_data::{AbilityLibrary, AbilityLibraryImpl, ItemLibraryImpl, MoveLibraryImpl, SpeciesLibraryImpl}; +use crate::static_data::{GrowthRateLibrary, GrowthRateLibraryImpl}; +use crate::static_data::{ItemLibrary, NatureLibraryImpl}; +use crate::static_data::{LibrarySettings, TypeLibraryImpl}; use crate::{ValueIdentifiable, ValueIdentifier}; +use std::fmt::Debug; + +/// The storage for all different libraries. +pub trait StaticData: Debug + ValueIdentifiable { + /// Several misc settings for the library. + fn settings(&self) -> &Box; + /// All data for Pokemon species. + fn species(&self) -> &Box; + /// All data for Pokemon species. + fn species_mut(&mut self) -> &mut Box; + /// All data for the moves. + fn moves(&self) -> &Box; + /// All data for the moves. + fn moves_mut(&mut self) -> &mut Box; + /// All data for the items. + fn items(&self) -> &Box; + /// All data for the items. + fn items_mut(&mut self) -> &mut Box; + + /// All data for growth rates. + fn growth_rates(&self) -> &Box; + /// All data for growth rates. + fn growth_rates_mut(&mut self) -> &mut Box; + /// All data related to types and type effectiveness. + fn types(&self) -> &Box; + /// All data related to types and type effectiveness. + fn types_mut(&mut self) -> &mut Box; + /// All data related to natures. + fn natures(&self) -> &Box; + /// All data related to natures. + fn natures_mut(&mut self) -> &mut Box; + /// All data related to abilities. + fn abilities(&self) -> &Box; + /// All data related to abilities. + fn abilities_mut(&mut self) -> &mut Box; +} /// The storage for all different libraries. #[derive(Debug)] -pub struct StaticData { +pub struct StaticDataImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// Several misc settings for the library. - settings: LibrarySettings, + settings: Box, /// All data for Pokemon species. - species: SpeciesLibrary, + species: Box, /// All data for the moves. - moves: MoveLibrary, + moves: Box, /// All data for the items. - items: ItemLibrary, + items: Box, /// All data for growth rates. - growth_rates: GrowthRateLibrary, + growth_rates: Box, /// All data related to types and type effectiveness. - types: TypeLibrary, + types: Box, /// All data related to natures. - natures: NatureLibrary, + natures: Box, /// All data related to abilities. - abilities: AbilityLibrary, + abilities: Box, } -impl StaticData { +impl StaticDataImpl { /// Instantiates a new data collection. - pub fn new(settings: LibrarySettings) -> Self { + pub fn new(settings: Box) -> Self { Self { identifier: Default::default(), settings, - species: SpeciesLibrary::new(0), - moves: MoveLibrary::new(0), - items: ItemLibrary::new(0), - growth_rates: GrowthRateLibrary::new(0), - types: TypeLibrary::new(0), - natures: NatureLibrary::new(0), - abilities: AbilityLibrary::new(0), + species: Box::new(SpeciesLibraryImpl::new(0)), + moves: Box::new(MoveLibraryImpl::new(0)), + items: Box::new(ItemLibraryImpl::new(0)), + growth_rates: Box::new(GrowthRateLibraryImpl::new(0)), + types: Box::new(TypeLibraryImpl::new(0)), + natures: Box::new(NatureLibraryImpl::new(0)), + abilities: Box::new(AbilityLibraryImpl::new(0)), } } +} + +impl StaticData for StaticDataImpl { /// Several misc settings for the library. - pub fn settings(&self) -> &LibrarySettings { + fn settings(&self) -> &Box { &self.settings } /// All data for Pokemon species. - pub fn species(&self) -> &SpeciesLibrary { + fn species(&self) -> &Box { &self.species } /// All data for Pokemon species. - pub fn species_mut(&mut self) -> &mut SpeciesLibrary { + fn species_mut(&mut self) -> &mut Box { &mut self.species } /// All data for the moves. - pub fn moves(&self) -> &MoveLibrary { + fn moves(&self) -> &Box { &self.moves } /// All data for the moves. - pub fn moves_mut(&mut self) -> &mut MoveLibrary { + fn moves_mut(&mut self) -> &mut Box { &mut self.moves } /// All data for the items. - pub fn items(&self) -> &ItemLibrary { + fn items(&self) -> &Box { &self.items } /// All data for the items. - pub fn items_mut(&mut self) -> &mut ItemLibrary { + fn items_mut(&mut self) -> &mut Box { &mut self.items } /// All data for growth rates. - pub fn growth_rates(&self) -> &GrowthRateLibrary { + fn growth_rates(&self) -> &Box { &self.growth_rates } /// All data for growth rates. - pub fn growth_rates_mut(&mut self) -> &mut GrowthRateLibrary { + fn growth_rates_mut(&mut self) -> &mut Box { &mut self.growth_rates } /// All data related to types and type effectiveness. - pub fn types(&self) -> &TypeLibrary { + fn types(&self) -> &Box { &self.types } /// All data related to types and type effectiveness. - pub fn types_mut(&mut self) -> &mut TypeLibrary { + fn types_mut(&mut self) -> &mut Box { &mut self.types } /// All data related to natures. - pub fn natures(&self) -> &NatureLibrary { + fn natures(&self) -> &Box { &self.natures } /// All data related to natures. - pub fn natures_mut(&mut self) -> &mut NatureLibrary { + fn natures_mut(&mut self) -> &mut Box { &mut self.natures } /// All data related to abilities. - pub fn abilities(&self) -> &AbilityLibrary { + fn abilities(&self) -> &Box { &self.abilities } /// All data related to abilities. - pub fn abilities_mut(&mut self) -> &mut AbilityLibrary { + fn abilities_mut(&mut self) -> &mut Box { &mut self.abilities } } -impl ValueIdentifiable for StaticData { +impl ValueIdentifiable for StaticDataImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } @@ -117,23 +156,48 @@ impl ValueIdentifiable for StaticData { #[cfg(test)] pub mod test { - use crate::static_data::libraries::library_settings::LibrarySettings; - use crate::static_data::libraries::static_data::StaticData; - use crate::static_data::libraries::{ - ability_library, growth_rate_library, item_library, move_library, nature_library, species_library, type_library, - }; + use super::*; + use crate::static_data::LibrarySettingsImpl; - pub fn build() -> StaticData { - StaticData { + mockall::mock! { + #[derive(Debug)] + pub StaticData{} + impl StaticData for StaticData { + fn settings(&self) -> &Box; + fn species(&self) -> &Box; + fn species_mut(&mut self) -> &mut Box; + fn moves(&self) -> &Box; + fn moves_mut(&mut self) -> &mut Box; + fn items(&self) -> &Box; + fn items_mut(&mut self) -> &mut Box; + + fn growth_rates(&self) -> & Box; + fn growth_rates_mut(&mut self) -> &mut Box; + fn types(&self) -> &Box; + fn types_mut(&mut self) -> &mut Box; + fn natures(&self) -> &Box; + fn natures_mut(&mut self) -> &mut Box; + fn abilities(&self) -> &Box; + fn abilities_mut(&mut self) -> &mut Box; + } + impl ValueIdentifiable for StaticData { + fn value_identifier(&self) -> ValueIdentifier{ + ValueIdentifier::new(0) + } + } + } + + pub fn build() -> StaticDataImpl { + StaticDataImpl { identifier: Default::default(), - settings: LibrarySettings::new(100), - species: species_library::tests::build(), - moves: move_library::tests::build(), - items: item_library::tests::build(), - growth_rates: growth_rate_library::tests::build(), - types: type_library::tests::build(), - natures: nature_library::tests::build(), - abilities: ability_library::tests::build(), + settings: Box::new(LibrarySettingsImpl::new(100)), + species: crate::static_data::libraries::species_library::tests::build(), + moves: crate::static_data::libraries::move_library::tests::build(), + items: crate::static_data::libraries::item_library::tests::build(), + growth_rates: Box::new(crate::static_data::libraries::growth_rate_library::tests::build()), + types: Box::new(crate::static_data::libraries::type_library::tests::build()), + natures: Box::new(crate::static_data::libraries::nature_library::tests::build()), + abilities: Box::new(crate::static_data::libraries::ability_library::tests::build()), } } } diff --git a/src/static_data/libraries/type_library.rs b/src/static_data/libraries/type_library.rs index 5b52016..cc97ed3 100755 --- a/src/static_data/libraries/type_library.rs +++ b/src/static_data/libraries/type_library.rs @@ -1,5 +1,6 @@ use atomig::Atom; use hashbrown::HashMap; +use std::fmt::Debug; use crate::{StringKey, ValueIdentifiable, ValueIdentifier}; @@ -24,9 +25,32 @@ impl From for u8 { } } +/// All data related to types and effectiveness. +pub trait TypeLibrary: Debug + ValueIdentifiable { + /// Gets the type identifier for a type with a name. + fn get_type_id(&self, key: &StringKey) -> Option; + + /// Gets the type name from the type identifier. + fn get_type_name(&self, t: TypeIdentifier) -> Option; + + /// Gets the effectiveness for a single attacking type against a single defending type. + fn get_single_effectiveness(&self, attacking: TypeIdentifier, defending: TypeIdentifier) -> f32; + + /// Gets the effectiveness for a single attacking type against an amount of defending types. + /// This is equivalent to running [`get_single_effectiveness`] on each defending type, and + /// multiplying the results with each other. + fn get_effectiveness(&self, attacking: TypeIdentifier, defending: &[TypeIdentifier]) -> f32; + + /// Registers a new type in the library. + fn register_type(&mut self, name: &StringKey) -> TypeIdentifier; + + /// Sets the effectiveness for an attacking type against a defending type. + fn set_effectiveness(&mut self, attacking: TypeIdentifier, defending: TypeIdentifier, effectiveness: f32); +} + /// All data related to types and effectiveness. #[derive(Debug)] -pub struct TypeLibrary { +pub struct TypeLibraryImpl { /// A unique identifier so we know what value this is. identifier: ValueIdentifier, /// A list of types @@ -35,23 +59,25 @@ pub struct TypeLibrary { effectiveness: Vec>, } -impl TypeLibrary { +impl TypeLibraryImpl { /// Instantiates a new type library with a specific capacity. - pub fn new(capacity: usize) -> TypeLibrary { - TypeLibrary { + pub fn new(capacity: usize) -> Self { + Self { identifier: Default::default(), types: HashMap::with_capacity(capacity), effectiveness: vec![], } } +} +impl TypeLibrary for TypeLibraryImpl { /// Gets the type identifier for a type with a name. - pub fn get_type_id(&self, key: &StringKey) -> Option { + fn get_type_id(&self, key: &StringKey) -> Option { self.types.get(key).cloned() } /// Gets the type name from the type identifier. - pub fn get_type_name(&self, t: TypeIdentifier) -> Option { + fn get_type_name(&self, t: TypeIdentifier) -> Option { for kv in &self.types { if *kv.1 == t { return Some(kv.0.clone()); @@ -61,14 +87,14 @@ impl TypeLibrary { } /// Gets the effectiveness for a single attacking type against a single defending type. - pub fn get_single_effectiveness(&self, attacking: TypeIdentifier, defending: TypeIdentifier) -> f32 { + fn get_single_effectiveness(&self, attacking: TypeIdentifier, defending: TypeIdentifier) -> f32 { self.effectiveness[(attacking.val - 1) as usize][(defending.val - 1) as usize] } /// Gets the effectiveness for a single attacking type against an amount of defending types. /// This is equivalent to running [`get_single_effectiveness`] on each defending type, and /// multiplying the results with each other. - pub fn get_effectiveness(&self, attacking: TypeIdentifier, defending: &[TypeIdentifier]) -> f32 { + fn get_effectiveness(&self, attacking: TypeIdentifier, defending: &[TypeIdentifier]) -> f32 { let mut e = 1.0; for def in defending { e *= self.get_single_effectiveness(attacking, *def); @@ -77,7 +103,7 @@ impl TypeLibrary { } /// Registers a new type in the library. - pub fn register_type(&mut self, name: &StringKey) -> TypeIdentifier { + fn register_type(&mut self, name: &StringKey) -> TypeIdentifier { let id = TypeIdentifier { val: (self.types.len() + 1) as u8, }; @@ -90,12 +116,12 @@ impl TypeLibrary { } /// Sets the effectiveness for an attacking type against a defending type. - pub fn set_effectiveness(&mut self, attacking: TypeIdentifier, defending: TypeIdentifier, effectiveness: f32) { + fn set_effectiveness(&mut self, attacking: TypeIdentifier, defending: TypeIdentifier, effectiveness: f32) { self.effectiveness[(attacking.val - 1) as usize][(defending.val - 1) as usize] = effectiveness; } } -impl ValueIdentifiable for TypeLibrary { +impl ValueIdentifiable for TypeLibraryImpl { fn value_identifier(&self) -> ValueIdentifier { self.identifier } @@ -105,10 +131,11 @@ impl ValueIdentifiable for TypeLibrary { pub mod tests { use assert_approx_eq::assert_approx_eq; + use super::*; use crate::static_data::libraries::type_library::TypeLibrary; - pub fn build() -> TypeLibrary { - let mut lib = TypeLibrary::new(2); + pub fn build() -> TypeLibraryImpl { + let mut lib = TypeLibraryImpl::new(2); // Borrow as mut so we can insert let w = &mut lib; @@ -124,7 +151,7 @@ pub mod tests { #[test] fn add_two_types_retrieve_them() { - let mut lib = TypeLibrary::new(2); + let mut lib = TypeLibraryImpl::new(2); // Borrow as mut so we can insert let w = &mut lib; @@ -140,7 +167,7 @@ pub mod tests { #[test] fn add_two_types_set_effectiveness_retrieve() { - let mut lib = TypeLibrary::new(2); + let mut lib = TypeLibraryImpl::new(2); // Borrow as mut so we can insert let w = &mut lib; @@ -158,7 +185,7 @@ pub mod tests { #[test] fn add_two_types_get_aggregate_effectiveness() { - let mut lib = TypeLibrary::new(2); + let mut lib = TypeLibraryImpl::new(2); // Borrow as mut so we can insert let w = &mut lib; @@ -176,7 +203,7 @@ pub mod tests { #[test] fn add_two_types_get_type_name() { - let mut lib = TypeLibrary::new(2); + let mut lib = TypeLibraryImpl::new(2); // Borrow as mut so we can insert let w = &mut lib; diff --git a/src/static_data/species_data/form.rs b/src/static_data/species_data/form.rs index 8dd3239..53b8b5a 100755 --- a/src/static_data/species_data/form.rs +++ b/src/static_data/species_data/form.rs @@ -28,7 +28,6 @@ pub trait Form: ValueIdentifiable + Debug { /// The possible hidden abilities a Pokemon with this form can have. fn hidden_abilities(&self) -> &Vec; - #[allow(clippy::borrowed_box)] /// The moves a Pokemon with this form can learn. fn moves(&self) -> &Box; /// Arbitrary flags can be set on a form for scripting use. @@ -146,7 +145,6 @@ impl Form for FormImpl { &self.hidden_abilities } - #[allow(clippy::borrowed_box)] /// The moves a Pokemon with this form can learn. fn moves(&self) -> &Box { &self.moves @@ -233,7 +231,6 @@ pub(crate) mod tests { fn base_stats(&self) -> &StaticStatisticSet; fn abilities(&self) -> &Vec; fn hidden_abilities(&self) -> &Vec; - #[allow(clippy::borrowed_box)] fn moves(&self) -> &Box; fn flags(&self) -> &HashSet; fn get_type(&self, index: usize) -> TypeIdentifier; diff --git a/tests/common/library_loader.rs b/tests/common/library_loader.rs index b6419a3..6c341e1 100755 --- a/tests/common/library_loader.rs +++ b/tests/common/library_loader.rs @@ -10,24 +10,24 @@ use project_root::get_project_root; use serde_json::Value; use pkmn_lib::defines::LevelInt; -use pkmn_lib::dynamic_data::DynamicLibrary; use pkmn_lib::dynamic_data::Gen7BattleStatCalculator; use pkmn_lib::dynamic_data::Gen7DamageLibrary; use pkmn_lib::dynamic_data::Gen7MiscLibrary; +use pkmn_lib::dynamic_data::{DynamicLibrary, DynamicLibraryImpl}; use pkmn_lib::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver; use pkmn_lib::static_data::{ - AbilityImpl, AbilityLibrary, BattleItemCategory, DataLibrary, EffectParameter, Form, FormImpl, GrowthRateLibrary, - ItemImpl, ItemLibrary, LearnableMoves, LearnableMovesImpl, LibrarySettings, LookupGrowthRate, MoveDataImpl, - MoveLibrary, NatureImpl, NatureLibrary, SecondaryEffect, SecondaryEffectImpl, SpeciesImpl, StaticData, - StaticStatisticSet, Statistic, TypeLibrary, + AbilityImpl, AbilityLibrary, BattleItemCategory, EffectParameter, Form, FormImpl, GrowthRateLibrary, ItemImpl, + ItemLibrary, LearnableMoves, LearnableMovesImpl, LibrarySettingsImpl, LookupGrowthRate, MoveDataImpl, MoveLibrary, + NatureImpl, NatureLibrary, SecondaryEffect, SecondaryEffectImpl, SpeciesImpl, StaticData, StaticDataImpl, + StaticStatisticSet, Statistic, TypeLibrary, TypeLibraryImpl, }; use pkmn_lib::StringKey; -pub fn load_library() -> DynamicLibrary { +pub fn load_library() -> Arc { let mut path = get_project_root().unwrap(); path.push("tests/data/"); let path = path.to_str().unwrap().to_string(); - let mut data = StaticData::new(LibrarySettings::new(100)); + let mut data = StaticDataImpl::new(Box::new(LibrarySettingsImpl::new(100))); load_types(&path, data.types_mut()); load_natures(&path, data.natures_mut()); load_items(&path, data.items_mut()); @@ -38,16 +38,16 @@ pub fn load_library() -> DynamicLibrary { let mut resolver = WebAssemblyScriptResolver::new(); load_wasm(&path, resolver.as_mut()); - DynamicLibrary::new( - data, + Arc::new(DynamicLibraryImpl::new( + Box::new(data), Box::new(Gen7BattleStatCalculator::new()), Box::new(Gen7DamageLibrary::new(false)), Box::new(Gen7MiscLibrary::new()), resolver, - ) + )) } -pub fn load_types(path: &String, type_library: &mut TypeLibrary) { +pub fn load_types(path: &String, type_library: &mut Box) { let mut reader = csv::ReaderBuilder::new() .delimiter(b'|') .from_path(path.to_string() + "Types.csv") @@ -69,7 +69,7 @@ pub fn load_types(path: &String, type_library: &mut TypeLibrary) { } } -pub fn load_natures(path: &String, nature_library: &mut NatureLibrary) { +pub fn load_natures(path: &String, nature_library: &mut Box) { let mut reader = csv::ReaderBuilder::new() .delimiter(b'|') .from_path(path.to_string() + "Natures.csv") @@ -93,7 +93,7 @@ pub fn load_natures(path: &String, nature_library: &mut NatureLibrary) { } } -pub fn load_items(path: &String, lib: &mut ItemLibrary) { +pub fn load_items(path: &String, lib: &mut Box) { let mut file = File::open(path.to_string() + "Items.json").unwrap(); let mut data = String::new(); file.read_to_string(&mut data).unwrap(); @@ -123,7 +123,7 @@ pub fn load_items(path: &String, lib: &mut ItemLibrary) { } } -pub fn load_growth_rates(path: &String, growth_rate_library: &mut GrowthRateLibrary) { +pub fn load_growth_rates(path: &String, growth_rate_library: &mut Box) { let mut file = File::open(path.to_string() + "GrowthRates.json").unwrap(); let mut data = String::new(); file.read_to_string(&mut data).unwrap(); @@ -142,7 +142,7 @@ pub fn load_growth_rates(path: &String, growth_rate_library: &mut GrowthRateLibr } } -pub fn load_abilities(path: &String, ability_library: &mut AbilityLibrary) { +pub fn load_abilities(path: &String, ability_library: &mut Box) { let mut file = File::open(path.to_string() + "Abilities.json").unwrap(); let mut data = String::new(); file.read_to_string(&mut data).unwrap(); @@ -166,7 +166,7 @@ pub fn load_abilities(path: &String, ability_library: &mut AbilityLibrary) { } } -pub fn load_moves(path: &String, lib: &mut StaticData) { +pub fn load_moves(path: &String, lib: &mut dyn StaticData) { let mut file = File::open(path.to_string() + "Moves.json").unwrap(); let mut data = String::new(); file.read_to_string(&mut data).unwrap(); @@ -231,7 +231,7 @@ pub fn load_moves(path: &String, lib: &mut StaticData) { } } -pub fn load_species(path: &String, library: &mut StaticData) { +pub fn load_species(path: &String, library: &mut dyn StaticData) { let mut file = File::open(path.to_string() + "Pokemon.json").unwrap(); let mut data = String::new(); file.read_to_string(&mut data).unwrap(); @@ -285,7 +285,7 @@ fn load_wasm(path: &String, library: &mut WebAssemblyScriptResolver) { library.finalize(); } -fn parse_form(name: StringKey, value: &Value, library: &mut StaticData) -> Arc { +fn parse_form(name: StringKey, value: &Value, library: &mut dyn StaticData) -> Arc { let mut abilities = Vec::new(); for a in value.get("abilities").unwrap().as_array().unwrap() { abilities.push(a.as_str().unwrap().into()); @@ -308,7 +308,7 @@ fn parse_form(name: StringKey, value: &Value, library: &mut StaticData) -> Arc Box { +fn parse_moves(value: &Value, move_library: &mut Box) -> Box { let mut moves = LearnableMovesImpl::default(); let level_moves = value.get("levelMoves").unwrap().as_array().unwrap(); @@ -410,7 +410,7 @@ fn parse_effect_parameter(value: &Value) -> EffectParameter { fn test_type_library_loaded() { let mut path = get_project_root().unwrap(); path.push("tests/data/"); - let mut lib = TypeLibrary::new(18); + let mut lib: Box = Box::new(TypeLibraryImpl::new(18)); load_types(&path.to_str().unwrap().to_string(), &mut lib); assert_eq!( diff --git a/tests/common/test_case.rs b/tests/common/test_case.rs index 030afa1..01ca3de 100755 --- a/tests/common/test_case.rs +++ b/tests/common/test_case.rs @@ -43,7 +43,7 @@ struct TestPokemon { } impl TestCase { - pub fn run_test(&self, library: Arc) { + pub fn run_test(&self, library: Arc) { let mut parties = Vec::new(); for party in &self.battle_setup.parties { let pokemon = party @@ -73,7 +73,7 @@ impl TestCase { } impl TestPokemon { - fn to_pokemon(&self, library: Arc) -> Pokemon { + fn to_pokemon(&self, library: Arc) -> Pokemon { 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 12e0939..477ebd2 100755 --- a/tests/main.rs +++ b/tests/main.rs @@ -17,8 +17,8 @@ use crate::common::{library_loader, TestCase}; pub mod common; -fn get_library() -> Arc { - Arc::new(library_loader::load_library()) +fn get_library() -> Arc { + library_loader::load_library() } #[test]