224 lines
8.2 KiB
Rust
Executable File
224 lines
8.2 KiB
Rust
Executable File
use alloc::rc::Rc;
|
|
|
|
use crate::app_interface::{
|
|
BattleParty, BattleRandom, BattleSide, ChoiceQueue, DynamicLibrary, Pokemon, StringKey,
|
|
};
|
|
use alloc::vec::Vec;
|
|
|
|
#[cfg_attr(feature = "mock_data", mockall::automock)]
|
|
pub trait BattleTrait {
|
|
fn library(&self) -> DynamicLibrary;
|
|
fn parties(&self) -> Vec<BattleParty>;
|
|
fn sides(&self) -> Vec<BattleSide>;
|
|
fn random(&self) -> BattleRandom;
|
|
fn choice_queue(&self) -> ChoiceQueue;
|
|
fn get_pokemon(&self, side: u8, index: u8) -> PkmnResult<Option<Pokemon>>;
|
|
fn find_party_for_pokemon(&self, pokemon: &Pokemon) -> PkmnResult<Option<BattleParty>>;
|
|
fn weather_name(&self) -> PkmnResult<Option<StringKey>>;
|
|
fn has_weather(&self, name: &str) -> PkmnResult<bool>;
|
|
fn can_flee(&self) -> PkmnResult<bool>;
|
|
fn number_of_sides(&self) -> PkmnResult<u8>;
|
|
fn pokemon_per_side(&self) -> PkmnResult<u8>;
|
|
fn has_ended(&self) -> PkmnResult<bool>;
|
|
fn has_ended_conclusively(&self) -> PkmnResult<bool>;
|
|
fn winning_side(&self) -> PkmnResult<u8>;
|
|
fn current_turn(&self) -> PkmnResult<u32>;
|
|
}
|
|
|
|
pub type Battle = Rc<dyn BattleTrait>;
|
|
#[cfg(feature = "mock_data")]
|
|
pub type MockBattle = MockBattleTrait;
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
mod implementation {
|
|
use super::*;
|
|
use crate::app_interface::dynamic_data::dynamic_library::DynamicLibraryImpl;
|
|
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::ffi_array::FFIArray;
|
|
use crate::handling::wasm_result::WasmResult;
|
|
use crate::handling::Cacheable;
|
|
use crate::{
|
|
cached_value, cached_value_getters, wasm_value_getters_extern, wasm_value_getters_funcs,
|
|
ExternRef, ExternalReferenceType, PkmnResult, StringKey,
|
|
};
|
|
use alloc::vec::Vec;
|
|
|
|
struct BattleInner {
|
|
reference: ExternRef<BattleImpl>,
|
|
library: CachedValue<DynamicLibrary>,
|
|
parties: CachedValue<Vec<BattleParty>>,
|
|
sides: CachedValue<Vec<BattleSide>>,
|
|
random: CachedValue<Rc<BattleRandomImpl>>,
|
|
choice_queue: CachedValue<Rc<ChoiceQueueImpl>>,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct BattleImpl {
|
|
inner: Rc<BattleInner>,
|
|
}
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
impl BattleImpl {
|
|
pub fn new(reference: ExternRef<BattleImpl>) -> Self {
|
|
Self::from_ref(reference, &|reference| Self {
|
|
inner: Rc::new(BattleInner {
|
|
reference,
|
|
library: cached_value!({
|
|
Rc::new(battle_get_library(reference).unwrap().get_value().unwrap())
|
|
}),
|
|
parties: cached_value!({
|
|
let parties: FFIArray<ExternRef<BattlePartyImpl>> =
|
|
FFIArray::from_u64(battle_get_parties(reference).unwrap());
|
|
let parties =
|
|
Vec::from_raw_parts(parties.ptr(), parties.len(), parties.len());
|
|
let parties = parties
|
|
.into_iter()
|
|
.map::<BattleParty, _>(|r| Rc::new(BattlePartyImpl::new(r)))
|
|
.collect::<Vec<_>>();
|
|
parties
|
|
}),
|
|
sides: cached_value!({
|
|
let sides: FFIArray<ExternRef<BattleSideImpl>> =
|
|
FFIArray::from_u64(battle_get_sides(reference).unwrap());
|
|
let sides = Vec::from_raw_parts(sides.ptr(), sides.len(), sides.len());
|
|
let sides = sides
|
|
.into_iter()
|
|
.map::<BattleSide, _>(|r| Rc::new(BattleSideImpl::new(r)))
|
|
.collect::<Vec<_>>();
|
|
sides
|
|
}),
|
|
random: cached_value!({
|
|
Rc::new(battle_get_random(reference).unwrap().get_value().unwrap())
|
|
}),
|
|
choice_queue: cached_value!({
|
|
Rc::new(
|
|
battle_get_choice_queue(reference)
|
|
.unwrap()
|
|
.get_value()
|
|
.unwrap(),
|
|
)
|
|
}),
|
|
}),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
impl BattleTrait for BattleImpl {
|
|
cached_value_getters! {
|
|
fn library(&self) -> DynamicLibrary;
|
|
fn parties(&self) -> Vec<BattleParty>;
|
|
fn sides(&self) -> Vec<BattleSide>;
|
|
fn random(&self) -> BattleRandom;
|
|
fn choice_queue(&self) -> ChoiceQueue;
|
|
}
|
|
|
|
fn get_pokemon(&self, side: u8, index: u8) -> PkmnResult<Option<Pokemon>> {
|
|
unsafe {
|
|
let v = battle_get_pokemon(self.inner.reference, side, index)
|
|
.as_res()?
|
|
.get_value();
|
|
if let Some(v) = v {
|
|
Ok(Some(Rc::new(v)))
|
|
} else {
|
|
Ok(None)
|
|
}
|
|
}
|
|
}
|
|
|
|
fn find_party_for_pokemon(&self, pokemon: &Pokemon) -> PkmnResult<Option<BattleParty>> {
|
|
unsafe {
|
|
let b =
|
|
battle_find_party_for_pokemon(self.inner.reference, pokemon.reference().into())
|
|
.as_res()?
|
|
.get_value();
|
|
Ok(if let Some(b) = b {
|
|
Some(Rc::new(b))
|
|
} else {
|
|
None
|
|
})
|
|
}
|
|
}
|
|
|
|
fn weather_name(&self) -> PkmnResult<Option<StringKey>> {
|
|
unsafe {
|
|
Ok(battle_get_weather_name(self.inner.reference)
|
|
.as_res()?
|
|
.get_value())
|
|
}
|
|
}
|
|
fn has_weather(&self, name: &str) -> PkmnResult<bool> {
|
|
if let Some(weather) = self.weather_name()? {
|
|
if weather.equals_str(name) {
|
|
return Ok(true);
|
|
}
|
|
}
|
|
Ok(false)
|
|
}
|
|
|
|
wasm_value_getters_funcs! {
|
|
Battle,
|
|
fn can_flee(&self) -> bool;
|
|
fn number_of_sides(&self) -> u8;
|
|
fn pokemon_per_side(&self) -> u8;
|
|
fn has_ended(&self) -> bool;
|
|
fn has_ended_conclusively(&self) -> bool;
|
|
fn winning_side(&self) -> u8;
|
|
fn current_turn(&self) -> u32;
|
|
}
|
|
}
|
|
|
|
wasm_value_getters_extern! {
|
|
BattleImpl, Battle,
|
|
pub fn can_flee(&self) -> bool;
|
|
pub fn number_of_sides(&self) -> u8;
|
|
pub fn pokemon_per_side(&self) -> u8;
|
|
pub fn has_ended(&self) -> bool;
|
|
pub fn has_ended_conclusively(&self) -> bool;
|
|
pub fn winning_side(&self) -> u8;
|
|
pub fn current_turn(&self) -> u32;
|
|
}
|
|
|
|
crate::handling::cacheable::cacheable!(BattleImpl);
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
impl ExternalReferenceType for BattleImpl {
|
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
|
Self::new(reference)
|
|
}
|
|
}
|
|
|
|
#[cfg(not(feature = "mock_data"))]
|
|
extern "wasm" {
|
|
fn battle_get_library(
|
|
r: ExternRef<BattleImpl>,
|
|
) -> WasmResult<ExternRef<DynamicLibraryImpl>>;
|
|
fn battle_get_parties(r: ExternRef<BattleImpl>) -> WasmResult<u64>;
|
|
fn battle_get_sides(r: ExternRef<BattleImpl>) -> WasmResult<u64>;
|
|
fn battle_get_random(r: ExternRef<BattleImpl>) -> WasmResult<ExternRef<BattleRandomImpl>>;
|
|
fn battle_get_choice_queue(
|
|
r: ExternRef<BattleImpl>,
|
|
) -> WasmResult<ExternRef<ChoiceQueueImpl>>;
|
|
fn battle_get_pokemon(
|
|
r: ExternRef<BattleImpl>,
|
|
side: u8,
|
|
index: u8,
|
|
) -> WasmResult<ExternRef<PokemonImpl>>;
|
|
fn battle_find_party_for_pokemon(
|
|
r: ExternRef<BattleImpl>,
|
|
mon: ExternRef<PokemonImpl>,
|
|
) -> WasmResult<ExternRef<BattlePartyImpl>>;
|
|
|
|
fn battle_get_weather_name(r: ExternRef<BattleImpl>) -> WasmResult<ExternRef<StringKey>>;
|
|
}
|
|
}
|
|
|
|
use crate::PkmnResult;
|
|
#[cfg(not(feature = "mock_data"))]
|
|
pub use implementation::*;
|