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, side_index: CachedValue, pokemon_per_side: CachedValue, battle: CachedValue, } #[derive(Clone)] pub struct BattleSide { inner: Rc, } impl BattleSide { #[cfg(not(feature = "mock_data"))] pub fn new(reference: ExternRef) -> 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 { unsafe { battleside_get_pokemon(self.inner.reference, index).get_value() } } #[cfg(not(feature = "mock_data"))] pub fn add_volatile(&self, script: Box) -> &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(&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::new(reference) } } #[cfg(not(feature = "mock_data"))] extern "wasm" { fn battleside_get_side_index(r: ExternRef) -> u8; fn battleside_get_pokemon_per_side(r: ExternRef) -> u8; fn battleside_get_battle(r: ExternRef) -> ExternRef; fn battleside_get_pokemon(r: ExternRef, index: usize) -> ExternRef; fn battleside_add_volatile_by_name(r: ExternRef, name: *const c_char) -> ScriptPtr; fn battleside_add_volatile(r: ExternRef, script: ScriptPtr) -> ScriptPtr; fn battleside_has_volatile(r: ExternRef, name: *const c_char) -> bool; fn battleside_remove_volatile(r: ExternRef, name: *const c_char); fn battleside_get_volatile(r: ExternRef, name: *const c_char) -> ScriptPtr; }