Moves a bunch of libraries to traits
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2022-12-24 12:00:50 +01:00
parent bce636b97e
commit 47df85e8d3
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
47 changed files with 730 additions and 358 deletions

View File

@ -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]

View File

@ -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 {

View File

@ -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<u32>);
fn calculate_flat_stat(&self, pokemon: &Pokemon, stat: Statistic) -> u32;
fn calculate_boosted_stats(&self, pokemon: &Pokemon, stats: &StatisticSet<u32>);
fn calculate_boosted_stat(&self, pokemon: &Pokemon, stat: Statistic) -> u32;
}
impl ValueIdentifiable for BattleStatCalculator {
fn value_identifier(&self) -> ValueIdentifier{
ValueIdentifier::new(0)
}
}
}
}

View File

@ -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<dyn StaticData>;
/// 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<Option<Arc<dyn Script>>>;
/// 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<dyn Item>) -> PkmnResult<Option<Arc<dyn ItemScript>>>;
}
/// 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<dyn StaticData>,
/// The stat calculator deals with the calculation of flat and boosted stats, based on the
/// Pokemons attributes.
stat_calculator: Box<dyn BattleStatCalculator>,
@ -32,13 +61,10 @@ pub struct DynamicLibrary {
script_resolver: Box<dyn ScriptResolver>,
}
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<dyn StaticData>,
stat_calculator: Box<dyn BattleStatCalculator>,
damage_calculator: Box<dyn DamageLibrary>,
misc_library: Box<dyn MiscLibrary>,
@ -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<dyn StaticData> {
&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<dyn Item>) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
fn load_item_script(&self, _key: &Arc<dyn Item>) -> PkmnResult<Option<Arc<dyn ItemScript>>> {
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<dyn StaticData>;
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<Option<Arc<dyn Script>>>;
fn load_item_script(&self, _key: &Arc<dyn Item>) -> PkmnResult<Option<Arc<dyn ItemScript>>>;
}
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()),

View File

@ -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,

View File

