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

110 lines
3.6 KiB
Rust
Executable File

use crate::app_interface::{Battle, Pokemon};
use crate::handling::cacheable::Cacheable;
use crate::handling::cached_value::CachedValue;
use crate::{
cached_value, cached_value_getters, wasm_value_getters, ExternRef, ExternalReferenceType,
Script, ScriptPtr,
};
use alloc::boxed::Box;
use alloc::rc::Rc;
use cstr_core::{c_char, CString};
struct BattleSideInner {
reference: ExternRef<BattleSide>,
side_index: CachedValue<u8>,
pokemon_per_side: CachedValue<u8>,
battle: CachedValue<Battle>,
}
#[derive(Clone)]
pub struct BattleSide {
inner: Rc<BattleSideInner>,
}
impl BattleSide {
#[cfg(not(feature = "mock_data"))]
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) }),
pokemon_per_side: cached_value!({ battleside_get_pokemon_per_side(reference) }),
battle: cached_value!({ battleside_get_battle(reference).get_value().unwrap() }),
}),
})
}
cached_value_getters! {
pub fn side_index(&self) -> u8;
pub fn pokemon_per_side(&self) -> u8;
pub fn battle(&self) -> Battle;
}
#[cfg(not(feature = "mock_data"))]
pub fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
unsafe { battleside_get_pokemon(self.inner.reference, index).get_value() }
}
#[cfg(not(feature = "mock_data"))]
pub fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script {
unsafe {
battleside_add_volatile(self.inner.reference, ScriptPtr::new(script))
.val()
.unwrap()
}
}
#[cfg(not(feature = "mock_data"))]
pub fn remove_volatile(&self, script: &dyn Script) {
unsafe {
let name = CString::new(script.get_name()).unwrap();
battleside_remove_volatile(self.inner.reference, name.into_raw());
}
}
#[cfg(not(feature = "mock_data"))]
pub fn get_volatile<T>(&self, script_name: &str) -> Option<&T>
where
T: Script + 'static,
{
unsafe {
let script_name = CString::new(script_name).unwrap();
let s = battleside_get_volatile(self.inner.reference, script_name.into_raw()).val();
if let Some(s) = s {
Some(s.as_any().downcast_ref().unwrap())
} else {
None
}
}
}
}
wasm_value_getters! {
BattleSide,
pub fn has_fled_battle(&self) -> bool;
pub fn is_defeated(&self) -> bool;
}
crate::handling::cacheable::cacheable!(BattleSide);
#[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for BattleSide {
fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference)
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn battleside_get_side_index(r: ExternRef<BattleSide>) -> u8;
fn battleside_get_pokemon_per_side(r: ExternRef<BattleSide>) -> u8;
fn battleside_get_battle(r: ExternRef<BattleSide>) -> ExternRef<Battle>;
fn battleside_get_pokemon(r: ExternRef<BattleSide>, index: usize) -> ExternRef<Pokemon>;
fn battleside_add_volatile_by_name(r: ExternRef<BattleSide>, name: *const c_char) -> ScriptPtr;
fn battleside_add_volatile(r: ExternRef<BattleSide>, script: ScriptPtr) -> ScriptPtr;
fn battleside_has_volatile(r: ExternRef<BattleSide>, name: *const c_char) -> bool;
fn battleside_remove_volatile(r: ExternRef<BattleSide>, name: *const c_char);
fn battleside_get_volatile(r: ExternRef<BattleSide>, name: *const c_char) -> ScriptPtr;
}