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

190 lines
6.3 KiB
Rust
Executable File

use crate::app_interface::{Battle, Pokemon, WithVolatile};
use alloc::rc::Rc;
pub trait BattleSideTrait: WithVolatile {
fn side_index(&self) -> u8;
fn pokemon_per_side(&self) -> u8;
fn battle(&self) -> Battle;
fn get_pokemon(&self, index: usize) -> Option<Pokemon>;
fn has_fled_battle(&self) -> PkmnResult<bool>;
fn is_defeated(&self) -> PkmnResult<bool>;
}
pub type BattleSide = Rc<dyn BattleSideTrait>;
#[cfg(not(feature = "mock_data"))]
mod implementation {
use super::*;
use crate::app_interface::{BattleImpl, PokemonImpl};
use crate::handling::cached_value::CachedValue;
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
use crate::handling::wasm_result::{WasmResult, WasmVoidResult};
use crate::handling::{Cacheable, Script};
use crate::{
cached_value, cached_value_getters, wasm_value_getters_extern, wasm_value_getters_funcs,
PkmnResult, ScriptPtr,
};
use alloc::boxed::Box;
use cstr_core::{c_char, CString};
struct BattleSideInner {
reference: ExternRef<BattleSideImpl>,
side_index: CachedValue<u8>,
pokemon_per_side: CachedValue<u8>,
battle: CachedValue<Rc<BattleImpl>>,
}
#[derive(Clone)]
pub struct BattleSideImpl {
inner: Rc<BattleSideInner>,
}
impl BattleSideImpl {
pub fn new(reference: ExternRef<Self>) -> Self {
Self::from_ref(reference, &|reference| Self {
inner: Rc::new(BattleSideInner {
reference,
side_index: cached_value!({ battleside_get_side_index(reference).unwrap() }),
pokemon_per_side: cached_value!({
battleside_get_pokemon_per_side(reference).unwrap()
}),
battle: cached_value!({
Rc::new(
battleside_get_battle(reference)
.unwrap()
.get_value()
.unwrap(),
)
}),
}),
})
}
}
impl BattleSideTrait for BattleSideImpl {
cached_value_getters! {
fn side_index(&self) -> u8;
fn pokemon_per_side(&self) -> u8;
fn battle(&self) -> Battle;
}
fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
unsafe {
let p = battleside_get_pokemon(self.inner.reference, index)
.unwrap()
.get_value();
if let Some(p) = p {
Some(Rc::new(p))
} else {
None
}
}
}
wasm_value_getters_funcs! {
BattleSide,
fn has_fled_battle(&self) -> bool;
fn is_defeated(&self) -> bool;
}
}
impl WithVolatile for BattleSideImpl {
fn has_volatile(&self, script_name: &str) -> PkmnResult<bool> {
unsafe {
let script_name = CString::new(script_name).unwrap();
battleside_has_volatile(self.inner.reference, script_name.as_ptr()).as_res()
}
}
fn add_volatile(&self, script: Box<dyn Script>) -> PkmnResult<&dyn Script> {
unsafe {
Ok(
battleside_add_volatile(self.inner.reference, ScriptPtr::new(script))
.as_res()?
.val()
.unwrap(),
)
}
}
fn add_volatile_by_name(&self, script_name: &str) -> PkmnResult<&dyn Script> {
unsafe {
let ptr = CString::new(script_name).unwrap();
Ok(
battleside_add_volatile_by_name(self.inner.reference, ptr.as_ptr())
.as_res()?
.val()
.unwrap(),
)
}
}
fn remove_volatile(&self, script: &dyn Script) -> PkmnResult<()> {
unsafe {
let name = CString::new(script.get_name()).unwrap();
battleside_remove_volatile(self.inner.reference, name.as_ptr()).as_res()
}
}
fn get_volatile_script(&self, script_name: &str) -> PkmnResult<Option<&dyn Script>> {
let script_name = CString::new(script_name).unwrap();
unsafe {
Ok(
battleside_get_volatile(self.inner.reference, script_name.as_ptr())
.as_res()?
.val(),
)
}
}
}
wasm_value_getters_extern! {
BattleSideImpl, BattleSide,
pub fn has_fled_battle(&self) -> bool;
pub fn is_defeated(&self) -> bool;
}
crate::handling::cacheable::cacheable!(BattleSideImpl);
impl ExternalReferenceType for BattleSideImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference)
}
}
extern "wasm" {
fn battleside_get_side_index(r: ExternRef<BattleSideImpl>) -> WasmResult<u8>;
fn battleside_get_pokemon_per_side(r: ExternRef<BattleSideImpl>) -> WasmResult<u8>;
fn battleside_get_battle(r: ExternRef<BattleSideImpl>)
-> WasmResult<ExternRef<BattleImpl>>;
fn battleside_get_pokemon(
r: ExternRef<BattleSideImpl>,
index: usize,
) -> WasmResult<ExternRef<PokemonImpl>>;
fn battleside_add_volatile_by_name(
r: ExternRef<BattleSideImpl>,
name: *const c_char,
) -> WasmResult<ScriptPtr>;
fn battleside_add_volatile(
r: ExternRef<BattleSideImpl>,
script: ScriptPtr,
) -> WasmResult<ScriptPtr>;
fn battleside_has_volatile(
r: ExternRef<BattleSideImpl>,
name: *const c_char,
) -> WasmResult<bool>;
fn battleside_remove_volatile(
r: ExternRef<BattleSideImpl>,
name: *const c_char,
) -> WasmVoidResult;
fn battleside_get_volatile(
r: ExternRef<BattleSideImpl>,
name: *const c_char,
) -> WasmResult<ScriptPtr>;
}
}
use crate::PkmnResult;
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;