Make LearnableMoves a trait
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2022-11-28 20:20:46 +01:00
parent d4b1cadad0
commit c1e09c654b
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
6 changed files with 48 additions and 29 deletions

View File

@ -23,7 +23,7 @@ unsafe extern "C" fn form_new(
abilities_length: usize, abilities_length: usize,
hidden_abilities: *const BorrowedPtr<c_char>, hidden_abilities: *const BorrowedPtr<c_char>,
hidden_abilities_length: usize, hidden_abilities_length: usize,
moves: OwnedPtr<LearnableMoves>, moves: OwnedPtr<Box<dyn LearnableMoves>>,
flags: *const *const c_char, flags: *const *const c_char,
flags_length: usize, flags_length: usize,
) -> IdentifiablePointer<Arc<Form>> { ) -> IdentifiablePointer<Arc<Form>> {
@ -89,7 +89,11 @@ unsafe extern "C" fn form_base_stats(ptr: ExternPointer<Arc<Form>>) -> Identifia
ffi_vec_stringkey_getters!(Form, abilities); ffi_vec_stringkey_getters!(Form, abilities);
ffi_vec_stringkey_getters!(Form, hidden_abilities); ffi_vec_stringkey_getters!(Form, hidden_abilities);
ffi_arc_getter!(Form, moves, BorrowedPtr<LearnableMoves>); /// The moves a Pokemon with this form can learn.
#[no_mangle]
extern "C" fn form_moves(ptr: ExternPointer<Arc<Form>>) -> BorrowedPtr<Box<dyn LearnableMoves>> {
ptr.as_ref().moves() as *const Box<dyn LearnableMoves>
}
/// Check if the form has a specific flag set. /// Check if the form has a specific flag set.
#[no_mangle] #[no_mangle]

View File

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

View File

@ -48,10 +48,9 @@ pub mod tests {
use crate::static_data::libraries::data_library::DataLibrary; use crate::static_data::libraries::data_library::DataLibrary;
use crate::static_data::libraries::species_library::SpeciesLibrary; use crate::static_data::libraries::species_library::SpeciesLibrary;
use crate::static_data::Form;
use crate::static_data::LearnableMoves;
use crate::static_data::Species; use crate::static_data::Species;
use crate::static_data::StaticStatisticSet; use crate::static_data::StaticStatisticSet;
use crate::static_data::{Form, LearnableMovesImpl};
fn build_species() -> Species { fn build_species() -> Species {
Species::new( Species::new(
@ -69,7 +68,7 @@ pub mod tests {
StaticStatisticSet::new(10, 10, 10, 10, 10, 10), StaticStatisticSet::new(10, 10, 10, 10, 10, 10),
Vec::new(), Vec::new(),
Vec::new(), Vec::new(),
LearnableMoves::new(), Box::new(LearnableMovesImpl::new()),
HashSet::new(), HashSet::new(),
)), )),
HashSet::new(), HashSet::new(),

View File

@ -30,7 +30,7 @@ pub struct Form {
/// The possible hidden abilities a Pokemon with this form can have. /// The possible hidden abilities a Pokemon with this form can have.
hidden_abilities: Vec<StringKey>, hidden_abilities: Vec<StringKey>,
/// The moves a Pokemon with this form can learn. /// The moves a Pokemon with this form can learn.
moves: LearnableMoves, moves: Box<dyn LearnableMoves>,
/// Arbitrary flags can be set on a form for scripting use. /// Arbitrary flags can be set on a form for scripting use.
flags: HashSet<StringKey>, flags: HashSet<StringKey>,
} }
@ -46,7 +46,7 @@ impl Form {
base_stats: StaticStatisticSet<u16>, base_stats: StaticStatisticSet<u16>,
abilities: Vec<StringKey>, abilities: Vec<StringKey>,
hidden_abilities: Vec<StringKey>, hidden_abilities: Vec<StringKey>,
moves: LearnableMoves, moves: Box<dyn LearnableMoves>,
flags: HashSet<StringKey>, flags: HashSet<StringKey>,
) -> Form { ) -> Form {
Form { Form {
@ -96,8 +96,10 @@ impl Form {
pub fn hidden_abilities(&self) -> &Vec<StringKey> { pub fn hidden_abilities(&self) -> &Vec<StringKey> {
&self.hidden_abilities &self.hidden_abilities
} }
#[allow(clippy::borrowed_box)]
/// The moves a Pokemon with this form can learn. /// The moves a Pokemon with this form can learn.
pub fn moves(&self) -> &LearnableMoves { pub fn moves(&self) -> &Box<dyn LearnableMoves> {
&self.moves &self.moves
} }
/// Arbitrary flags can be set on a form for scripting use. /// Arbitrary flags can be set on a form for scripting use.

View File

@ -1,26 +1,39 @@
use hashbrown::hash_map::Entry::{Occupied, Vacant}; use hashbrown::hash_map::Entry::{Occupied, Vacant};
use hashbrown::HashMap; use hashbrown::HashMap;
use std::fmt::Debug;
use crate::defines::LevelInt; use crate::defines::LevelInt;
use crate::StringKey; use crate::StringKey;
/// This allows for storage of the moves a Pokemon can learn. /// The storage of the moves a Pokemon can learn.
pub trait LearnableMoves: Debug {
/// Adds a new level move the Pokemon can learn.
fn add_level_move(&mut self, level: LevelInt, m: &StringKey);
/// Gets all moves a Pokemon can learn when leveling up to a specific level.
fn get_learned_by_level(&self, level: LevelInt) -> Option<&Vec<StringKey>>;
/// Gets the distinct moves a Pokemon can learn through leveling up.
fn get_distinct_level_moves(&self) -> &Vec<StringKey>;
}
/// The storage of the moves a Pokemon can learn.
#[derive(Default, PartialEq, Eq, Debug)] #[derive(Default, PartialEq, Eq, Debug)]
pub struct LearnableMoves { pub struct LearnableMovesImpl {
/// A map of the moves a Pokemon can learn per level. /// A map of the moves a Pokemon can learn per level.
learned_by_level: HashMap<LevelInt, Vec<StringKey>>, learned_by_level: HashMap<LevelInt, Vec<StringKey>>,
/// A list of the distinct moves a Pokemon can learn through leveling up. /// A list of the distinct moves a Pokemon can learn through leveling up.
distinct_level_moves: Vec<StringKey>, distinct_level_moves: Vec<StringKey>,
} }
impl LearnableMoves { impl LearnableMovesImpl {
/// Instantiates a new Learnable Moves. /// Instantiates a new Learnable Moves.
pub fn new() -> LearnableMoves { pub fn new() -> Self {
LearnableMoves::default() Self::default()
} }
}
impl LearnableMoves for LearnableMovesImpl {
/// Adds a new level move the Pokemon can learn. /// Adds a new level move the Pokemon can learn.
pub fn add_level_move(&mut self, level: LevelInt, m: &StringKey) { fn add_level_move(&mut self, level: LevelInt, m: &StringKey) {
match self.learned_by_level.entry(level) { match self.learned_by_level.entry(level) {
Occupied(x) => { Occupied(x) => {
x.into_mut().push(m.clone()); x.into_mut().push(m.clone());
@ -35,12 +48,12 @@ impl LearnableMoves {
} }
/// Gets all moves a Pokemon can learn when leveling up to a specific level. /// Gets all moves a Pokemon can learn when leveling up to a specific level.
pub fn get_learned_by_level(&self, level: LevelInt) -> Option<&Vec<StringKey>> { fn get_learned_by_level(&self, level: LevelInt) -> Option<&Vec<StringKey>> {
self.learned_by_level.get(&level) self.learned_by_level.get(&level)
} }
/// Gets the distinct moves a Pokemon can learn through leveling up. /// Gets the distinct moves a Pokemon can learn through leveling up.
pub fn get_distinct_level_moves(&self) -> &Vec<StringKey> { fn get_distinct_level_moves(&self) -> &Vec<StringKey> {
&self.distinct_level_moves &self.distinct_level_moves
} }
} }
@ -48,10 +61,11 @@ impl LearnableMoves {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::static_data::species_data::learnable_moves::LearnableMoves; use crate::static_data::species_data::learnable_moves::LearnableMoves;
use crate::static_data::LearnableMovesImpl;
#[test] #[test]
fn adds_level_moves() { fn adds_level_moves() {
let mut moves = LearnableMoves::new(); let mut moves = LearnableMovesImpl::new();
moves.add_level_move(1, &"foo".into()); moves.add_level_move(1, &"foo".into());
moves.add_level_move(1, &"bar".into()); moves.add_level_move(1, &"bar".into());
@ -63,7 +77,7 @@ mod tests {
#[test] #[test]
fn adds_two_same_moves_at_different_level() { fn adds_two_same_moves_at_different_level() {
let mut moves = LearnableMoves::new(); let mut moves = LearnableMovesImpl::new();
moves.add_level_move(1, &"foo".into()); moves.add_level_move(1, &"foo".into());
moves.add_level_move(5, &"foo".into()); moves.add_level_move(5, &"foo".into());

View File

@ -17,9 +17,9 @@ use pkmn_lib::dynamic_data::Gen7MiscLibrary;
use pkmn_lib::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver; use pkmn_lib::script_implementations::wasm::script_resolver::WebAssemblyScriptResolver;
use pkmn_lib::static_data::{ use pkmn_lib::static_data::{
AbilityImpl, AbilityLibrary, BattleItemCategory, DataLibrary, EffectParameter, Form, GrowthRateLibrary, ItemImpl, AbilityImpl, AbilityLibrary, BattleItemCategory, DataLibrary, EffectParameter, Form, GrowthRateLibrary, ItemImpl,
ItemLibrary, LearnableMoves, LibrarySettings, LookupGrowthRate, MoveDataImpl, MoveLibrary, NatureImpl, ItemLibrary, LearnableMoves, LearnableMovesImpl, LibrarySettings, LookupGrowthRate, MoveDataImpl, MoveLibrary,
NatureLibrary, SecondaryEffect, SecondaryEffectImpl, Species, StaticData, StaticStatisticSet, Statistic, NatureImpl, NatureLibrary, SecondaryEffect, SecondaryEffectImpl, Species, StaticData, StaticStatisticSet,
TypeLibrary, Statistic, TypeLibrary,
}; };
use pkmn_lib::StringKey; use pkmn_lib::StringKey;
@ -368,8 +368,8 @@ where
) )
} }
fn parse_moves(value: &Value, move_library: &MoveLibrary) -> LearnableMoves { fn parse_moves(value: &Value, move_library: &MoveLibrary) -> Box<dyn LearnableMoves> {
let mut moves = LearnableMoves::default(); let mut moves = LearnableMovesImpl::default();
let level_moves = value.get("levelMoves").unwrap().as_array().unwrap(); let level_moves = value.get("levelMoves").unwrap().as_array().unwrap();
for level_move in level_moves { for level_move in level_moves {
@ -379,7 +379,7 @@ fn parse_moves(value: &Value, move_library: &MoveLibrary) -> LearnableMoves {
moves.add_level_move(level, &name); moves.add_level_move(level, &name);
} }
moves Box::new(moves)
} }
fn parse_effect_parameter(value: &Value) -> EffectParameter { fn parse_effect_parameter(value: &Value) -> EffectParameter {