More work on mocking and unit testing

This commit is contained in:
Deukhoofd 2023-01-04 18:39:27 +01:00
parent a1e13af793
commit 517c5710d1
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
17 changed files with 948 additions and 714 deletions

View File

@ -44,7 +44,7 @@ impl Script for Acrobatics {
mod tests { mod tests {
use super::*; use super::*;
use alloc::rc::Rc; use alloc::rc::Rc;
use pkmn_lib_interface::app_interface::{Item, MockExecutingMove, MockItem, MockPokemon}; use pkmn_lib_interface::app_interface::{MockExecutingMove, MockItem, MockPokemon};
fn mock_executing_move(has_held_item: bool) -> ExecutingMove { fn mock_executing_move(has_held_item: bool) -> ExecutingMove {
let mut mv = MockExecutingMove::new(); let mut mv = MockExecutingMove::new();

View File

@ -1,4 +1,3 @@
use alloc::boxed::Box;
use core::any::Any; use core::any::Any;
use core::mem::transmute; use core::mem::transmute;
use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon, Statistic}; use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon, Statistic};
@ -39,3 +38,68 @@ impl Script for Acupressure {
self self
} }
} }
#[cfg(test)]
mod tests {
use super::*;
use alloc::rc::Rc;
use pkmn_lib_interface::app_interface::{
MockBattle, MockBattleRandom, MockExecutingMove, MockHitData, MockItem, MockPokemon,
};
#[test]
fn fails_if_target_is_user() {
let mut user = MockPokemon::new();
user.expect_equals().return_const(true);
let user = Rc::new(user);
let u = user.clone();
let mut mv = MockExecutingMove::new();
mv.expect_user().returning_st(move || user.clone());
let mut hit_data = MockHitData::new();
hit_data.expect_fail().once();
let hit_data = Rc::new(hit_data);
mv.expect_get_hit_data()
.returning_st(move |_, _| hit_data.clone());
let script = Acupressure::new();
script.on_secondary_effect(Rc::new(mv), u, 0);
}
#[test]
fn increases_stat_by_two() {
let mut user = MockPokemon::new();
user.expect_equals().return_const(false);
user.expect_battle().returning_st(move || {
let mut battle = MockBattle::new();
battle.expect_random().returning_st(move || {
let mut random = MockBattleRandom::new();
random.expect_get_between().returning_st(|low, high| {
assert_eq!(1, low);
assert_eq!(6, high);
return 1;
});
Rc::new(random)
});
Some(Rc::new(battle))
});
user.expect_change_stat_boost()
.once()
.returning(|stat, amount, self_inflicted| {
assert_eq!(Statistic::Attack, stat);
assert_eq!(2, amount);
assert_eq!(false, self_inflicted);
true
});
let user = Rc::new(user);
let u = user.clone();
let mut mv = MockExecutingMove::new();
mv.expect_user().returning_st(move || user.clone());
let script = Acupressure::new();
script.on_secondary_effect(Rc::new(mv), u, 0);
}
}

View File