@ -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<DynamicLibrary>,
library: Arc<dyn DynamicLibrary>,
/// A list of all different parties in the battle.
parties: Vec<BattleParty>,
/// 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<DynamicLibrary>,
library: Arc<dyn DynamicLibrary>,
parties: Vec<BattleParty>,
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<DynamicLibrary> {
pub fn library(&self) -> &Arc<dyn DynamicLibrary> {
&self.library
}
/// A list of all different parties in the battle.

View File

@ -33,12 +33,13 @@ pub enum MoveLearnMethod {
impl LearnedMove {
/// Instantiate a new learned move.
pub fn new(move_data: &Arc<dyn MoveData>, learn_method: MoveLearnMethod) -> Self {
pub fn new(move_data: Arc<dyn MoveData>, 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<dyn MoveData> = 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());

View File

@ -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<DynamicLibrary>,
library: Arc<dyn DynamicLibrary>,
/// The species of the Pokemon.
species: RwLock<Arc<dyn Species>>,
/// The form of the Pokemon.
@ -120,7 +120,7 @@ pub struct Pokemon {
impl Pokemon {
/// Instantiates a new Pokemon.
pub fn new(
library: Arc<DynamicLibrary>,
library: Arc<dyn DynamicLibrary>,
species: Arc<dyn Species>,
form: &Arc<dyn Form>,
ability: AbilityIndex,
@ -188,7 +188,7 @@ impl Pokemon {
}
/// The library data of the Pokemon.
pub fn library(&self) -> &Arc<DynamicLibrary> {
pub fn library(&self) -> &Arc<dyn DynamicLibrary> {
&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<dyn Ability> {
pub fn active_ability(&self) -> Arc<dyn Ability> {
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<dyn DynamicLibrary> {
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<dyn Form> = 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<dyn Species> = 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());
}
}

View File

@ -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<DynamicLibrary>,
library: Arc<dyn DynamicLibrary>,
/// 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<DynamicLibrary>, species: StringKey, level: LevelInt) -> Self {
pub fn new(library: Arc<dyn DynamicLibrary>, species: StringKey, level: LevelInt) -> Self {
Self {
library,
species,

View File

@ -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<EffectParameter>) {}
fn on_initialize(&self, _library: &Arc<dyn DynamicLibrary>, _pars: Vec<EffectParameter>) {}
/// 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.

View File

@ -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<StaticData>,
static_data: OwnedPtr<Box<dyn StaticData>>,
stat_calculator: OwnedPtr<Box<dyn BattleStatCalculator>>,
damage_library: OwnedPtr<Box<dyn DamageLibrary>>,
misc_library: OwnedPtr<Box<dyn MiscLibrary>>,
script_resolver: OwnedPtr<Box<dyn ScriptResolver>>,
) -> IdentifiablePointer<Arc<DynamicLibrary>> {
) -> IdentifiablePointer<Arc<dyn DynamicLibrary>> {
unsafe {
Arc::new(DynamicLibrary::new(
let a: Arc<dyn DynamicLibrary> = 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()
}
}

View File

@ -9,7 +9,7 @@ use std::sync::Arc;
/// Initializes a new battle.
#[no_mangle]
extern "C" fn battle_new(
library: ExternPointer<Arc<DynamicLibrary>>,
library: ExternPointer<Arc<dyn DynamicLibrary>>,
parties: *const OwnedPtr<BattleParty>,
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<Arc<Battle>>) -> IdentifiablePointer<Arc<DynamicLibrary>> {
extern "C" fn battle_library(ptr: ExternPointer<Arc<Battle>>) -> IdentifiablePointer<Arc<dyn DynamicLibrary>> {
ptr.as_ref().library().clone().into()
}

View File

@ -10,7 +10,7 @@ extern "C" fn learned_move_new(
move_data: ExternPointer<Arc<dyn MoveData>>,
learn_method: MoveLearnMethod,
) -> IdentifiablePointer<Arc<LearnedMove>> {
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.

View File

@ -11,7 +11,7 @@ use std::sync::Arc;
/// Instantiates a new Pokemon.
#[no_mangle]
extern "C" fn pokemon_new(
library: ExternPointer<Arc<DynamicLibrary>>,
library: ExternPointer<Arc<dyn DynamicLibrary>>,
species: ExternPointer<Arc<dyn Species>>,
form: ExternPointer<Arc<dyn Form>>,
hidden_ability: bool,
@ -48,7 +48,7 @@ unsafe extern "C" fn pokemon_drop(ptr: OwnedPtr<Arc<Pokemon>>) {
/// The library data of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_library(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<DynamicLibrary>> {
extern "C" fn pokemon_library(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<dyn DynamicLibrary>> {
ptr.as_ref().library().clone().into()
}

View File

@ -163,6 +163,16 @@ impl<T: ValueIdentifiable + ?Sized> From<Box<T>> for IdentifiablePointer<Box<T>>
}
}
impl<T: ValueIdentifiable + ?Sized> From<&Box<T>> for IdentifiablePointer<Box<T>> {
fn from(v: &Box<T>) -> Self {
let id = unsafe { transmute(v.value_identifier()) };
Self {
ptr: v as *const Box<T>,
id,
}
}
}
impl<T: ValueIdentifiable + ?Sized> From<Option<Box<T>>> for IdentifiablePointer<Box<T>> {
fn from(v: Option<Box<T>>) -> Self {
if let Some(v) = v {

View File

@ -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<GrowthRateLibrary> {
Box::new(GrowthRateLibrary::new(capacity)).into()
extern "C" fn growth_rate_library_new(capacity: usize) -> IdentifiablePointer<Box<dyn GrowthRateLibrary>> {
let b: Box<dyn GrowthRateLibrary> = Box::new(GrowthRateLibraryImpl::new(capacity));
b.into()
}
/// Drops the growthrate library.
#[no_mangle]
unsafe extern "C" fn growth_rate_library_drop(ptr: OwnedPtr<GrowthRateLibrary>) {
unsafe extern "C" fn growth_rate_library_drop(ptr: OwnedPtr<Box<dyn GrowthRateLibrary>>) {
drop_in_place(ptr)
}
/// Calculates the level for a given growth key name and a certain experience.
#[no_mangle]
unsafe extern "C" fn growth_rate_library_calculate_level(
ptr: ExternPointer<GrowthRateLibrary>,
ptr: ExternPointer<Box<dyn GrowthRateLibrary>>,
growth_rate: BorrowedPtr<c_char>,
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<GrowthRateLibrary>,
ptr: ExternPointer<Box<dyn GrowthRateLibrary>>,
growth_rate: BorrowedPtr<c_char>,
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<GrowthRateLibrary>,
mut ptr: ExternPointer<Box<dyn GrowthRateLibrary>>,
name: BorrowedPtr<c_char>,
growth_rate: OwnedPtr<Box<dyn GrowthRate>>,
) {

View File

@ -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<LibrarySettings> {
Box::new(LibrarySettings::new(max_level)).into()
extern "C" fn library_settings_new(max_level: LevelInt) -> IdentifiablePointer<Box<dyn LibrarySettings>> {
let b: Box<dyn LibrarySettings> = Box::new(LibrarySettingsImpl::new(max_level));
b.into()
}
/// Drop a library settings object.
#[no_mangle]
unsafe extern "C" fn library_settings_drop(ptr: OwnedPtr<LibrarySettings>) {
unsafe extern "C" fn library_settings_drop(ptr: OwnedPtr<Box<dyn LibrarySettings>>) {
drop_in_place(ptr)
}
/// The highest level a Pokemon can be.
#[no_mangle]
extern "C" fn library_settings_maximum_level(ptr: ExternPointer<LibrarySettings>) -> LevelInt {
extern "C" fn library_settings_maximum_level(ptr: ExternPointer<Box<dyn LibrarySettings>>) -> LevelInt {
ptr.as_ref().maximum_level()
}

View File

@ -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<c_char>, value: OwnedPtr<Arc<$return_type>>) {
unsafe extern "C" fn [< $library_type_name:snake _add >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr<c_char>, value: OwnedPtr<Arc<$return_type>>) {
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<c_char>) {
unsafe extern "C" fn [< $library_type_name:snake _remove >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr<c_char>) {
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<c_char>) -> IdentifiablePointer<Arc<$return_type>> {
unsafe extern "C" fn [< $library_type_name:snake _get >](ptr: OwnedPtr<$library_type>, key: BorrowedPtr<c_char>) -> IdentifiablePointer<Arc<$return_type>> {
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<c_char> {
unsafe extern "C" fn [< $library_type_name:snake _get_key_by_index >](ptr: OwnedPtr<$library_type>, index: usize) -> OwnedPtr<c_char> {
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 SpeciesLibrary>, dyn Species);
library_interface!(MoveLibrary, Box<dyn MoveLibrary>, dyn MoveData);
library_interface!(AbilityLibrary, Box<dyn AbilityLibrary>, dyn Ability);
library_interface!(ItemLibrary, Box<dyn ItemLibrary>, dyn Item);

View File

@ -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<NatureLibrary> {
Box::new(NatureLibrary::new(capacity)).into()
extern "C" fn nature_library_new(capacity: usize) -> IdentifiablePointer<Box<dyn NatureLibrary>> {
let b: Box<dyn NatureLibrary> = Box::new(NatureLibraryImpl::new(capacity));
b.into()
}
/// Drop a nature library.
#[no_mangle]
unsafe extern "C" fn nature_library_drop(ptr: OwnedPtr<NatureLibrary>) {
unsafe extern "C" fn nature_library_drop(ptr: OwnedPtr<Box<dyn NatureLibrary>>) {
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<NatureLibrary>,
mut ptr: ExternPointer<Box<dyn NatureLibrary>>,
name: BorrowedPtr<c_char>,
nature: OwnedPtr<Arc<dyn Nature>>,
) {
@ -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<NatureLibrary>,
ptr: ExternPointer<Box<dyn NatureLibrary>>,
name: BorrowedPtr<c_char>,
) -> IdentifiablePointer<Arc<dyn Nature>> {
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<NatureLibrary>,
ptr: ExternPointer<Box<dyn NatureLibrary>>,
nature: BorrowedPtr<Arc<dyn Nature>>,
) -> OwnedPtr<c_char> {
CString::new(ptr.as_ref().get_nature_name(nature.as_ref().unwrap()).str())

View File

@ -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<LibrarySettings>) -> IdentifiablePointer<StaticData> {
Box::new(StaticData::new(*Box::from_raw(settings))).into()
unsafe extern "C" fn static_data_new(
settings: OwnedPtr<Box<dyn LibrarySettings>>,
) -> IdentifiablePointer<Box<dyn StaticData>> {
let b: Box<dyn StaticData> = 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<StaticData>) {
unsafe extern "C" fn static_data_drop(ptr: OwnedPtr<Box<dyn StaticData>>) {
drop_in_place(ptr)
}
/// Several misc settings for the library.
#[no_mangle]
unsafe extern "C" fn static_data_settings(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<LibrarySettings> {
(data.as_mut().settings() as *const LibrarySettings).into()
unsafe extern "C" fn static_data_settings(
mut data: ExternPointer<Box<dyn StaticData>>,
) -> IdentifiablePointer<Box<dyn LibrarySettings>> {
data.as_mut().settings().into()
}
/// All data for Pokemon species.
#[no_mangle]
unsafe extern "C" fn static_data_species(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<SpeciesLibrary> {
(data.as_mut().species_mut() as *const SpeciesLibrary).into()
unsafe extern "C" fn static_data_species(
mut data: ExternPointer<Box<dyn StaticData>>,
) -> IdentifiablePointer<Box<dyn SpeciesLibrary>> {
data.as_mut().species().into()
}
/// All data for the moves.
#[no_mangle]
unsafe extern "C" fn static_data_moves(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<MoveLibrary> {
(data.as_mut().moves_mut() as *const MoveLibrary).into()
unsafe extern "C" fn static_data_moves(
mut data: ExternPointer<Box<dyn StaticData>>,
) -> IdentifiablePointer<Box<dyn MoveLibrary>> {
data.as_mut().moves().into()
}
/// All data for the items.
#[no_mangle]
unsafe extern "C" fn static_data_items(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<ItemLibrary> {
(data.as_mut().items_mut() as *const ItemLibrary).into()
unsafe extern "C" fn static_data_items(
mut data: ExternPointer<Box<dyn StaticData>>,
) -> IdentifiablePointer<Box<dyn ItemLibrary>> {
(data.as_mut().items()).into()
}
/// All data for growth rates.
#[no_mangle]
unsafe extern "C" fn static_data_growth_rates(
mut data: ExternPointer<StaticData>,
) -> IdentifiablePointer<GrowthRateLibrary> {
(data.as_mut().growth_rates_mut() as *const GrowthRateLibrary).into()
mut data: ExternPointer<Box<dyn StaticData>>,
) -> IdentifiablePointer<Box<dyn GrowthRateLibrary>> {
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<StaticData>) -> IdentifiablePointer<TypeLibrary> {
(data.as_mut().types_mut() as *const TypeLibrary).into()
unsafe extern "C" fn static_data_types(
mut data: ExternPointer<Box<dyn StaticData>>,
) -> IdentifiablePointer<Box<dyn TypeLibrary>> {
data.as_mut().types().into()
}
/// All data related to natures.
#[no_mangle]
unsafe extern "C" fn static_data_natures(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<NatureLibrary> {
(data.as_mut().natures_mut() as *const NatureLibrary).into()
unsafe extern "C" fn static_data_natures(
data: ExternPointer<Box<dyn StaticData>>,
) -> IdentifiablePointer<Box<dyn NatureLibrary>> {
data.as_ref().natures().into()
}
/// All data related to abilities.
#[no_mangle]
unsafe extern "C" fn static_data_abilities(mut data: ExternPointer<StaticData>) -> IdentifiablePointer<AbilityLibrary> {
(data.as_mut().abilities_mut() as *const AbilityLibrary).into()
unsafe extern "C" fn static_data_abilities(
mut data: ExternPointer<Box<dyn StaticData>>,
) -> IdentifiablePointer<Box<dyn AbilityLibrary>> {
(data.as_mut().abilities()).into()
}

View File

@ -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<TypeLibrary> {
Box::new(TypeLibrary::new(capacity)).into()
extern "C" fn type_library_new(capacity: usize) -> IdentifiablePointer<Box<dyn TypeLibrary>> {
let b: Box<dyn TypeLibrary> = Box::new(TypeLibraryImpl::new(capacity));
b.into()
}
/// Drops a type library.
#[no_mangle]
unsafe extern "C" fn type_library_drop(ptr: OwnedPtr<TypeLibrary>) {
unsafe extern "C" fn type_library_drop(ptr: OwnedPtr<Box<dyn TypeLibrary>>) {
drop_in_place(ptr);
}
/// Gets the type identifier for a type with a name.
#[no_mangle]
unsafe extern "C" fn type_library_get_type_id(
ptr: ExternPointer<TypeLibrary>,
ptr: ExternPointer<Box<dyn TypeLibrary>>,
key: BorrowedPtr<c_char>,
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<TypeLibrary>,
ptr: ExternPointer<Box<dyn TypeLibrary>>,
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<TypeLibrary>,
ptr: ExternPointer<Box<dyn TypeLibrary>>,
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<TypeLibrary>,
ptr: ExternPointer<Box<dyn TypeLibrary>>,
attacking: TypeIdentifier,
defending: OwnedPtr<TypeIdentifier>,
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<TypeLibrary>,
mut ptr: ExternPointer<Box<dyn TypeLibrary>>,
name: BorrowedPtr<c_char>,
) -> 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<TypeLibrary>,
mut ptr: ExternPointer<Box<dyn TypeLibrary>>,
attacking: TypeIdentifier,
defending: TypeIdentifier,
effectiveness: f32,

View File

@ -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)]

View File

@ -37,8 +37,8 @@ register! {
fn battle_get_library(
env: FunctionEnvMut<WebAssemblyEnv>,
battle: ExternRef<Battle>,
) -> ExternRef<DynamicLibrary> {
ExternRef::func_new(&env, battle.value_func(&env).unwrap().library().as_ref())
) -> ExternRef<dyn DynamicLibrary> {
ExternRef::func_new(&env, &battle.value_func_arc(&env).unwrap().library().clone())
}
fn battle_get_sides(

View File

@ -31,9 +31,9 @@ mod turn_choice;
register! {
fn dynamic_library_get_static_data(
env: FunctionEnvMut<WebAssemblyEnv>,
dynamic_lib: ExternRef<DynamicLibrary>,
) -> ExternRef<StaticData> {
ExternRef::func_new(&env, dynamic_lib.value_func(&env).unwrap().static_data())
dynamic_lib: ExternRef<dyn DynamicLibrary>,
) -> ExternRef<dyn StaticData> {
ExternRef::func_new(&env, dynamic_lib.value_func_arc(&env).unwrap().static_data())
}
fn script_get_owner(

View File

@ -15,9 +15,9 @@ register! {
fn pokemon_get_library(
env: FunctionEnvMut<WebAssemblyEnv>,
pokemon: ExternRef<Pokemon>,
) -> ExternRef<DynamicLibrary> {
let lib = pokemon.value_func(&env).unwrap().library().as_ref();
ExternRef::func_new(&env, lib)
) -> ExternRef<dyn DynamicLibrary> {
let lib = pokemon.value_func(&env).unwrap().library().clone();
ExternRef::func_new(&env, &lib)
}
fn pokemon_get_boosted_stats(

View File

@ -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<WebAssemblyEnv>,
lib: ExternRef<ItemLibrary>,
lib: ExternRef<dyn ItemLibrary>,
string_key: ExternRef<StringKey>,
) -> ExternRef<dyn Item> {
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<WebAssemblyEnv>, lib: ExternRef<ItemLibrary>, hash: u32) -> ExternRef<dyn Item> {
let lib = lib.value_func(&env).unwrap();
fn item_library_get_item_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, lib: ExternRef<dyn ItemLibrary>, hash: u32) -> ExternRef<dyn Item> {
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()
}

View File

@ -17,34 +17,34 @@ mod moves;
mod species;
register! {
fn static_data_get_move_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<StaticData>) -> ExternRef<MoveLibrary> {
ExternRef::func_new(&env, data_library.value_func(&env).unwrap().moves())
fn static_data_get_move_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn StaticData>) -> ExternRef<dyn MoveLibrary> {
ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().moves())
}
fn static_data_get_species_library(
env: FunctionEnvMut<WebAssemblyEnv>,
data_library: ExternRef<StaticData>,
) -> ExternRef<SpeciesLibrary> {
ExternRef::func_new(&env, data_library.value_func(&env).unwrap().species())
data_library: ExternRef<dyn StaticData>,
) -> ExternRef<dyn SpeciesLibrary> {
ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().species())
}
fn static_data_get_item_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<StaticData>) -> ExternRef<ItemLibrary> {
ExternRef::func_new(&env, data_library.value_func(&env).unwrap().items())
fn static_data_get_item_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn StaticData>) -> ExternRef<dyn ItemLibrary> {
ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().items())
}
fn static_data_get_type_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<StaticData>) -> ExternRef<TypeLibrary> {
ExternRef::func_new(&env, data_library.value_func(&env).unwrap().types())
fn static_data_get_type_library(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn StaticData>) -> ExternRef<dyn TypeLibrary> {
ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().types())
}
fn static_data_get_library_settings(
env: FunctionEnvMut<WebAssemblyEnv>,
data_library: ExternRef<StaticData>,
) -> ExternRef<LibrarySettings> {
ExternRef::func_new(&env, data_library.value_func(&env).unwrap().settings())
data_library: ExternRef<dyn StaticData>,
) -> ExternRef<dyn LibrarySettings> {
ExternRef::func_new(&env, data_library.value_func_box(&env).unwrap().settings())
}
fn library_settings_get_maximum_level(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<LibrarySettings>) -> LevelInt {
data_library.value_func(&env).unwrap().maximum_level()
fn library_settings_get_maximum_level(env: FunctionEnvMut<WebAssemblyEnv>, data_library: ExternRef<dyn LibrarySettings>) -> LevelInt {
data_library.value_func_box(&env).unwrap().maximum_level()
}
fn statistic_set_get(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8) -> i64 {

View File

@ -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<WebAssemblyEnv>,
lib: ExternRef<MoveLibrary>,
lib: ExternRef<dyn MoveLibrary>,
string_key: ExternRef<StringKey>,
) -> ExternRef<dyn MoveData> {
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<WebAssemblyEnv>, lib: ExternRef<MoveLibrary>, hash: u32) -> ExternRef<dyn MoveData> {
let lib = lib.value_func(&env).unwrap();
fn move_library_get_move_by_hash(env: FunctionEnvMut<WebAssemblyEnv>, lib: ExternRef<dyn MoveLibrary>, hash: u32) -> ExternRef<dyn MoveData> {
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()
}

View File

@ -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<WebAssemblyEnv>,
lib: ExternRef<SpeciesLibrary>,
lib: ExternRef<dyn SpeciesLibrary>,
string_key: ExternRef<StringKey>,
) -> ExternRef<dyn Species> {
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()
}

View File

@ -74,6 +74,15 @@ impl<T: ValueIdentifiable + ?Sized> ExternRef<T> {
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<WebAssemblyEnv>) -> Option<&Box<T>>
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<WebAssemblyEnvironmentData>) -> Option<&'c T>
@ -93,6 +102,15 @@ impl<T: ValueIdentifiable + ?Sized> ExternRef<T> {
.downcast_ref::<Arc<T>>()
.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<WebAssemblyEnvironmentData>) -> Option<&Box<T>>
where
T: 'static,
{
env.get_extern_ref_value::<T>(self.index).downcast_ref::<Box<T>>()
}
}
unsafe impl<T: ?Sized> FromToNativeWasmType for ExternRef<T> {

View File

@ -125,7 +125,7 @@ impl Script for WebAssemblyScript {
}
}
fn on_initialize(&self, library: &DynamicLibrary, pars: Vec<EffectParameter>) {
fn on_initialize(&self, library: &Arc<dyn DynamicLibrary>, pars: Vec<EffectParameter>) {
if !self.has_capability(&WebAssemblyScriptCapabilities::Initialize) {
return;
}

View File

@ -117,7 +117,7 @@ unsafe impl<T> FromToNativeWasmType for WasmPtr<T> {
script_function_cache! {
stack()
on_remove()
on_initialize(ExternRef<DynamicLibrary>, VecExternRef<EffectParameter>)
on_initialize(ExternRef<dyn DynamicLibrary>, VecExternRef<EffectParameter>)
on_before_turn(ExternRef<TurnChoice>)
change_speed(ExternRef<TurnChoice>, WasmPtr<u32>)
change_priority(ExternRef<TurnChoice>, WasmPtr<i8>)

View File

@ -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<dyn Ability> + 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<StringKey, Arc<dyn Ability>>,
}
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<dyn Ability> for AbilityLibrary {
impl AbilityLibrary for AbilityLibraryImpl {}
impl DataLibrary<dyn Ability> for AbilityLibraryImpl {
fn map(&self) -> &IndexMap<StringKey, Arc<dyn Ability>> {
&self.map
}
@ -34,7 +40,7 @@ impl DataLibrary<dyn Ability> 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(

View File

@ -24,13 +24,13 @@ pub trait DataLibrary<T: ?Sized> {
}
/// Gets a value from the library.
fn get(&self, key: &StringKey) -> Option<&Arc<T>> {
self.map().get::<StringKey>(key)
fn get(&self, key: &StringKey) -> Option<Arc<T>> {
self.map().get::<StringKey>(key).cloned()
}
/// Gets a value from the library.
fn get_by_hash(&self, key: u32) -> Option<&Arc<T>> {
self.map().get::<u32>(&key)
fn get_by_hash(&self, key: u32) -> Option<Arc<T>> {
self.map().get::<u32>(&key).cloned()
}
/// Gets a value from the library by the index where it is stored.

View File

@ -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<dyn GrowthRate>);
}
/// 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<StringKey, Box<dyn GrowthRate>>,
}
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<dyn GrowthRate>) {
fn add_growth_rate(&mut self, key: &StringKey, value: Box<dyn GrowthRate>) {
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<dyn GrowthRate>);
}
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();

View File

@ -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<dyn Item> + 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<StringKey, Arc<dyn Item>>,
}
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<dyn Item> for ItemLibrary {
impl ItemLibrary for ItemLibraryImpl {}
impl DataLibrary<dyn Item> for ItemLibraryImpl {
fn map(&self) -> &IndexMap<StringKey, Arc<dyn Item>> {
&self.map
}
@ -36,7 +41,7 @@ impl DataLibrary<dyn Item> 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<dyn ItemLibrary> {
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)
}
}

View File

@ -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
}

View File

@ -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;

View File

@ -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<dyn MoveData> + 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<StringKey, Arc<dyn MoveData>>,
}
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<dyn MoveData> for MoveLibrary {
impl MoveLibrary for MoveLibraryImpl {}
impl DataLibrary<dyn MoveData> for MoveLibraryImpl {
fn map(&self) -> &IndexMap<StringKey, Arc<dyn MoveData>> {
&self.map
}
@ -35,7 +40,7 @@ impl DataLibrary<dyn MoveData> 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<dyn MoveLibrary> {
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)
}
}

View File

@ -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<dyn Nature>);
/// Gets a nature by name.
fn get_nature(&self, key: &StringKey) -> Option<Arc<dyn Nature>>;
/// Finds a nature name by nature.
fn get_nature_name(&self, nature: &Arc<dyn Nature>) -> 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<StringKey, Arc<dyn Nature>>,
}
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<dyn Nature>) {
fn load_nature(&mut self, name: StringKey, nature: Arc<dyn Nature>) {
self.map.insert(name, nature);
}
/// Gets a nature by name.
pub fn get_nature(&self, key: &StringKey) -> Option<&Arc<dyn Nature>> {
self.map.get(key)
fn get_nature(&self, key: &StringKey) -> Option<Arc<dyn Nature>> {
self.map.get(key).cloned()
}
/// Finds a nature name by nature.
pub fn get_nature_name(&self, nature: &Arc<dyn Nature>) -> StringKey {
fn get_nature_name(&self, nature: &Arc<dyn Nature>) -> 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<dyn Nature>);
fn get_nature(&self, key: &StringKey) -> Option<Arc<dyn Nature>>;
fn get_nature_name(&self, nature: &Arc<dyn Nature>) -> 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());
}
}

View File

@ -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<dyn Species> + 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<StringKey, Arc<dyn Species>>,
}
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<dyn Species> for SpeciesLibrary {
impl SpeciesLibrary for SpeciesLibraryImpl {}
impl DataLibrary<dyn Species> for SpeciesLibraryImpl {
fn map(&self) -> &IndexMap<StringKey, Arc<dyn Species>> {
&self.map
}
@ -35,7 +40,7 @@ impl DataLibrary<dyn Species> 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<dyn Species> for SpeciesLibrary {
fn get<'a, 'b>(&'a self, key: &'b StringKey) -> Option<Arc<dyn Species>> ;
fn get_by_hash<'a>(&'a self, key: u32) -> Option<Arc<dyn Species>>;
fn map(&self) -> &IndexMap<StringKey, Arc<dyn Species>>;
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<dyn Species>>;
}
impl ValueIdentifiable for SpeciesLibrary {
fn value_identifier(&self) -> ValueIdentifier{
ValueIdentifier::new(0)
}
}
}
fn build_species() -> Arc<dyn Species> {
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<dyn SpeciesLibrary> {
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);
}

View File

@ -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<dyn LibrarySettings>;
/// All data for Pokemon species.
fn species(&self) -> &Box<dyn SpeciesLibrary>;
/// All data for Pokemon species.
fn species_mut(&mut self) -> &mut Box<dyn SpeciesLibrary>;
/// All data for the moves.
fn moves(&self) -> &Box<dyn MoveLibrary>;
/// All data for the moves.
fn moves_mut(&mut self) -> &mut Box<dyn MoveLibrary>;
/// All data for the items.
fn items(&self) -> &Box<dyn ItemLibrary>;
/// All data for the items.
fn items_mut(&mut self) -> &mut Box<dyn ItemLibrary>;
/// All data for growth rates.
fn growth_rates(&self) -> &Box<dyn GrowthRateLibrary>;
/// All data for growth rates.
fn growth_rates_mut(&mut self) -> &mut Box<dyn GrowthRateLibrary>;
/// All data related to types and type effectiveness.
fn types(&self) -> &Box<dyn TypeLibrary>;
/// All data related to types and type effectiveness.
fn types_mut(&mut self) -> &mut Box<dyn TypeLibrary>;
/// All data related to natures.
fn natures(&self) -> &Box<dyn NatureLibrary>;
/// All data related to natures.
fn natures_mut(&mut self) -> &mut Box<dyn NatureLibrary>;
/// All data related to abilities.
fn abilities(&self) -> &Box<dyn AbilityLibrary>;
/// All data related to abilities.
fn abilities_mut(&mut self) -> &mut Box<dyn AbilityLibrary>;
}
/// 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<dyn LibrarySettings>,
/// All data for Pokemon species.
species: SpeciesLibrary,
species: Box<dyn SpeciesLibrary>,
/// All data for the moves.
moves: MoveLibrary,
moves: Box<dyn MoveLibrary>,
/// All data for the items.
items: ItemLibrary,
items: Box<dyn ItemLibrary>,
/// All data for growth rates.
growth_rates: GrowthRateLibrary,
growth_rates: Box<dyn GrowthRateLibrary>,
/// All data related to types and type effectiveness.
types: TypeLibrary,
types: Box<dyn TypeLibrary>,
/// All data related to natures.
natures: NatureLibrary,
natures: Box<dyn NatureLibrary>,
/// All data related to abilities.
abilities: AbilityLibrary,
abilities: Box<dyn AbilityLibrary>,
}
impl StaticData {
impl StaticDataImpl {
/// Instantiates a new data collection.
pub fn new(settings: LibrarySettings) -> Self {
pub fn new(settings: Box<dyn LibrarySettings>) -> 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<dyn LibrarySettings> {
&self.settings
}
/// All data for Pokemon species.
pub fn species(&self) -> &SpeciesLibrary {
fn species(&self) -> &Box<dyn SpeciesLibrary> {
&self.species
}
/// All data for Pokemon species.
pub fn species_mut(&mut self) -> &mut SpeciesLibrary {
fn species_mut(&mut self) -> &mut Box<dyn SpeciesLibrary> {
&mut self.species
}
/// All data for the moves.
pub fn moves(&self) -> &MoveLibrary {
fn moves(&self) -> &Box<dyn MoveLibrary> {
&self.moves
}
/// All data for the moves.
pub fn moves_mut(&mut self) -> &mut MoveLibrary {
fn moves_mut(&mut self) -> &mut Box<dyn MoveLibrary> {
&mut self.moves
}
/// All data for the items.
pub fn items(&self) -> &ItemLibrary {
fn items(&self) -> &Box<dyn ItemLibrary> {
&self.items
}
/// All data for the items.
pub fn items_mut(&mut self) -> &mut ItemLibrary {
fn items_mut(&mut self) -> &mut Box<dyn ItemLibrary> {
&mut self.items
}
/// All data for growth rates.
pub fn growth_rates(&self) -> &GrowthRateLibrary {
fn growth_rates(&self) -> &Box<dyn GrowthRateLibrary> {
&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<dyn GrowthRateLibrary> {
&mut self.growth_rates
}
/// All data related to types and type effectiveness.
pub fn types(&self) -> &TypeLibrary {
fn types(&self) -> &Box<dyn TypeLibrary> {
&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<dyn TypeLibrary> {
&mut self.types
}
/// All data related to natures.
pub fn natures(&self) -> &NatureLibrary {
fn natures(&self) -> &Box<dyn NatureLibrary> {
&self.natures
}
/// All data related to natures.
pub fn natures_mut(&mut self) -> &mut NatureLibrary {
fn natures_mut(&mut self) -> &mut Box<dyn NatureLibrary> {
&mut self.natures
}
/// All data related to abilities.
pub fn abilities(&self) -> &AbilityLibrary {
fn abilities(&self) -> &Box<dyn AbilityLibrary> {
&self.abilities
}
/// All data related to abilities.
pub fn abilities_mut(&mut self) -> &mut AbilityLibrary {
fn abilities_mut(&mut self) -> &mut Box<dyn AbilityLibrary> {
&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<dyn LibrarySettings>;
fn species(&self) -> &Box<dyn SpeciesLibrary>;
fn species_mut(&mut self) -> &mut Box<dyn SpeciesLibrary>;
fn moves(&self) -> &Box<dyn MoveLibrary>;
fn moves_mut(&mut self) -> &mut Box<dyn MoveLibrary>;
fn items(&self) -> &Box<dyn ItemLibrary>;
fn items_mut(&mut self) -> &mut Box<dyn ItemLibrary>;
fn growth_rates(&self) -> & Box<dyn GrowthRateLibrary>;
fn growth_rates_mut(&mut self) -> &mut Box<dyn GrowthRateLibrary>;
fn types(&self) -> &Box<dyn TypeLibrary>;
fn types_mut(&mut self) -> &mut Box<dyn TypeLibrary>;
fn natures(&self) -> &Box<dyn NatureLibrary>;
fn natures_mut(&mut self) -> &mut Box<dyn NatureLibrary>;
fn abilities(&self) -> &Box<dyn AbilityLibrary>;
fn abilities_mut(&mut self) -> &mut Box<dyn AbilityLibrary>;
}
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()),
}
}
}

View File

@ -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<TypeIdentifier> 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<TypeIdentifier>;
/// Gets the type name from the type identifier.
fn get_type_name(&self, t: TypeIdentifier) -> Option<StringKey>;
/// 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<Vec<f32>>,
}
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<TypeIdentifier> {
fn get_type_id(&self, key: &StringKey) -> Option<TypeIdentifier> {
self.types.get(key).cloned()
}
/// Gets the type name from the type identifier.
pub fn get_type_name(&self, t: TypeIdentifier) -> Option<StringKey> {
fn get_type_name(&self, t: TypeIdentifier) -> Option<StringKey> {
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;

View File

@ -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<StringKey>;
#[allow(clippy::borrowed_box)]
/// The moves a Pokemon with this form can learn.
fn moves(&self) -> &Box<dyn LearnableMoves>;
/// 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<dyn LearnableMoves> {
&self.moves
@ -233,7 +231,6 @@ pub(crate) mod tests {
fn base_stats(&self) -> &StaticStatisticSet<u16>;
fn abilities(&self) -> &Vec<StringKey>;
fn hidden_abilities(&self) -> &Vec<StringKey>;
#[allow(clippy::borrowed_box)]
fn moves(&self) -> &Box<dyn LearnableMoves>;
fn flags(&self) -> &HashSet<StringKey>;
fn get_type(&self, index: usize) -> TypeIdentifier;

View File

@ -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<dyn DynamicLibrary> {
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<dyn TypeLibrary>) {
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<dyn NatureLibrary>) {
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<dyn ItemLibrary>) {
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<dyn GrowthRateLibrary>) {
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<dyn AbilityLibrary>) {
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<dyn Form> {
fn parse_form(name: StringKey, value: &Value, library: &mut dyn StaticData) -> Arc<dyn Form> {
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<d
.map(|a| library.types().get_type_id(&a.as_str().unwrap().into()).unwrap())
.collect();
let moves = parse_moves(value.get("moves").unwrap(), library.moves());
let moves = parse_moves(value.get("moves").unwrap(), library.moves_mut());
Arc::new(FormImpl::new(
&name,
@ -368,7 +368,7 @@ where
)
}
fn parse_moves(value: &Value, move_library: &MoveLibrary) -> Box<dyn LearnableMoves> {
fn parse_moves(value: &Value, move_library: &mut Box<dyn MoveLibrary>) -> Box<dyn LearnableMoves> {
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<dyn TypeLibrary> = Box::new(TypeLibraryImpl::new(18));
load_types(&path.to_str().unwrap().to_string(), &mut lib);
assert_eq!(

View File

@ -43,7 +43,7 @@ struct TestPokemon {
}
impl TestCase {
pub fn run_test(&self, library: Arc<DynamicLibrary>) {
pub fn run_test(&self, library: Arc<dyn DynamicLibrary>) {
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<DynamicLibrary>) -> Pokemon {
fn to_pokemon(&self, library: Arc<dyn DynamicLibrary>) -> 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));

View File

@ -17,8 +17,8 @@ use crate::common::{library_loader, TestCase};
pub mod common;
fn get_library() -> Arc<DynamicLibrary> {
Arc::new(library_loader::load_library())
fn get_library() -> Arc<dyn DynamicLibrary> {
library_loader::load_library()
}
#[test]