Moves a bunch of libraries to traits
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2022-12-24 12:00:50 +01:00
parent bce636b97e
commit 47df85e8d3
47 changed files with 730 additions and 358 deletions

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;