@ -30,8 +30,8 @@ impl Script for AuroraVeil {
if target.battle().unwrap().has_weather(Hail::get_const_name()) { if target.battle().unwrap().has_weather(Hail::get_const_name()) {
return mv.get_hit_data(&target, hit).fail(); return mv.get_hit_data(&target, hit).fail();
} }
let script = target let binding = target.battle_side();
.battle_side() let script = binding
.add_volatile(Box::new(AuroraVeilEffect::new())) .add_volatile(Box::new(AuroraVeilEffect::new()))
.as_any() .as_any()
.downcast_ref::<AuroraVeilEffect>() .downcast_ref::<AuroraVeilEffect>()

View File

@ -14,6 +14,6 @@ spin = { version = "0.9.4", default-features = false, features = ["rwlock"] }
paste = { version = "1.0.7" } paste = { version = "1.0.7" }
hashbrown = { version = "0.12.3" } hashbrown = { version = "0.12.3" }
dlmalloc = { version = "0.2.4", features = ["global"] } dlmalloc = { version = "0.2.4", features = ["global"] }
mockall = { version = "0.11.2", optional = true } mockall = { version = "0.11.2", optional = true, features = ["nightly"] }

View File

@ -1,16 +1,12 @@
use crate::app_interface::{
BattleParty, BattlePartyImpl, BattleRandom, BattleRandomImpl, BattleSide, BattleSideImpl,
ChoiceQueue, ChoiceQueueImpl, Pokemon, PokemonImpl,
};
use crate::handling::cached_value::CachedValue;
use crate::handling::Cacheable;
use crate::{
cached_value, cached_value_getters, wasm_value_getters, wasm_value_getters_extern,
wasm_value_getters_funcs, DynamicLibrary, ExternRef, ExternalReferenceType, ImmutableList,
StringKey, VecExternRef,
};
use alloc::rc::Rc; use alloc::rc::Rc;
use crate::app_interface::list::ImmutableList;
use crate::app_interface::BattleSideImpl;
use crate::app_interface::{
BattleParty, BattlePartyImpl, BattleRandom, ChoiceQueue, DynamicLibrary, Pokemon, StringKey,
};
#[cfg_attr(feature = "mock_data", mockall::automock)]
pub trait BattleTrait { pub trait BattleTrait {
fn library(&self) -> DynamicLibrary; fn library(&self) -> DynamicLibrary;
fn parties(&self) -> ImmutableList<BattlePartyImpl>; fn parties(&self) -> ImmutableList<BattlePartyImpl>;
@ -31,23 +27,41 @@ pub trait BattleTrait {
} }
pub type Battle = Rc<dyn BattleTrait>; pub type Battle = Rc<dyn BattleTrait>;
#[cfg(feature = "mock_data")]
pub type MockBattle = MockBattleTrait;
struct BattleInner { #[cfg(not(feature = "mock_data"))]
mod implementation {
use super::*;
use crate::app_interface::PokemonImpl;
use crate::app_interface::{
BattleParty, BattlePartyImpl, BattleRandom, BattleRandomImpl, BattleSide, BattleSideImpl,
ChoiceQueue, ChoiceQueueImpl, Pokemon,
};
use crate::handling::cached_value::CachedValue;
use crate::handling::Cacheable;
use crate::{
cached_value, cached_value_getters, wasm_value_getters, wasm_value_getters_extern,
wasm_value_getters_funcs, DynamicLibrary, ExternRef, ExternalReferenceType, ImmutableList,
StringKey, VecExternRef,
};
struct BattleInner {
reference: ExternRef<BattleImpl>, reference: ExternRef<BattleImpl>,
library: CachedValue<DynamicLibrary>, library: CachedValue<DynamicLibrary>,
parties: CachedValue<ImmutableList<BattlePartyImpl>>, parties: CachedValue<ImmutableList<BattlePartyImpl>>,
sides: CachedValue<ImmutableList<BattleSideImpl>>, sides: CachedValue<ImmutableList<BattleSideImpl>>,
random: CachedValue<Rc<BattleRandomImpl>>, random: CachedValue<Rc<BattleRandomImpl>>,
choice_queue: CachedValue<Rc<ChoiceQueueImpl>>, choice_queue: CachedValue<Rc<ChoiceQueueImpl>>,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct BattleImpl { pub struct BattleImpl {
inner: Rc<BattleInner>, inner: Rc<BattleInner>,
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl BattleImpl { impl BattleImpl {
pub fn new(reference: ExternRef<BattleImpl>) -> Self { pub fn new(reference: ExternRef<BattleImpl>) -> Self {
Self::from_ref(reference, &|reference| Self { Self::from_ref(reference, &|reference| Self {
inner: Rc::new(BattleInner { inner: Rc::new(BattleInner {
@ -64,10 +78,10 @@ impl BattleImpl {
}), }),
}) })
} }
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl BattleTrait for BattleImpl { impl BattleTrait for BattleImpl {
cached_value_getters! { cached_value_getters! {
fn library(&self) -> DynamicLibrary; fn library(&self) -> DynamicLibrary;
fn parties(&self) -> ImmutableList<BattlePartyImpl>; fn parties(&self) -> ImmutableList<BattlePartyImpl>;
@ -89,7 +103,8 @@ impl BattleTrait for BattleImpl {
fn find_party_for_pokemon(&self, pokemon: &Pokemon) -> Option<BattleParty> { fn find_party_for_pokemon(&self, pokemon: &Pokemon) -> Option<BattleParty> {
unsafe { unsafe {
let b = battle_find_party_for_pokemon(self.inner.reference, pokemon.reference().into()) let b =
battle_find_party_for_pokemon(self.inner.reference, pokemon.reference().into())
.get_value(); .get_value();
if let Some(b) = b { if let Some(b) = b {
Some(Rc::new(b)) Some(Rc::new(b))
@ -121,9 +136,9 @@ impl BattleTrait for BattleImpl {
fn winning_side(&self) -> u8; fn winning_side(&self) -> u8;
fn current_turn(&self) -> u32; fn current_turn(&self) -> u32;
} }
} }
wasm_value_getters_extern! { wasm_value_getters_extern! {
BattleImpl, Battle, BattleImpl, Battle,
pub fn can_flee(&self) -> bool; pub fn can_flee(&self) -> bool;
pub fn number_of_sides(&self) -> u8; pub fn number_of_sides(&self) -> u8;
@ -132,29 +147,37 @@ wasm_value_getters_extern! {
pub fn has_ended_conclusively(&self) -> bool; pub fn has_ended_conclusively(&self) -> bool;
pub fn winning_side(&self) -> u8; pub fn winning_side(&self) -> u8;
pub fn current_turn(&self) -> u32; pub fn current_turn(&self) -> u32;
} }
crate::handling::cacheable::cacheable!(BattleImpl); crate::handling::cacheable::cacheable!(BattleImpl);
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for BattleImpl { impl ExternalReferenceType for BattleImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self { fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference) Self::new(reference)
} }
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn battle_get_library(r: ExternRef<BattleImpl>) -> ExternRef<DynamicLibrary>; fn battle_get_library(r: ExternRef<BattleImpl>) -> ExternRef<DynamicLibrary>;
fn battle_get_parties(r: ExternRef<BattleImpl>) -> VecExternRef<BattlePartyImpl>; fn battle_get_parties(r: ExternRef<BattleImpl>) -> VecExternRef<BattlePartyImpl>;
fn battle_get_sides(r: ExternRef<BattleImpl>) -> VecExternRef<BattleSideImpl>; fn battle_get_sides(r: ExternRef<BattleImpl>) -> VecExternRef<BattleSideImpl>;
fn battle_get_random(r: ExternRef<BattleImpl>) -> ExternRef<BattleRandomImpl>; fn battle_get_random(r: ExternRef<BattleImpl>) -> ExternRef<BattleRandomImpl>;
fn battle_get_choice_queue(r: ExternRef<BattleImpl>) -> ExternRef<ChoiceQueueImpl>; fn battle_get_choice_queue(r: ExternRef<BattleImpl>) -> ExternRef<ChoiceQueueImpl>;
fn battle_get_pokemon(r: ExternRef<BattleImpl>, side: u8, index: u8) -> ExternRef<PokemonImpl>; fn battle_get_pokemon(
r: ExternRef<BattleImpl>,
side: u8,
index: u8,
) -> ExternRef<PokemonImpl>;
fn battle_find_party_for_pokemon( fn battle_find_party_for_pokemon(
r: ExternRef<BattleImpl>, r: ExternRef<BattleImpl>,
mon: ExternRef<PokemonImpl>, mon: ExternRef<PokemonImpl>,
) -> ExternRef<BattlePartyImpl>; ) -> ExternRef<BattlePartyImpl>;
fn battle_get_weather_name(r: ExternRef<BattleImpl>) -> ExternRef<StringKey>; fn battle_get_weather_name(r: ExternRef<BattleImpl>) -> ExternRef<StringKey>;
}
} }
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;

View File

@ -1,6 +1,6 @@
use crate::{ExternRef, ExternalReferenceType};
use alloc::rc::Rc; use alloc::rc::Rc;
#[cfg_attr(feature = "mock_data", mockall::automock)]
pub trait BattleRandomTrait { pub trait BattleRandomTrait {
fn get(&self) -> i32; fn get(&self) -> i32;
fn get_max(&self, max: i32) -> i32; fn get_max(&self, max: i32) -> i32;
@ -8,14 +8,23 @@ pub trait BattleRandomTrait {
} }
pub type BattleRandom = Rc<dyn BattleRandomTrait>; pub type BattleRandom = Rc<dyn BattleRandomTrait>;
#[cfg(feature = "mock_data")]
#[derive(Clone)] pub type MockBattleRandom = MockBattleRandomTrait;
pub struct BattleRandomImpl {
reference: ExternRef<Self>,
}
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl BattleRandomTrait for BattleRandomImpl { pub use implementation::*;
#[cfg(not(feature = "mock_data"))]
mod implementation {
use super::*;
use crate::{ExternRef, ExternalReferenceType};
#[derive(Clone)]
pub struct BattleRandomImpl {
reference: ExternRef<Self>,
}
impl BattleRandomTrait for BattleRandomImpl {
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
fn get(&self) -> i32 { fn get(&self) -> i32 {
unsafe { battle_random_get(self.reference) } unsafe { battle_random_get(self.reference) }
@ -29,18 +38,19 @@ impl BattleRandomTrait for BattleRandomImpl {
unsafe { battle_random_get_between(self.reference, min, max) } unsafe { battle_random_get_between(self.reference, min, max) }
} }
// TODO: effect_chance() // TODO: effect_chance()
} }
impl ExternalReferenceType for BattleRandomImpl { impl ExternalReferenceType for BattleRandomImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self { fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self { reference } Self { reference }
} }
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn battle_random_get(r: ExternRef<BattleRandomImpl>) -> i32; fn battle_random_get(r: ExternRef<BattleRandomImpl>) -> i32;
fn battle_random_get_max(r: ExternRef<BattleRandomImpl>, max: i32) -> i32; fn battle_random_get_max(r: ExternRef<BattleRandomImpl>, max: i32) -> i32;
fn battle_random_get_between(r: ExternRef<BattleRandomImpl>, min: i32, max: i32) -> i32; fn battle_random_get_between(r: ExternRef<BattleRandomImpl>, min: i32, max: i32) -> i32;
}
} }

View File

@ -1,4 +1,6 @@
use crate::app_interface::{Battle, BattleImpl, Pokemon, PokemonImpl, WithVolatile}; use crate::app_interface::{Battle, Pokemon, WithVolatile};
#[cfg(not(feature = "mock_data"))]
use crate::app_interface::{BattleImpl, PokemonImpl};
use crate::handling::cacheable::Cacheable; use crate::handling::cacheable::Cacheable;
use crate::handling::cached_value::CachedValue; use crate::handling::cached_value::CachedValue;
use crate::{ use crate::{
@ -20,6 +22,7 @@ pub trait BattleSideTrait: WithVolatile {
pub type BattleSide = Rc<dyn BattleSideTrait>; pub type BattleSide = Rc<dyn BattleSideTrait>;
#[cfg(not(feature = "mock_data"))]
struct BattleSideInner { struct BattleSideInner {
reference: ExternRef<BattleSideImpl>, reference: ExternRef<BattleSideImpl>,
side_index: CachedValue<u8>, side_index: CachedValue<u8>,
@ -29,6 +32,7 @@ struct BattleSideInner {
#[derive(Clone)] #[derive(Clone)]
pub struct BattleSideImpl { pub struct BattleSideImpl {
#[cfg(not(feature = "mock_data"))]
inner: Rc<BattleSideInner>, inner: Rc<BattleSideInner>,
} }
@ -82,13 +86,23 @@ impl WithVolatile for BattleSideImpl {
battleside_has_volatile(self.inner.reference, script_name.as_ptr()) battleside_has_volatile(self.inner.reference, script_name.as_ptr())
} }
} }
fn add_volatile<'a, 'b>(&'a self, script: Box<dyn Script>) -> &'b dyn Script { fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script {
unsafe { unsafe {
battleside_add_volatile(self.inner.reference, ScriptPtr::new(script)) battleside_add_volatile(self.inner.reference, ScriptPtr::new(script))
.val() .val()
.unwrap() .unwrap()
} }
} }
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script {
unsafe {
let ptr = CString::new(script_name).unwrap();
battleside_add_volatile_by_name(self.inner.reference, ptr.as_ptr())
.val()
.unwrap()
}
}
fn remove_volatile(&self, script: &dyn Script) { fn remove_volatile(&self, script: &dyn Script) {
unsafe { unsafe {
let name = CString::new(script.get_name()).unwrap(); let name = CString::new(script.get_name()).unwrap();

View File

@ -1,3 +1,4 @@
#[cfg(not(feature = "mock_data"))]
use crate::app_interface::PokemonImpl; use crate::app_interface::PokemonImpl;
use crate::{ExternRef, ExternalReferenceType, Pokemon}; use crate::{ExternRef, ExternalReferenceType, Pokemon};
use alloc::rc::Rc; use alloc::rc::Rc;

View File

@ -1,18 +1,11 @@
use crate::app_interface::{LearnedMove, MoveData, Pokemon, PokemonImpl}; #[cfg(not(feature = "mock_data"))]
use crate::app_interface::PokemonImpl;
use crate::app_interface::{LearnedMove, MoveData, Pokemon};
use crate::handling::cached_value::CachedValue; use crate::handling::cached_value::CachedValue;
use crate::handling::temporary::Temporary; use crate::handling::temporary::Temporary;
use crate::{cached_value, ExternRef, ExternalReferenceType, Script}; use crate::{cached_value, ExternRef, ExternalReferenceType, Script};
use alloc::boxed::Box;
use alloc::rc::Rc; use alloc::rc::Rc;
struct ExecutingMoveInner {
reference: ExternRef<ExecutingMoveImpl>,
number_of_hits: CachedValue<u8>,
user: CachedValue<PokemonImpl>,
chosen_move: CachedValue<LearnedMove>,
use_move: CachedValue<MoveData>,
}
#[cfg_attr(feature = "mock_data", mockall::automock)] #[cfg_attr(feature = "mock_data", mockall::automock)]
pub trait ExecutingMoveTrait { pub trait ExecutingMoveTrait {
fn number_of_hits(&self) -> u8; fn number_of_hits(&self) -> u8;
@ -25,16 +18,50 @@ pub trait ExecutingMoveTrait {
fn get_hit_data(&self, pokemon: &Pokemon, hit: u8) -> HitData; fn get_hit_data(&self, pokemon: &Pokemon, hit: u8) -> HitData;
} }
#[cfg_attr(feature = "mock_data", mockall::automock)]
pub trait HitDataTrait {
fn is_critical(&self) -> bool;
fn base_power(&self) -> u8;
fn effectiveness(&self) -> f32;
fn damage(&self) -> u32;
fn move_type(&self) -> u8;
fn has_failed(&self) -> bool;
fn set_critical(&self, critical: bool);
fn set_effectiveness(&self, effectiveness: f32);
fn set_damage(&self, damage: u32);
fn set_move_type(&self, move_type: u8);
fn fail(&self);
}
pub type ExecutingMove = Rc<dyn ExecutingMoveTrait>; pub type ExecutingMove = Rc<dyn ExecutingMoveTrait>;
#[cfg(feature = "mock_data")] #[cfg(feature = "mock_data")]
pub type MockExecutingMove = MockExecutingMoveTrait; pub type MockExecutingMove = MockExecutingMoveTrait;
#[derive(Clone)] pub type HitData = Rc<dyn HitDataTrait>;
pub struct ExecutingMoveImpl { #[cfg(feature = "mock_data")]
inner: Temporary<ExecutingMoveInner>, pub type MockHitData = MockHitDataTrait;
}
impl ExecutingMoveImpl { #[cfg(not(feature = "mock_data"))]
pub use implementation::*;
#[cfg(not(feature = "mock_data"))]
mod implementation {
use super::*;
#[derive(Clone)]
pub struct ExecutingMoveImpl {
inner: Temporary<ExecutingMoveInner>,
}
struct ExecutingMoveInner {
reference: ExternRef<ExecutingMoveImpl>,
number_of_hits: CachedValue<u8>,
user: CachedValue<PokemonImpl>,
chosen_move: CachedValue<LearnedMove>,
use_move: CachedValue<MoveData>,
}
impl ExecutingMoveImpl {
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
pub(crate) fn new(reference: ExternRef<Self>) -> Self { pub(crate) fn new(reference: ExternRef<Self>) -> Self {
Self { Self {
@ -42,7 +69,9 @@ impl ExecutingMoveImpl {
reference.get_internal_index(), reference.get_internal_index(),
ExecutingMoveInner { ExecutingMoveInner {
reference, reference,
number_of_hits: cached_value!({ executing_move_get_number_of_hits(reference) }), number_of_hits: cached_value!({
executing_move_get_number_of_hits(reference)
}),
user: cached_value!({ user: cached_value!({
executing_move_get_user(reference).get_value().unwrap() executing_move_get_user(reference).get_value().unwrap()
}), }),
@ -58,10 +87,10 @@ impl ExecutingMoveImpl {
), ),
} }
} }
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl ExecutingMoveTrait for ExecutingMoveImpl { impl ExecutingMoveTrait for ExecutingMoveImpl {
fn number_of_hits(&self) -> u8 { fn number_of_hits(&self) -> u8 {
self.inner.value().number_of_hits.value() self.inner.value().number_of_hits.value()
} }
@ -101,31 +130,15 @@ impl ExecutingMoveTrait for ExecutingMoveImpl {
) )
} }
} }
} }
pub trait HitDataTrait { #[derive(Clone)]
fn is_critical(&self) -> bool; pub struct HitDataImpl {
fn base_power(&self) -> u8;
fn effectiveness(&self) -> f32;
fn damage(&self) -> u32;
fn move_type(&self) -> u8;
fn has_failed(&self) -> bool;
fn set_critical(&self, critical: bool);
fn set_effectiveness(&self, effectiveness: f32);
fn set_damage(&self, damage: u32);
fn set_move_type(&self, move_type: u8);
fn fail(&self);
}
pub type HitData = Rc<dyn HitDataTrait>;
#[derive(Clone)]
pub struct HitDataImpl {
reference: ExternRef<HitDataImpl>, reference: ExternRef<HitDataImpl>,
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl HitDataTrait for HitDataImpl { impl HitDataTrait for HitDataImpl {
fn is_critical(&self) -> bool { fn is_critical(&self) -> bool {
unsafe { hit_data_is_critical(self.reference) } unsafe { hit_data_is_critical(self.reference) }
} }
@ -160,28 +173,30 @@ impl HitDataTrait for HitDataImpl {
fn fail(&self) { fn fail(&self) {
unsafe { hit_data_fail(self.reference) } unsafe { hit_data_fail(self.reference) }
} }
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for ExecutingMoveImpl { impl ExternalReferenceType for ExecutingMoveImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self { fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference) Self::new(reference)
} }
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for HitDataImpl { impl ExternalReferenceType for HitDataImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self { fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self { reference } Self { reference }
} }
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn executing_move_get_number_of_targets(r: ExternRef<ExecutingMoveImpl>) -> usize; fn executing_move_get_number_of_targets(r: ExternRef<ExecutingMoveImpl>) -> usize;
fn executing_move_get_number_of_hits(r: ExternRef<ExecutingMoveImpl>) -> u8; fn executing_move_get_number_of_hits(r: ExternRef<ExecutingMoveImpl>) -> u8;
fn executing_move_get_user(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<PokemonImpl>; fn executing_move_get_user(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<PokemonImpl>;
fn executing_move_get_chosen_move(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<LearnedMove>; fn executing_move_get_chosen_move(
r: ExternRef<ExecutingMoveImpl>,
) -> ExternRef<LearnedMove>;
fn executing_move_get_use_move(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<MoveData>; fn executing_move_get_use_move(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<MoveData>;
#[allow(improper_ctypes)] #[allow(improper_ctypes)]
fn executing_move_get_script(r: ExternRef<ExecutingMoveImpl>) -> *const dyn Script; fn executing_move_get_script(r: ExternRef<ExecutingMoveImpl>) -> *const dyn Script;
@ -209,4 +224,5 @@ extern "wasm" {
fn hit_data_set_damage(r: ExternRef<HitDataImpl>, damage: u32); fn hit_data_set_damage(r: ExternRef<HitDataImpl>, damage: u32);
fn hit_data_set_move_type(r: ExternRef<HitDataImpl>, move_type: u8); fn hit_data_set_move_type(r: ExternRef<HitDataImpl>, move_type: u8);
fn hit_data_fail(r: ExternRef<HitDataImpl>); fn hit_data_fail(r: ExternRef<HitDataImpl>);
}
} }

View File

@ -1,4 +1,6 @@
use crate::app_interface::{Pokemon, PokemonImpl}; use crate::app_interface::Pokemon;
#[cfg(not(feature = "mock_data"))]
use crate::app_interface::PokemonImpl;
use crate::{ExternRef, ExternalReferenceType}; use crate::{ExternRef, ExternalReferenceType};
use alloc::rc::Rc; use alloc::rc::Rc;

View File

@ -1,48 +1,17 @@
use crate::app_interface::ability::{Ability, AbilityIndex};
use crate::app_interface::{ use crate::app_interface::{
AbilityImpl, Battle, BattleImpl, BattleSide, ClampedStatisticSet, Form, Gender, Item, ItemImpl, AbilityImpl, AbilityIndex, Battle, BattleSide, ClampedStatisticSet, DynamicLibrary, Form,
LearnedMove, LevelInt, Nature, Species, Statistic, StatisticSet, StatisticSetImpl, Gender, Item, LearnedMove, LevelInt, Nature, Species, Statistic, StatisticSet, TypeIdentifier,
}; WithVolatile,
use crate::handling::cached_value::CachedValue;
use crate::handling::Cacheable;
use crate::{
cached_value, cached_value_getters, wasm_optional_reference_getters,
wasm_optional_reference_getters_extern, wasm_optional_reference_getters_funcs,
wasm_reference_getters, wasm_reference_getters_extern, wasm_reference_getters_funcs,
wasm_value_getters, wasm_value_getters_extern, wasm_value_getters_funcs, DynamicLibrary,
ExternRef, ExternalReferenceType, Script, ScriptPtr, TypeIdentifier,
}; };
use crate::handling::Script;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::rc::Rc; use alloc::rc::Rc;
use core::any::Any; use cstr_core::c_char;
use cstr_core::{c_char, CString};
struct PokemonInner { #[cfg(not(feature = "mock_data"))]
reference: ExternRef<PokemonImpl>, pub use implementation::*;
library: CachedValue<DynamicLibrary>,
// We cache the reference to the data, not the values stored inside, which are dynamic.
flat_stats: CachedValue<Rc<StatisticSetImpl<u32>>>,
// We cache the reference to the data, not the values stored inside, which are dynamic.
stat_boosts: CachedValue<ClampedStatisticSet<i8>>,
// We cache the reference to the data, not the values stored inside, which are dynamic.
boosted_stats: CachedValue<Rc<StatisticSetImpl<u32>>>,
// We cache the reference to the data, not the values stored inside, which are dynamic.
individual_values: CachedValue<ClampedStatisticSet<u8>>,
// We cache the reference to the data, not the values stored inside, which are dynamic.
effort_values: CachedValue<ClampedStatisticSet<u8>>,
}
pub type Pokemon = Rc<dyn PokemonTrait>; pub trait PokemonTrait: WithVolatile {
#[cfg(feature = "mock_data")]
pub type MockPokemon = MockPokemonTrait;
#[derive(Clone)]
pub struct PokemonImpl {
inner: Rc<PokemonInner>,
}
#[cfg_attr(feature = "mock_data", mockall::automock)]
pub trait PokemonTrait {
fn reference(&self) -> u32; fn reference(&self) -> u32;
fn species(&self) -> Species; fn species(&self) -> Species;
@ -95,18 +64,59 @@ pub trait PokemonTrait {
fn set_weight(&self, weight: f32); fn set_weight(&self, weight: f32);
fn clear_status(&self); fn clear_status(&self);
fn battle_side(&self) -> BattleSide; fn battle_side(&self) -> BattleSide;
fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script;
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script;
fn remove_volatile(&self, script: &dyn Script);
// fn get_volatile<T: Script>(&self, script_name: &str) -> Option<&'static T>
// where
// T: Script + 'static;
fn equals(&self, other: &Pokemon) -> bool; fn equals(&self, other: &Pokemon) -> bool;
} }
pub type Pokemon = Rc<dyn PokemonTrait>;
/// A source of damage. This should be as unique as possible.
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum DamageSource {
/// The damage is done by a move.
MoveDamage = 0,
/// The damage is done by something else.
Misc = 1,
/// The damage is done because of struggling.
Struggle = 2,
}
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl PokemonTrait for PokemonImpl { mod implementation {
use super::*;
use cstr_core::CString;
use crate::app_interface::{BattleImpl, ItemImpl, StatisticSetImpl};
use crate::handling::cached_value::CachedValue;
use crate::handling::Cacheable;
use crate::{
cached_value, cached_value_getters, wasm_optional_reference_getters_extern,
wasm_optional_reference_getters_funcs, wasm_reference_getters_extern,
wasm_reference_getters_funcs, wasm_value_getters_extern, wasm_value_getters_funcs,
DynamicLibrary, ExternRef, ExternalReferenceType, Script, ScriptPtr, TypeIdentifier,
};
struct PokemonInner {
reference: ExternRef<PokemonImpl>,
library: CachedValue<DynamicLibrary>,
// We cache the reference to the data, not the values stored inside, which are dynamic.
flat_stats: CachedValue<Rc<StatisticSetImpl<u32>>>,
// We cache the reference to the data, not the values stored inside, which are dynamic.
stat_boosts: CachedValue<ClampedStatisticSet<i8>>,
// We cache the reference to the data, not the values stored inside, which are dynamic.
boosted_stats: CachedValue<Rc<StatisticSetImpl<u32>>>,
// We cache the reference to the data, not the values stored inside, which are dynamic.
individual_values: CachedValue<ClampedStatisticSet<u8>>,
// We cache the reference to the data, not the values stored inside, which are dynamic.
effort_values: CachedValue<ClampedStatisticSet<u8>>,
}
#[derive(Clone)]
pub struct PokemonImpl {
inner: Rc<PokemonInner>,
}
impl PokemonTrait for PokemonImpl {
fn reference(&self) -> u32 { fn reference(&self) -> u32 {
self.reference().get_internal_index() self.reference().get_internal_index()
} }
@ -136,8 +146,8 @@ impl PokemonTrait for PokemonImpl {
} }
fn set_held_item(&self, item: &Item) -> Option<Item> { fn set_held_item(&self, item: &Item) -> Option<Item> {
unsafe { unsafe {
let i = let i = pokemon_set_held_item(self.inner.reference, item.reference().into())
pokemon_set_held_item(self.inner.reference, item.reference().into()).get_value(); .get_value();
if let Some(i) = i { if let Some(i) = i {
Some(Rc::new(i)) Some(Rc::new(i))
} else { } else {
@ -181,7 +191,12 @@ impl PokemonTrait for PokemonImpl {
fn get_learned_move(&self, index: usize) -> Option<LearnedMove> { fn get_learned_move(&self, index: usize) -> Option<LearnedMove> {
unsafe { pokemon_get_learned_move(self.inner.reference, index).get_value() } unsafe { pokemon_get_learned_move(self.inner.reference, index).get_value() }
} }
fn change_stat_boost(&self, stat: Statistic, diff_amount: i8, self_inflicted: bool) -> bool { fn change_stat_boost(
&self,
stat: Statistic,
diff_amount: i8,
self_inflicted: bool,
) -> bool {
unsafe { unsafe {
pokemon_change_stat_boost(self.inner.reference, stat, diff_amount, self_inflicted) pokemon_change_stat_boost(self.inner.reference, stat, diff_amount, self_inflicted)
} }
@ -227,21 +242,6 @@ impl PokemonTrait for PokemonImpl {
.unwrap(), .unwrap(),
) )
} }
fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script {
unsafe {
pokemon_add_volatile(self.inner.reference, ScriptPtr::new(script))
.val()
.unwrap()
}
}
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script {
unsafe {
let ptr = CString::new(script_name).unwrap();
pokemon_add_volatile_by_name(self.inner.reference, ptr.as_ptr())
.val()
.unwrap()
}
}
wasm_reference_getters_funcs! { wasm_reference_getters_funcs! {
Pokemon, Pokemon,
@ -268,13 +268,6 @@ impl PokemonTrait for PokemonImpl {
} }
} }
fn remove_volatile(&self, script: &dyn Script) {
unsafe {
let name = CString::new(script.get_name()).unwrap();
pokemon_remove_volatile(self.inner.reference, name.as_ptr());
}
}
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
wasm_value_getters_funcs! { wasm_value_getters_funcs! {
Pokemon, Pokemon,
@ -302,10 +295,51 @@ impl PokemonTrait for PokemonImpl {
.get_internal_index() .get_internal_index()
.eq(&other.reference()) .eq(&other.reference())
} }
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl PokemonImpl { impl WithVolatile for PokemonImpl {
fn has_volatile(&self, script_name: &str) -> bool {
unsafe {
let ptr = CString::new(script_name).unwrap();
pokemon_has_volatile(self.inner.reference, ptr.as_ptr())
}
}
fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script {
unsafe {
pokemon_add_volatile(self.inner.reference, ScriptPtr::new(script))
.val()
.unwrap()
}
}
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script {
unsafe {
let ptr = CString::new(script_name).unwrap();
pokemon_add_volatile_by_name(self.inner.reference, ptr.as_ptr())
.val()
.unwrap()
}
}
fn remove_volatile(&self, script: &dyn Script) {
unsafe {
let name = CString::new(script.get_name()).unwrap();
pokemon_remove_volatile(self.inner.reference, name.as_ptr());
}
}
fn get_volatile_script(&self, script_name: &str) -> Option<&dyn Script> {
unsafe {
let script_name = CString::new(script_name).unwrap();
pokemon_get_volatile(self.inner.reference, script_name.as_ptr()).val()
}
}
}
#[cfg(not(feature = "mock_data"))]
impl PokemonImpl {
pub(crate) fn new(reference: ExternRef<Self>) -> Self { pub(crate) fn new(reference: ExternRef<Self>) -> Self {
Self::from_ref(reference, &|reference| Self { Self::from_ref(reference, &|reference| Self {
inner: Rc::new(PokemonInner { inner: Rc::new(PokemonInner {
@ -335,43 +369,28 @@ impl PokemonImpl {
pub(crate) fn reference(&self) -> ExternRef<Self> { pub(crate) fn reference(&self) -> ExternRef<Self> {
self.inner.reference self.inner.reference
} }
}
fn get_volatile<T>(&self, script_name: &str) -> Option<&T> #[cfg(not(feature = "mock_data"))]
where wasm_reference_getters_extern! {
T: Script + 'static,
{
unsafe {
let script_name = CString::new(script_name).unwrap();
let s = pokemon_get_volatile(self.inner.reference, script_name.as_ptr()).val();
if let Some(s) = s {
Some(s.as_any().downcast_ref().unwrap())
} else {
None
}
}
}
}
#[cfg(not(feature = "mock_data"))]
wasm_reference_getters_extern! {
PokemonImpl, Pokemon, PokemonImpl, Pokemon,
pub fn species(&self) -> Species; pub fn species(&self) -> Species;
pub fn form(&self) -> Form; pub fn form(&self) -> Form;
pub fn active_ability(&self) -> AbilityImpl; pub fn active_ability(&self) -> AbilityImpl;
pub fn nature(&self) -> Nature; pub fn nature(&self) -> Nature;
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
wasm_optional_reference_getters_extern! { wasm_optional_reference_getters_extern! {
PokemonImpl, Pokemon, PokemonImpl, Pokemon,
pub fn display_species(&self) -> Option<Species>; pub fn display_species(&self) -> Option<Species>;
pub fn display_form(&self) -> Option<Form>; pub fn display_form(&self) -> Option<Form>;
pub fn held_item(&self) -> Option<ItemImpl>; pub fn held_item(&self) -> Option<ItemImpl>;
pub fn battle(&self) -> Option<BattleImpl>; pub fn battle(&self) -> Option<BattleImpl>;
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
wasm_value_getters_extern! { wasm_value_getters_extern! {
PokemonImpl, Pokemon, PokemonImpl, Pokemon,
pub fn level(&self) -> LevelInt; pub fn level(&self) -> LevelInt;
pub fn experience(&self) -> u32; pub fn experience(&self) -> u32;
@ -389,45 +408,37 @@ wasm_value_getters_extern! {
pub fn is_ability_overriden(&self) -> u8; pub fn is_ability_overriden(&self) -> u8;
pub fn allowed_experience_gain(&self) -> bool; pub fn allowed_experience_gain(&self) -> bool;
pub fn is_usable(&self) -> bool; pub fn is_usable(&self) -> bool;
} }
impl PartialEq for PokemonImpl { impl PartialEq for PokemonImpl {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.inner.reference == other.inner.reference self.inner.reference == other.inner.reference
} }
} }
/// A source of damage. This should be as unique as possible. crate::handling::cacheable::cacheable!(PokemonImpl);
#[derive(Debug, Clone, Copy)]
#[repr(u8)]
pub enum DamageSource {
/// The damage is done by a move.
MoveDamage = 0,
/// The damage is done by something else.
Misc = 1,
/// The damage is done because of struggling.
Struggle = 2,
}
crate::handling::cacheable::cacheable!(PokemonImpl); #[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for PokemonImpl {
#[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for PokemonImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self { fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference) Self::new(reference)
} }
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn pokemon_get_library(r: ExternRef<PokemonImpl>) -> ExternRef<DynamicLibrary>; fn pokemon_get_library(r: ExternRef<PokemonImpl>) -> ExternRef<DynamicLibrary>;
fn pokemon_get_flat_stats(r: ExternRef<PokemonImpl>) -> ExternRef<StatisticSetImpl<u32>>; fn pokemon_get_flat_stats(r: ExternRef<PokemonImpl>) -> ExternRef<StatisticSetImpl<u32>>;
fn pokemon_get_stat_boosts(r: ExternRef<PokemonImpl>) -> ExternRef<ClampedStatisticSet<i8>>; fn pokemon_get_stat_boosts(r: ExternRef<PokemonImpl>)
fn pokemon_get_boosted_stats(r: ExternRef<PokemonImpl>) -> ExternRef<StatisticSetImpl<u32>>; -> ExternRef<ClampedStatisticSet<i8>>;
fn pokemon_get_boosted_stats(r: ExternRef<PokemonImpl>)
-> ExternRef<StatisticSetImpl<u32>>;
fn pokemon_get_individual_values( fn pokemon_get_individual_values(
r: ExternRef<PokemonImpl>, r: ExternRef<PokemonImpl>,
) -> ExternRef<ClampedStatisticSet<u8>>; ) -> ExternRef<ClampedStatisticSet<u8>>;
fn pokemon_get_effort_values(r: ExternRef<PokemonImpl>) -> ExternRef<ClampedStatisticSet<u8>>; fn pokemon_get_effort_values(
r: ExternRef<PokemonImpl>,
) -> ExternRef<ClampedStatisticSet<u8>>;
fn pokemon_has_held_item(r: ExternRef<PokemonImpl>, name: *const c_char) -> bool; fn pokemon_has_held_item(r: ExternRef<PokemonImpl>, name: *const c_char) -> bool;
fn pokemon_set_held_item( fn pokemon_set_held_item(
r: ExternRef<PokemonImpl>, r: ExternRef<PokemonImpl>,
@ -437,7 +448,10 @@ extern "wasm" {
fn pokemon_consume_held_item(r: ExternRef<PokemonImpl>) -> bool; fn pokemon_consume_held_item(r: ExternRef<PokemonImpl>) -> bool;
fn pokemon_get_type(r: ExternRef<PokemonImpl>, index: usize) -> u8; fn pokemon_get_type(r: ExternRef<PokemonImpl>, index: usize) -> u8;
fn pokemon_has_type(r: ExternRef<PokemonImpl>, identifier: u8) -> bool; fn pokemon_has_type(r: ExternRef<PokemonImpl>, identifier: u8) -> bool;
fn pokemon_get_learned_move(r: ExternRef<PokemonImpl>, index: usize) -> ExternRef<LearnedMove>; fn pokemon_get_learned_move(
r: ExternRef<PokemonImpl>,
index: usize,
) -> ExternRef<LearnedMove>;
fn pokemon_change_stat_boost( fn pokemon_change_stat_boost(
r: ExternRef<PokemonImpl>, r: ExternRef<PokemonImpl>,
tat: Statistic, tat: Statistic,
@ -457,9 +471,91 @@ extern "wasm" {
fn pokemon_set_weight(r: ExternRef<PokemonImpl>, weight: f32); fn pokemon_set_weight(r: ExternRef<PokemonImpl>, weight: f32);
fn pokemon_clear_status(r: ExternRef<PokemonImpl>); fn pokemon_clear_status(r: ExternRef<PokemonImpl>);
fn pokemon_add_volatile_by_name(r: ExternRef<PokemonImpl>, name: *const c_char) -> ScriptPtr; fn pokemon_add_volatile_by_name(
r: ExternRef<PokemonImpl>,
name: *const c_char,
) -> ScriptPtr;
fn pokemon_add_volatile(r: ExternRef<PokemonImpl>, script: ScriptPtr) -> ScriptPtr; fn pokemon_add_volatile(r: ExternRef<PokemonImpl>, script: ScriptPtr) -> ScriptPtr;
fn pokemon_has_volatile(r: ExternRef<PokemonImpl>, name: *const c_char) -> bool; fn pokemon_has_volatile(r: ExternRef<PokemonImpl>, name: *const c_char) -> bool;
fn pokemon_remove_volatile(r: ExternRef<PokemonImpl>, name: *const c_char); fn pokemon_remove_volatile(r: ExternRef<PokemonImpl>, name: *const c_char);
fn pokemon_get_volatile(r: ExternRef<PokemonImpl>, name: *const c_char) -> ScriptPtr; fn pokemon_get_volatile(r: ExternRef<PokemonImpl>, name: *const c_char) -> ScriptPtr;
}
}
#[cfg(feature = "mock_data")]
mockall::mock!(
pub Pokemon {}
impl PokemonTrait for Pokemon {
fn reference(&self) -> u32;
fn species(&self) -> Species;
fn form(&self) -> Form;
fn active_ability(&self) -> AbilityImpl;
fn nature(&self) -> Nature;
fn display_species(&self) -> Option<Species>;
fn display_form(&self) -> Option<Form>;
fn held_item(&self) -> Option<Item>;
fn battle(&self) -> Option<Battle>;
fn level(&self) -> LevelInt;
fn experience(&self) -> u32;
fn unique_identifier(&self) -> u32;
fn gender(&self) -> Gender;
fn coloring(&self) -> u8;
fn current_health(&self) -> u32;
fn weight(&self) -> f32;
fn height(&self) -> f32;
fn nickname(&self) -> *const c_char;
fn real_ability(&self) -> AbilityIndex;
fn types_length(&self) -> usize;
fn battle_side_index(&self) -> u8;
fn battle_index(&self) -> u8;
fn is_ability_overriden(&self) -> u8;
fn allowed_experience_gain(&self) -> bool;
fn is_usable(&self) -> bool;
fn library(&self) -> DynamicLibrary;
fn flat_stats(&self) -> StatisticSet<u32>;
fn stat_boosts(&self) -> ClampedStatisticSet<i8>;
fn boosted_stats(&self) -> StatisticSet<u32>;
fn individual_values(&self) -> ClampedStatisticSet<u8>;
fn effort_values(&self) -> ClampedStatisticSet<u8>;
fn has_held_item(&self, name: &str) -> bool;
fn set_held_item(&self, item: &Item) -> Option<Item>;
fn remove_held_item(&self) -> Option<Item>;
fn consume_held_item(&self) -> bool;
fn max_health(&self) -> u32;
fn get_type(&self, index: usize) -> u8;
fn has_type(&self, type_identifier: TypeIdentifier) -> bool;
fn has_type_by_name(&self, type_name: &str) -> bool;
fn get_learned_move(&self, index: usize) -> Option<LearnedMove>;
fn change_stat_boost(&self, stat: Statistic, diff_amount: i8, self_inflicted: bool) -> bool;
fn ability_script<'a>(&'a self) -> Option<&'a Box<dyn Script>>;
fn change_species(&self, species: Species, form: Form);
fn change_form(&self, form: Form);
fn is_fainted(&self) -> bool;
fn damage(&self, damage: u32, source: DamageSource);
fn heal(&self, amount: u32, allow_revive: bool) -> bool;
fn set_weight(&self, weight: f32);
fn clear_status(&self);
fn battle_side(&self) -> BattleSide;
fn equals(&self, other: &Pokemon) -> bool;
}
);
#[cfg(feature = "mock_data")]
impl WithVolatile for MockPokemon {
fn has_volatile(&self, script_name: &str) -> bool {
unimplemented!()
}
fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script {
unimplemented!()
}
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script {
unimplemented!()
}
fn remove_volatile<'a, 'b>(&'a self, script: &dyn Script) {
unimplemented!()
}
fn get_volatile_script<'a>(&'a self, script_name: &str) -> Option<&'a dyn Script> {
unimplemented!()
}
} }

View File

@ -1,4 +1,6 @@
use crate::app_interface::{LearnedMove, Pokemon, PokemonImpl}; #[cfg(not(feature = "mock_data"))]
use crate::app_interface::PokemonImpl;
use crate::app_interface::{LearnedMove, Pokemon};
use crate::handling::cached_value::CachedValue; use crate::handling::cached_value::CachedValue;
use crate::handling::temporary::Temporary; use crate::handling::temporary::Temporary;
use crate::ExternRef; use crate::ExternRef;
@ -14,6 +16,7 @@ pub trait BaseTurnChoiceDataTrait {
fn fail(&self); fn fail(&self);
} }
#[cfg(not(feature = "mock_data"))]
struct BaseTurnChoiceDataImpl { struct BaseTurnChoiceDataImpl {
reference: ExternRef<TurnChoice>, reference: ExternRef<TurnChoice>,
user: CachedValue<Rc<PokemonImpl>>, user: CachedValue<Rc<PokemonImpl>>,

View File

@ -3,7 +3,8 @@ use alloc::boxed::Box;
pub trait WithVolatile { pub trait WithVolatile {
fn has_volatile(&self, script_name: &str) -> bool; fn has_volatile(&self, script_name: &str) -> bool;
fn add_volatile<'a, 'b>(&'a self, script: Box<dyn Script>) -> &'b dyn Script; fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script;
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script;
fn remove_volatile(&self, script: &dyn Script); fn remove_volatile(&self, script: &dyn Script);
fn get_volatile_script(&self, script_name: &str) -> Option<&dyn Script>; fn get_volatile_script(&self, script_name: &str) -> Option<&dyn Script>;
} }

View File

@ -10,7 +10,7 @@ use alloc::vec::Vec;
use spin::RwLock; use spin::RwLock;
#[repr(u8)] #[repr(u8)]
#[derive(Eq, PartialEq)] #[derive(Eq, PartialEq, Debug)]
pub enum Gender { pub enum Gender {
Male = 0, Male = 0,
Female = 1, Female = 1,
@ -18,6 +18,7 @@ pub enum Gender {
} }
#[repr(u8)] #[repr(u8)]
#[derive(Eq, PartialEq, Debug)]
pub enum Statistic { pub enum Statistic {
HP = 0, HP = 0,
Attack = 1, Attack = 1,

View File

@ -1,7 +1,6 @@
use crate::app_interface::list::ImmutableList; use crate::app_interface::list::ImmutableList;
use crate::app_interface::{ use crate::app_interface::{
Battle, BattleImpl, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item, Battle, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item, Pokemon, Statistic,
Pokemon, Statistic,
}; };
use crate::handling::ScriptCapabilities; use crate::handling::ScriptCapabilities;
use crate::{ExternRef, ExternalReferenceType, ScriptPtr, StringKey, TurnChoice, TypeIdentifier}; use crate::{ExternRef, ExternalReferenceType, ScriptPtr, StringKey, TurnChoice, TypeIdentifier};

View File

@ -23,10 +23,13 @@ extern crate dlmalloc;
static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc {}; static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc {};
use crate::app_interface::list::ImmutableList; use crate::app_interface::list::ImmutableList;
#[cfg(not(feature = "mock_data"))]
use crate::app_interface::{BattleImpl, ExecutingMoveImpl, PokemonImpl};
use crate::app_interface::{ use crate::app_interface::{
BattleImpl, DamageSource, DynamicLibrary, EffectParameter, ExecutingMoveImpl, Item, ItemImpl, DamageSource, DynamicLibrary, EffectParameter, Item, ItemImpl, Pokemon, Statistic, StringKey,
Pokemon, PokemonImpl, Statistic, StringKey, TurnChoice, TypeIdentifier, TurnChoice, TypeIdentifier,
}; };
pub(crate) use crate::handling::extern_ref::*; pub(crate) use crate::handling::extern_ref::*;
use crate::handling::ffi_array::FFIArray; use crate::handling::ffi_array::FFIArray;
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]

View File

@ -1,4 +1,5 @@
use alloc::alloc::alloc; use alloc::alloc::alloc;
use alloc::string::String;
use core::alloc::Layout; use core::alloc::Layout;
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
use core::panic::PanicInfo; use core::panic::PanicInfo;
@ -22,9 +23,9 @@ pub fn print_raw(s: &[u8]) {
} }
#[cfg(feature = "mock_data")] #[cfg(feature = "mock_data")]
pub fn print_raw(s: CString) { pub fn print_raw(s: &[u8]) {
unsafe { unsafe {
println!("{}", s.into_string().unwrap()); println!("{}", String::from_utf8_lossy(s));
} }
} }