Gen7ScriptsRs/pkmn_lib_interface/src/app_interface/dynamic_data/executing_move.rs

232 lines
8.4 KiB
Rust
Executable File

use crate::app_interface::{LearnedMove, MoveData, Pokemon};
use crate::handling::Script;
use alloc::rc::Rc;
#[cfg_attr(feature = "mock_data", mockall::automock)]
pub trait ExecutingMoveTrait {
fn number_of_hits(&self) -> u8;
fn user(&self) -> Pokemon;
fn chosen_move(&self) -> LearnedMove;
fn use_move(&self) -> MoveData;
fn move_script<'a>(&'a self) -> Option<&'a dyn Script>;
fn number_of_targets(&self) -> usize;
fn is_pokemon_target(&self, pokemon: &Pokemon) -> bool;
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>;
#[cfg(feature = "mock_data")]
pub type MockExecutingMove = MockExecutingMoveTrait;
pub type HitData = Rc<dyn HitDataTrait>;
#[cfg(feature = "mock_data")]
pub type MockHitData = MockHitDataTrait;
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;
#[cfg(not(feature = "mock_data"))]
mod implementation {
use super::*;
use crate::app_interface::{LearnedMoveImpl, MoveDataImpl, PokemonImpl};
use crate::cached_value;
use crate::handling::cached_value::CachedValue;
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
use crate::handling::temporary::Temporary;
#[derive(Clone)]
pub struct ExecutingMoveImpl {
inner: Temporary<ExecutingMoveInner>,
}
struct ExecutingMoveInner {
reference: ExternRef<ExecutingMoveImpl>,
number_of_hits: CachedValue<u8>,
user: CachedValue<Pokemon>,
chosen_move: CachedValue<Rc<LearnedMoveImpl>>,
use_move: CachedValue<MoveData>,
}
impl ExecutingMoveImpl {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
Self {
inner: Temporary::new(
reference.get_internal_index(),
ExecutingMoveInner {
reference,
number_of_hits: cached_value!({
executing_move_get_number_of_hits(reference)
}),
user: cached_value!({
Rc::new(executing_move_get_user(reference).get_value().unwrap())
}),
chosen_move: cached_value!({
Rc::new(
executing_move_get_chosen_move(reference)
.get_value()
.unwrap(),
)
}),
use_move: cached_value!({
Rc::new(executing_move_get_use_move(reference).get_value().unwrap())
}),
},
),
}
}
}
#[cfg(not(feature = "mock_data"))]
impl ExecutingMoveTrait for ExecutingMoveImpl {
fn number_of_hits(&self) -> u8 {
self.inner.value().number_of_hits.value()
}
fn user(&self) -> Pokemon {
self.inner.value().user.value()
}
fn chosen_move(&self) -> LearnedMove {
self.inner.value().chosen_move.value()
}
fn use_move(&self) -> MoveData {
self.inner.value().use_move.value()
}
fn move_script(&self) -> Option<&dyn Script> {
unsafe { executing_move_get_script(self.inner.value().reference).as_ref() }
}
fn number_of_targets(&self) -> usize {
unsafe { executing_move_get_number_of_targets(self.inner.value().reference) }
}
fn is_pokemon_target(&self, pokemon: &Pokemon) -> bool {
unsafe {
executing_move_is_pokemon_target(
self.inner.value().reference,
pokemon.reference().into(),
)
}
}
fn get_hit_data(&self, pokemon: &Pokemon, hit: u8) -> HitData {
unsafe {
Rc::new(
executing_move_get_hit_data(
self.inner.value().reference,
pokemon.reference().into(),
hit,
)
.get_value()
.unwrap(),
)
}
}
}
#[derive(Clone)]
pub struct HitDataImpl {
reference: ExternRef<HitDataImpl>,
}
#[cfg(not(feature = "mock_data"))]
impl HitDataTrait for HitDataImpl {
fn is_critical(&self) -> bool {
unsafe { hit_data_is_critical(self.reference) }
}
fn base_power(&self) -> u8 {
unsafe { hit_data_get_base_power(self.reference) }
}
fn effectiveness(&self) -> f32 {
unsafe { hit_data_get_effectiveness(self.reference) }
}
fn damage(&self) -> u32 {
unsafe { hit_data_get_damage(self.reference) }
}
fn move_type(&self) -> u8 {
unsafe { hit_data_get_move_type(self.reference) }
}
fn has_failed(&self) -> bool {
unsafe { hit_data_is_critical(self.reference) }
}
fn set_critical(&self, critical: bool) {
unsafe { hit_data_set_critical(self.reference, critical) }
}
fn set_effectiveness(&self, effectiveness: f32) {
unsafe { hit_data_set_effectiveness(self.reference, effectiveness) }
}
fn set_damage(&self, damage: u32) {
unsafe { hit_data_set_damage(self.reference, damage) }
}
fn set_move_type(&self, move_type: u8) {
unsafe { hit_data_set_move_type(self.reference, move_type) }
}
fn fail(&self) {
unsafe { hit_data_fail(self.reference) }
}
}
#[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for ExecutingMoveImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference)
}
}
#[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for HitDataImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self { reference }
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
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_user(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<PokemonImpl>;
fn executing_move_get_chosen_move(
r: ExternRef<ExecutingMoveImpl>,
) -> ExternRef<LearnedMoveImpl>;
fn executing_move_get_use_move(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<MoveDataImpl>;
#[allow(improper_ctypes)]
fn executing_move_get_script(r: ExternRef<ExecutingMoveImpl>) -> *const dyn Script;
fn executing_move_is_pokemon_target(
r: ExternRef<ExecutingMoveImpl>,
pokemon: ExternRef<PokemonImpl>,
) -> bool;
fn executing_move_get_hit_data(
r: ExternRef<ExecutingMoveImpl>,
target: ExternRef<PokemonImpl>,
hit: u8,
) -> ExternRef<HitDataImpl>;
fn hit_data_is_critical(r: ExternRef<HitDataImpl>) -> bool;
fn hit_data_get_base_power(r: ExternRef<HitDataImpl>) -> u8;
fn hit_data_get_effectiveness(r: ExternRef<HitDataImpl>) -> f32;
fn hit_data_get_damage(r: ExternRef<HitDataImpl>) -> u32;
fn hit_data_get_move_type(r: ExternRef<HitDataImpl>) -> u8;
fn hit_data_has_failed(r: ExternRef<HitDataImpl>) -> bool;
fn hit_data_set_critical(r: ExternRef<HitDataImpl>, critical: bool);
fn hit_data_set_base_power(r: ExternRef<HitDataImpl>, power: u8);
fn hit_data_set_effectiveness(r: ExternRef<HitDataImpl>, effectiveness: f32);
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_fail(r: ExternRef<HitDataImpl>);
}
}