More work on mocking and removing the impls from the interface
This commit is contained in:
		| @@ -8,6 +8,7 @@ | |||||||
| extern crate alloc; | extern crate alloc; | ||||||
|  |  | ||||||
| use alloc::boxed::Box; | use alloc::boxed::Box; | ||||||
|  | #[cfg(not(test))] | ||||||
| use pkmn_lib_interface::set_load_script_fn; | use pkmn_lib_interface::set_load_script_fn; | ||||||
|  |  | ||||||
| #[macro_use] | #[macro_use] | ||||||
|   | |||||||
| @@ -39,3 +39,36 @@ impl Script for AfterYou { | |||||||
|         self |         self | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(test)] | ||||||
|  | mod tests { | ||||||
|  |     use super::*; | ||||||
|  |     use alloc::rc::Rc; | ||||||
|  |     use pkmn_lib_interface::app_interface::{ | ||||||
|  |         MockBattle, MockChoiceQueue, MockExecutingMove, MockPokemon, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn move_pokemon_choice_next_gets_called_once() { | ||||||
|  |         let mut battle = MockBattle::new(); | ||||||
|  |         battle.expect_choice_queue().once().return_once_st(move || { | ||||||
|  |             let mut choice_queue = MockChoiceQueue::new(); | ||||||
|  |             choice_queue | ||||||
|  |                 .expect_move_pokemon_choice_next() | ||||||
|  |                 .once() | ||||||
|  |                 .return_const(true); | ||||||
|  |             Rc::new(choice_queue) | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         let battle = Rc::new(battle); | ||||||
|  |         let mut target = MockPokemon::new(); | ||||||
|  |         target | ||||||
|  |             .expect_battle() | ||||||
|  |             .once() | ||||||
|  |             .return_once_st(move || Some(battle.clone())); | ||||||
|  |         let target = Rc::new(target); | ||||||
|  |  | ||||||
|  |         let script = AfterYou::new(); | ||||||
|  |         script.on_secondary_effect(Rc::new(MockExecutingMove::new()), target, 0); | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -3,8 +3,7 @@ use alloc::boxed::Box; | |||||||
| use core::any::Any; | use core::any::Any; | ||||||
| use core::sync::atomic::{AtomicBool, Ordering}; | use core::sync::atomic::{AtomicBool, Ordering}; | ||||||
| use pkmn_lib_interface::app_interface::{ | use pkmn_lib_interface::app_interface::{ | ||||||
|     BattleSide, BattleSideImpl, DamageSource, DataLibrary, ExecutingMove, Pokemon, TurnChoice, |     BattleSide, DamageSource, DataLibrary, ExecutingMove, Pokemon, TurnChoice, WithVolatile, | ||||||
|     WithVolatile, |  | ||||||
| }; | }; | ||||||
| use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; | use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; | ||||||
|  |  | ||||||
| @@ -26,10 +25,9 @@ impl Script for Assurance { | |||||||
|         ] |         ] | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[cfg(not(test))] |  | ||||||
|     fn on_before_turn(&self, choice: TurnChoice) { |     fn on_before_turn(&self, choice: TurnChoice) { | ||||||
|         if let TurnChoice::Move(data) = &choice { |         if let TurnChoice::Move(data) = &choice { | ||||||
|             let side: BattleSideImpl = choice |             let side: BattleSide = choice | ||||||
|                 .user() |                 .user() | ||||||
|                 .battle() |                 .battle() | ||||||
|                 .unwrap() |                 .unwrap() | ||||||
| @@ -90,7 +88,7 @@ impl Script for AssuranceData { | |||||||
|  |  | ||||||
|     #[cfg(not(test))] |     #[cfg(not(test))] | ||||||
|     fn on_end_turn(&self) { |     fn on_end_turn(&self) { | ||||||
|         let side: BattleSideImpl = self.get_owner().unwrap(); |         let side: pkmn_lib_interface::app_interface::BattleSideImpl = self.get_owner().unwrap(); | ||||||
|         side.remove_volatile(self); |         side.remove_volatile(self); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ use alloc::boxed::Box; | |||||||
| use core::any::Any; | use core::any::Any; | ||||||
| use core::sync::atomic::{AtomicU32, Ordering}; | use core::sync::atomic::{AtomicU32, Ordering}; | ||||||
| use pkmn_lib_interface::app_interface::{ | use pkmn_lib_interface::app_interface::{ | ||||||
|     BattleSide, BattleSideImpl, ExecutingMove, MoveCategory, Pokemon, WithVolatile, |     BattleSide, ExecutingMove, MoveCategory, Pokemon, WithVolatile, | ||||||
| }; | }; | ||||||
| use pkmn_lib_interface::handling::ScriptCapabilities::OnEndTurn; | use pkmn_lib_interface::handling::ScriptCapabilities::OnEndTurn; | ||||||
| use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; | use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; | ||||||
| @@ -76,7 +76,7 @@ impl Script for AuroraVeilEffect { | |||||||
|         if mv.get_hit_data(&target, hit).is_critical() { |         if mv.get_hit_data(&target, hit).is_critical() { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         let side: BattleSideImpl = self.get_owner().unwrap(); |         let side: pkmn_lib_interface::app_interface::BattleSideImpl = self.get_owner().unwrap(); | ||||||
|         if side.has_volatile(ReflectEffect::get_const_name()) |         if side.has_volatile(ReflectEffect::get_const_name()) | ||||||
|             && mv.use_move().category() == MoveCategory::Physical |             && mv.use_move().category() == MoveCategory::Physical | ||||||
|         { |         { | ||||||
|   | |||||||
| @@ -1,7 +1,8 @@ | |||||||
| use crate::script; | use crate::script; | ||||||
|  | use alloc::rc::Rc; | ||||||
| use core::any::Any; | use core::any::Any; | ||||||
| use core::sync::atomic::{AtomicI8, Ordering}; | use core::sync::atomic::{AtomicI8, Ordering}; | ||||||
| use pkmn_lib_interface::app_interface::list::ImmutableList; | use pkmn_lib_interface::app_interface::list::{ImmutableList, ImmutableListTrait}; | ||||||
| use pkmn_lib_interface::app_interface::{ | use pkmn_lib_interface::app_interface::{ | ||||||
|     DynamicLibrary, EffectParameter, ExecutingMove, Pokemon, Statistic, |     DynamicLibrary, EffectParameter, ExecutingMove, Pokemon, Statistic, | ||||||
| }; | }; | ||||||
| @@ -34,7 +35,7 @@ impl Script for ChangeAllTargetStats { | |||||||
|     fn on_initialize( |     fn on_initialize( | ||||||
|         &self, |         &self, | ||||||
|         _library: &DynamicLibrary, |         _library: &DynamicLibrary, | ||||||
|         parameters: Option<ImmutableList<EffectParameter>>, |         parameters: Option<ImmutableList<Rc<EffectParameter>>>, | ||||||
|     ) { |     ) { | ||||||
|         self.amount.store( |         self.amount.store( | ||||||
|             parameters.unwrap().get(0).unwrap().as_int() as i8, |             parameters.unwrap().get(0).unwrap().as_int() as i8, | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | use alloc::rc::Rc; | ||||||
| use core::any::Any; | use core::any::Any; | ||||||
| use core::sync::atomic::{AtomicI8, Ordering}; | use core::sync::atomic::{AtomicI8, Ordering}; | ||||||
| use pkmn_lib_interface::app_interface::list::ImmutableList; | use pkmn_lib_interface::app_interface::list::ImmutableList; | ||||||
| @@ -42,7 +43,7 @@ macro_rules! change_stat_effect { | |||||||
|                 fn on_initialize( |                 fn on_initialize( | ||||||
|                     &self, |                     &self, | ||||||
|                     _library: &DynamicLibrary, |                     _library: &DynamicLibrary, | ||||||
|                     parameters: Option<ImmutableList<EffectParameter>>, |                     parameters: Option<ImmutableList<Rc<EffectParameter>>>, | ||||||
|                 ) { |                 ) { | ||||||
|                     self.amount.store( |                     self.amount.store( | ||||||
|                         parameters.unwrap().get(0).unwrap().as_int() as i8, |                         parameters.unwrap().get(0).unwrap().as_int() as i8, | ||||||
|   | |||||||
| @@ -1,8 +1,9 @@ | |||||||
| use crate::script; | use crate::script; | ||||||
|  | use alloc::rc::Rc; | ||||||
| use atomic_float::AtomicF32; | use atomic_float::AtomicF32; | ||||||
| use core::any::Any; | use core::any::Any; | ||||||
| use core::sync::atomic::Ordering; | use core::sync::atomic::Ordering; | ||||||
| use pkmn_lib_interface::app_interface::list::ImmutableList; | use pkmn_lib_interface::app_interface::list::{ImmutableList, ImmutableListTrait}; | ||||||
| use pkmn_lib_interface::app_interface::{DynamicLibrary, EffectParameter, ExecutingMove, Pokemon}; | use pkmn_lib_interface::app_interface::{DynamicLibrary, EffectParameter, ExecutingMove, Pokemon}; | ||||||
| use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; | use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; | ||||||
|  |  | ||||||
| @@ -29,7 +30,7 @@ impl Script for Drain { | |||||||
|     fn on_initialize( |     fn on_initialize( | ||||||
|         &self, |         &self, | ||||||
|         _library: &DynamicLibrary, |         _library: &DynamicLibrary, | ||||||
|         parameters: Option<ImmutableList<EffectParameter>>, |         parameters: Option<ImmutableList<Rc<EffectParameter>>>, | ||||||
|     ) { |     ) { | ||||||
|         self.heal_modifier.store( |         self.heal_modifier.store( | ||||||
|             parameters.unwrap().get(0).unwrap().as_float(), |             parameters.unwrap().get(0).unwrap().as_float(), | ||||||
|   | |||||||
| @@ -1,16 +1,16 @@ | |||||||
| use alloc::rc::Rc; | use alloc::rc::Rc; | ||||||
|  |  | ||||||
| use crate::app_interface::list::ImmutableList; | use crate::app_interface::list::ImmutableList; | ||||||
| use crate::app_interface::BattleSideImpl; |  | ||||||
| use crate::app_interface::{ | use crate::app_interface::{ | ||||||
|     BattleParty, BattlePartyImpl, BattleRandom, ChoiceQueue, DynamicLibrary, Pokemon, StringKey, |     BattleParty, BattlePartyImpl, BattleRandom, BattleSide, ChoiceQueue, DynamicLibrary, Pokemon, | ||||||
|  |     StringKey, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #[cfg_attr(feature = "mock_data", mockall::automock)] | #[cfg_attr(feature = "mock_data", mockall::automock)] | ||||||
| pub trait BattleTrait { | pub trait BattleTrait { | ||||||
|     fn library(&self) -> DynamicLibrary; |     fn library(&self) -> DynamicLibrary; | ||||||
|     fn parties(&self) -> ImmutableList<BattlePartyImpl>; |     fn parties(&self) -> ImmutableList<BattleParty>; | ||||||
|     fn sides(&self) -> ImmutableList<BattleSideImpl>; |     fn sides(&self) -> ImmutableList<BattleSide>; | ||||||
|     fn random(&self) -> BattleRandom; |     fn random(&self) -> BattleRandom; | ||||||
|     fn choice_queue(&self) -> ChoiceQueue; |     fn choice_queue(&self) -> ChoiceQueue; | ||||||
|     fn get_pokemon(&self, side: u8, index: u8) -> Option<Pokemon>; |     fn get_pokemon(&self, side: u8, index: u8) -> Option<Pokemon>; | ||||||
| @@ -33,6 +33,9 @@ pub type MockBattle = MockBattleTrait; | |||||||
| #[cfg(not(feature = "mock_data"))] | #[cfg(not(feature = "mock_data"))] | ||||||
| mod implementation { | mod implementation { | ||||||
|     use super::*; |     use super::*; | ||||||
|  |     use crate::app_interface::list::{ | ||||||
|  |         BattlePartyImmutableList, BattleSideImmutableList, ImmutableListWasm, | ||||||
|  |     }; | ||||||
|     use crate::app_interface::PokemonImpl; |     use crate::app_interface::PokemonImpl; | ||||||
|     use crate::app_interface::{ |     use crate::app_interface::{ | ||||||
|         BattleParty, BattlePartyImpl, BattleRandom, BattleRandomImpl, BattleSide, BattleSideImpl, |         BattleParty, BattlePartyImpl, BattleRandom, BattleRandomImpl, BattleSide, BattleSideImpl, | ||||||
| @@ -42,15 +45,14 @@ mod implementation { | |||||||
|     use crate::handling::Cacheable; |     use crate::handling::Cacheable; | ||||||
|     use crate::{ |     use crate::{ | ||||||
|         cached_value, cached_value_getters, wasm_value_getters, wasm_value_getters_extern, |         cached_value, cached_value_getters, wasm_value_getters, wasm_value_getters_extern, | ||||||
|         wasm_value_getters_funcs, DynamicLibrary, ExternRef, ExternalReferenceType, ImmutableList, |         wasm_value_getters_funcs, ExternRef, ExternalReferenceType, StringKey, VecExternRef, | ||||||
|         StringKey, VecExternRef, |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     struct BattleInner { |     struct BattleInner { | ||||||
|         reference: ExternRef<BattleImpl>, |         reference: ExternRef<BattleImpl>, | ||||||
|         library: CachedValue<DynamicLibrary>, |         library: CachedValue<DynamicLibrary>, | ||||||
|         parties: CachedValue<ImmutableList<BattlePartyImpl>>, |         parties: CachedValue<ImmutableList<BattleParty>>, | ||||||
|         sides: CachedValue<ImmutableList<BattleSideImpl>>, |         sides: CachedValue<ImmutableList<BattleSide>>, | ||||||
|         random: CachedValue<Rc<BattleRandomImpl>>, |         random: CachedValue<Rc<BattleRandomImpl>>, | ||||||
|         choice_queue: CachedValue<Rc<ChoiceQueueImpl>>, |         choice_queue: CachedValue<Rc<ChoiceQueueImpl>>, | ||||||
|     } |     } | ||||||
| @@ -67,8 +69,14 @@ mod implementation { | |||||||
|                 inner: Rc::new(BattleInner { |                 inner: Rc::new(BattleInner { | ||||||
|                     reference, |                     reference, | ||||||
|                     library: cached_value!({ battle_get_library(reference).get_value().unwrap() }), |                     library: cached_value!({ battle_get_library(reference).get_value().unwrap() }), | ||||||
|                     parties: cached_value!({ battle_get_parties(reference).get_immutable_list() }), |                     parties: cached_value!({ | ||||||
|                     sides: cached_value!({ battle_get_sides(reference).get_immutable_list() }), |                         let reference = battle_get_parties(reference); | ||||||
|  |                         Rc::new(BattlePartyImmutableList::from_ref(reference)) | ||||||
|  |                     }), | ||||||
|  |                     sides: cached_value!({ | ||||||
|  |                         let reference = battle_get_sides(reference); | ||||||
|  |                         Rc::new(BattleSideImmutableList::from_ref(reference)) | ||||||
|  |                     }), | ||||||
|                     random: cached_value!({ |                     random: cached_value!({ | ||||||
|                         Rc::new(battle_get_random(reference).get_value().unwrap()) |                         Rc::new(battle_get_random(reference).get_value().unwrap()) | ||||||
|                     }), |                     }), | ||||||
| @@ -84,8 +92,8 @@ mod implementation { | |||||||
|     impl BattleTrait for BattleImpl { |     impl BattleTrait for BattleImpl { | ||||||
|         cached_value_getters! { |         cached_value_getters! { | ||||||
|             fn library(&self) -> DynamicLibrary; |             fn library(&self) -> DynamicLibrary; | ||||||
|             fn parties(&self) -> ImmutableList<BattlePartyImpl>; |             fn parties(&self) -> ImmutableList<BattleParty>; | ||||||
|             fn sides(&self) -> ImmutableList<BattleSideImpl>; |             fn sides(&self) -> ImmutableList<BattleSide>; | ||||||
|             fn random(&self) -> BattleRandom; |             fn random(&self) -> BattleRandom; | ||||||
|             fn choice_queue(&self) -> ChoiceQueue; |             fn choice_queue(&self) -> ChoiceQueue; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1,15 +1,5 @@ | |||||||
| use crate::app_interface::{Battle, Pokemon, WithVolatile}; | use crate::app_interface::{Battle, Pokemon, WithVolatile}; | ||||||
| #[cfg(not(feature = "mock_data"))] |  | ||||||
| use crate::app_interface::{BattleImpl, PokemonImpl}; |  | ||||||
| use crate::handling::cacheable::Cacheable; |  | ||||||
| use crate::handling::cached_value::CachedValue; |  | ||||||
| use crate::{ |  | ||||||
|     cached_value, cached_value_getters, wasm_value_getters, wasm_value_getters_extern, |  | ||||||
|     wasm_value_getters_funcs, ExternRef, ExternalReferenceType, Script, ScriptPtr, |  | ||||||
| }; |  | ||||||
| use alloc::boxed::Box; |  | ||||||
| use alloc::rc::Rc; | use alloc::rc::Rc; | ||||||
| use cstr_core::{c_char, CString}; |  | ||||||
|  |  | ||||||
| pub trait BattleSideTrait: WithVolatile { | pub trait BattleSideTrait: WithVolatile { | ||||||
|     fn side_index(&self) -> u8; |     fn side_index(&self) -> u8; | ||||||
| @@ -23,128 +13,141 @@ pub trait BattleSideTrait: WithVolatile { | |||||||
| pub type BattleSide = Rc<dyn BattleSideTrait>; | pub type BattleSide = Rc<dyn BattleSideTrait>; | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] | #[cfg(not(feature = "mock_data"))] | ||||||
| struct BattleSideInner { | mod implementation { | ||||||
|     reference: ExternRef<BattleSideImpl>, |     use super::*; | ||||||
|     side_index: CachedValue<u8>, |     use crate::app_interface::{BattleImpl, PokemonImpl}; | ||||||
|     pokemon_per_side: CachedValue<u8>, |     use crate::handling::cached_value::CachedValue; | ||||||
|     battle: CachedValue<Rc<BattleImpl>>, |     use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; | ||||||
| } |     use crate::handling::{Cacheable, Script}; | ||||||
|  |     use crate::{ | ||||||
|  |         cached_value, cached_value_getters, wasm_value_getters_extern, wasm_value_getters_funcs, | ||||||
|  |         ScriptPtr, | ||||||
|  |     }; | ||||||
|  |     use alloc::boxed::Box; | ||||||
|  |     use cstr_core::{c_char, CString}; | ||||||
|  |  | ||||||
| #[derive(Clone)] |     struct BattleSideInner { | ||||||
| pub struct BattleSideImpl { |         reference: ExternRef<BattleSideImpl>, | ||||||
|     #[cfg(not(feature = "mock_data"))] |         side_index: CachedValue<u8>, | ||||||
|     inner: Rc<BattleSideInner>, |         pokemon_per_side: CachedValue<u8>, | ||||||
| } |         battle: CachedValue<Rc<BattleImpl>>, | ||||||
|  |     } | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] |     #[derive(Clone)] | ||||||
| impl BattleSideImpl { |     pub struct BattleSideImpl { | ||||||
|     pub fn new(reference: ExternRef<Self>) -> Self { |         inner: Rc<BattleSideInner>, | ||||||
|         Self::from_ref(reference, &|reference| Self { |     } | ||||||
|             inner: Rc::new(BattleSideInner { |  | ||||||
|                 reference, |     impl BattleSideImpl { | ||||||
|                 side_index: cached_value!({ battleside_get_side_index(reference) }), |         pub fn new(reference: ExternRef<Self>) -> Self { | ||||||
|                 pokemon_per_side: cached_value!({ battleside_get_pokemon_per_side(reference) }), |             Self::from_ref(reference, &|reference| Self { | ||||||
|                 battle: cached_value!({ |                 inner: Rc::new(BattleSideInner { | ||||||
|                     Rc::new(battleside_get_battle(reference).get_value().unwrap()) |                     reference, | ||||||
|  |                     side_index: cached_value!({ battleside_get_side_index(reference) }), | ||||||
|  |                     pokemon_per_side: cached_value!({ battleside_get_pokemon_per_side(reference) }), | ||||||
|  |                     battle: cached_value!({ | ||||||
|  |                         Rc::new(battleside_get_battle(reference).get_value().unwrap()) | ||||||
|  |                     }), | ||||||
|                 }), |                 }), | ||||||
|             }), |             }) | ||||||
|         }) |         } | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] |  | ||||||
| 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> { |     impl BattleSideTrait for BattleSideImpl { | ||||||
|         unsafe { |         cached_value_getters! { | ||||||
|             let p = battleside_get_pokemon(self.inner.reference, index).get_value(); |             fn side_index(&self) -> u8; | ||||||
|             if let Some(p) = p { |             fn pokemon_per_side(&self) -> u8; | ||||||
|                 Some(Rc::new(p)) |             fn battle(&self) -> Battle; | ||||||
|             } else { |         } | ||||||
|                 None |  | ||||||
|  |         fn get_pokemon(&self, index: usize) -> Option<Pokemon> { | ||||||
|  |             unsafe { | ||||||
|  |                 let p = battleside_get_pokemon(self.inner.reference, index).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; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     wasm_value_getters_funcs! { |     impl WithVolatile for BattleSideImpl { | ||||||
|         BattleSide, |         fn has_volatile(&self, script_name: &str) -> bool { | ||||||
|         fn has_fled_battle(&self) -> bool; |             unsafe { | ||||||
|         fn is_defeated(&self) -> bool; |                 let script_name = CString::new(script_name).unwrap(); | ||||||
|     } |                 battleside_has_volatile(self.inner.reference, script_name.as_ptr()) | ||||||
| } |             } | ||||||
|  |         } | ||||||
|  |         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"))] |         fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script { | ||||||
| impl WithVolatile for BattleSideImpl { |             unsafe { | ||||||
|     fn has_volatile(&self, script_name: &str) -> bool { |                 let ptr = CString::new(script_name).unwrap(); | ||||||
|         unsafe { |                 battleside_add_volatile_by_name(self.inner.reference, ptr.as_ptr()) | ||||||
|  |                     .val() | ||||||
|  |                     .unwrap() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fn remove_volatile(&self, script: &dyn Script) { | ||||||
|  |             unsafe { | ||||||
|  |                 let name = CString::new(script.get_name()).unwrap(); | ||||||
|  |                 battleside_remove_volatile(self.inner.reference, name.as_ptr()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fn get_volatile_script(&self, script_name: &str) -> Option<&dyn Script> { | ||||||
|             let script_name = CString::new(script_name).unwrap(); |             let script_name = CString::new(script_name).unwrap(); | ||||||
|             battleside_has_volatile(self.inner.reference, script_name.as_ptr()) |             unsafe { battleside_get_volatile(self.inner.reference, script_name.as_ptr()).val() } | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script { |  | ||||||
|         unsafe { |  | ||||||
|             battleside_add_volatile(self.inner.reference, ScriptPtr::new(script)) |  | ||||||
|                 .val() |  | ||||||
|                 .unwrap() |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script { |     wasm_value_getters_extern! { | ||||||
|         unsafe { |         BattleSideImpl, BattleSide, | ||||||
|             let ptr = CString::new(script_name).unwrap(); |         pub fn has_fled_battle(&self) -> bool; | ||||||
|             battleside_add_volatile_by_name(self.inner.reference, ptr.as_ptr()) |         pub fn is_defeated(&self) -> bool; | ||||||
|                 .val() |     } | ||||||
|                 .unwrap() |  | ||||||
|  |     crate::handling::cacheable::cacheable!(BattleSideImpl); | ||||||
|  |  | ||||||
|  |     impl ExternalReferenceType for BattleSideImpl { | ||||||
|  |         fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||||
|  |             Self::new(reference) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn remove_volatile(&self, script: &dyn Script) { |     extern "wasm" { | ||||||
|         unsafe { |         fn battleside_get_side_index(r: ExternRef<BattleSideImpl>) -> u8; | ||||||
|             let name = CString::new(script.get_name()).unwrap(); |         fn battleside_get_pokemon_per_side(r: ExternRef<BattleSideImpl>) -> u8; | ||||||
|             battleside_remove_volatile(self.inner.reference, name.as_ptr()); |         fn battleside_get_battle(r: ExternRef<BattleSideImpl>) -> ExternRef<BattleImpl>; | ||||||
|         } |         fn battleside_get_pokemon( | ||||||
|     } |             r: ExternRef<BattleSideImpl>, | ||||||
|  |             index: usize, | ||||||
|  |         ) -> ExternRef<PokemonImpl>; | ||||||
|  |  | ||||||
|     fn get_volatile_script(&self, script_name: &str) -> Option<&dyn Script> { |         fn battleside_add_volatile_by_name( | ||||||
|         let script_name = CString::new(script_name).unwrap(); |             r: ExternRef<BattleSideImpl>, | ||||||
|         unsafe { battleside_get_volatile(self.inner.reference, script_name.as_ptr()).val() } |             name: *const c_char, | ||||||
|     } |         ) -> ScriptPtr; | ||||||
| } |         fn battleside_add_volatile(r: ExternRef<BattleSideImpl>, script: ScriptPtr) -> ScriptPtr; | ||||||
|  |         fn battleside_has_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char) -> bool; | ||||||
| wasm_value_getters_extern! { |         fn battleside_remove_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char); | ||||||
|     BattleSideImpl, BattleSide, |         fn battleside_get_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char) -> ScriptPtr; | ||||||
|     pub fn has_fled_battle(&self) -> bool; |  | ||||||
|     pub fn is_defeated(&self) -> bool; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| crate::handling::cacheable::cacheable!(BattleSideImpl); |  | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] |  | ||||||
| impl ExternalReferenceType for BattleSideImpl { |  | ||||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { |  | ||||||
|         Self::new(reference) |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] | #[cfg(not(feature = "mock_data"))] | ||||||
| extern "wasm" { | pub use implementation::*; | ||||||
|     fn battleside_get_side_index(r: ExternRef<BattleSideImpl>) -> u8; |  | ||||||
|     fn battleside_get_pokemon_per_side(r: ExternRef<BattleSideImpl>) -> u8; |  | ||||||
|     fn battleside_get_battle(r: ExternRef<BattleSideImpl>) -> ExternRef<BattleImpl>; |  | ||||||
|     fn battleside_get_pokemon(r: ExternRef<BattleSideImpl>, index: usize) |  | ||||||
|         -> ExternRef<PokemonImpl>; |  | ||||||
|  |  | ||||||
|     fn battleside_add_volatile_by_name( |  | ||||||
|         r: ExternRef<BattleSideImpl>, |  | ||||||
|         name: *const c_char, |  | ||||||
|     ) -> ScriptPtr; |  | ||||||
|     fn battleside_add_volatile(r: ExternRef<BattleSideImpl>, script: ScriptPtr) -> ScriptPtr; |  | ||||||
|     fn battleside_has_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char) -> bool; |  | ||||||
|     fn battleside_remove_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char); |  | ||||||
|     fn battleside_get_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char) -> ScriptPtr; |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -1,44 +1,53 @@ | |||||||
| #[cfg(not(feature = "mock_data"))] | use crate::app_interface::Pokemon; | ||||||
| use crate::app_interface::PokemonImpl; |  | ||||||
| use crate::{ExternRef, ExternalReferenceType, Pokemon}; |  | ||||||
| use alloc::rc::Rc; | use alloc::rc::Rc; | ||||||
|  |  | ||||||
|  | #[cfg_attr(feature = "mock_data", mockall::automock)] | ||||||
| pub trait ChoiceQueueTrait { | pub trait ChoiceQueueTrait { | ||||||
|     fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> bool; |     fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> bool; | ||||||
| } | } | ||||||
|  |  | ||||||
| pub type ChoiceQueue = Rc<dyn ChoiceQueueTrait>; | pub type ChoiceQueue = Rc<dyn ChoiceQueueTrait>; | ||||||
|  | #[cfg(feature = "mock_data")] | ||||||
| #[derive(Clone)] | pub type MockChoiceQueue = MockChoiceQueueTrait; | ||||||
| pub struct ChoiceQueueImpl { |  | ||||||
|     reference: ExternRef<ChoiceQueueImpl>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] | #[cfg(not(feature = "mock_data"))] | ||||||
| impl ChoiceQueueImpl { | mod implementation { | ||||||
|     pub fn new(reference: ExternRef<ChoiceQueueImpl>) -> Self { |     use super::*; | ||||||
|         Self { reference } |     use crate::app_interface::PokemonImpl; | ||||||
|  |     use crate::{ExternRef, ExternalReferenceType}; | ||||||
|  |  | ||||||
|  |     #[derive(Clone)] | ||||||
|  |     pub struct ChoiceQueueImpl { | ||||||
|  |         reference: ExternRef<ChoiceQueueImpl>, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl ChoiceQueueImpl { | ||||||
|  |         pub fn new(reference: ExternRef<ChoiceQueueImpl>) -> Self { | ||||||
|  |             Self { reference } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl ChoiceQueueTrait for ChoiceQueueImpl { | ||||||
|  |         fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> bool { | ||||||
|  |             unsafe { | ||||||
|  |                 choice_queue_move_pokemon_choice_next(self.reference, pokemon.reference().into()) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl ExternalReferenceType for ChoiceQueueImpl { | ||||||
|  |         fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||||
|  |             Self::new(reference) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     extern "wasm" { | ||||||
|  |         fn choice_queue_move_pokemon_choice_next( | ||||||
|  |             r: ExternRef<ChoiceQueueImpl>, | ||||||
|  |             pokemon: ExternRef<PokemonImpl>, | ||||||
|  |         ) -> bool; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] | #[cfg(not(feature = "mock_data"))] | ||||||
| impl ChoiceQueueTrait for ChoiceQueueImpl { | pub use implementation::*; | ||||||
|     fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> bool { |  | ||||||
|         unsafe { choice_queue_move_pokemon_choice_next(self.reference, pokemon.reference().into()) } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] |  | ||||||
| impl ExternalReferenceType for ChoiceQueueImpl { |  | ||||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { |  | ||||||
|         Self::new(reference) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] |  | ||||||
| extern "wasm" { |  | ||||||
|     fn choice_queue_move_pokemon_choice_next( |  | ||||||
|         r: ExternRef<ChoiceQueueImpl>, |  | ||||||
|         pokemon: ExternRef<PokemonImpl>, |  | ||||||
|     ) -> bool; |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| use crate::app_interface::{ | use crate::app_interface::{ | ||||||
|     AbilityImpl, AbilityIndex, Battle, BattleSide, ClampedStatisticSet, DynamicLibrary, Form, |     Ability, AbilityIndex, Battle, BattleSide, ClampedStatisticSet, DynamicLibrary, Form, Gender, | ||||||
|     Gender, Item, LearnedMove, LevelInt, Nature, Species, Statistic, StatisticSet, TypeIdentifier, |     Item, LearnedMove, LevelInt, Nature, Species, Statistic, StatisticSet, TypeIdentifier, | ||||||
|     WithVolatile, |     WithVolatile, | ||||||
| }; | }; | ||||||
| use crate::handling::Script; | use crate::handling::Script; | ||||||
| @@ -16,7 +16,7 @@ pub trait PokemonTrait: WithVolatile { | |||||||
|  |  | ||||||
|     fn species(&self) -> Species; |     fn species(&self) -> Species; | ||||||
|     fn form(&self) -> Form; |     fn form(&self) -> Form; | ||||||
|     fn active_ability(&self) -> AbilityImpl; |     fn active_ability(&self) -> Ability; | ||||||
|     fn nature(&self) -> Nature; |     fn nature(&self) -> Nature; | ||||||
|     fn display_species(&self) -> Option<Species>; |     fn display_species(&self) -> Option<Species>; | ||||||
|     fn display_form(&self) -> Option<Form>; |     fn display_form(&self) -> Option<Form>; | ||||||
| @@ -86,14 +86,15 @@ mod implementation { | |||||||
|     use super::*; |     use super::*; | ||||||
|     use cstr_core::CString; |     use cstr_core::CString; | ||||||
|  |  | ||||||
|     use crate::app_interface::{BattleImpl, ItemImpl, StatisticSetImpl}; |     use crate::app_interface::{AbilityImpl, BattleImpl, ItemImpl, StatisticSetImpl}; | ||||||
|     use crate::handling::cached_value::CachedValue; |     use crate::handling::cached_value::CachedValue; | ||||||
|     use crate::handling::Cacheable; |     use crate::handling::Cacheable; | ||||||
|  |     use crate::implementation::ScriptPtr; | ||||||
|     use crate::{ |     use crate::{ | ||||||
|         cached_value, cached_value_getters, wasm_optional_reference_getters_extern, |         cached_value, cached_value_getters, wasm_optional_reference_getters_extern, | ||||||
|         wasm_optional_reference_getters_funcs, wasm_reference_getters_extern, |         wasm_optional_reference_getters_funcs, wasm_reference_getters_extern, | ||||||
|         wasm_reference_getters_funcs, wasm_value_getters_extern, wasm_value_getters_funcs, |         wasm_reference_getters_funcs, wasm_value_getters_extern, wasm_value_getters_funcs, | ||||||
|         DynamicLibrary, ExternRef, ExternalReferenceType, Script, ScriptPtr, TypeIdentifier, |         ExternRef, ExternalReferenceType, Script, | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     struct PokemonInner { |     struct PokemonInner { | ||||||
| @@ -234,23 +235,29 @@ mod implementation { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         fn battle_side(&self) -> BattleSide { |         fn battle_side(&self) -> BattleSide { | ||||||
|             Rc::new( |             self.battle() | ||||||
|                 self.battle() |                 .unwrap() | ||||||
|                     .unwrap() |                 .sides() | ||||||
|                     .sides() |                 .get(self.battle_side_index() as u32) | ||||||
|                     .get(self.battle_side_index() as u32) |                 .unwrap() | ||||||
|                     .unwrap(), |  | ||||||
|             ) |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         wasm_reference_getters_funcs! { |         wasm_reference_getters_funcs! { | ||||||
|             Pokemon, |             Pokemon, | ||||||
|             fn species(&self) -> Species; |             fn species(&self) -> Species; | ||||||
|             fn form(&self) -> Form; |             fn form(&self) -> Form; | ||||||
|             fn active_ability(&self) -> AbilityImpl; |  | ||||||
|             fn nature(&self) -> Nature; |             fn nature(&self) -> Nature; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         fn active_ability(&self) -> Ability { | ||||||
|  |             unsafe { | ||||||
|  |                 let implementation = pokemon_get_active_ability(self.reference()) | ||||||
|  |                     .get_value() | ||||||
|  |                     .unwrap(); | ||||||
|  |                 Rc::new(implementation) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         wasm_optional_reference_getters_funcs! { |         wasm_optional_reference_getters_funcs! { | ||||||
|             Pokemon, |             Pokemon, | ||||||
|             fn display_species(&self) -> Option<Species>; |             fn display_species(&self) -> Option<Species>; | ||||||
| @@ -338,7 +345,6 @@ mod implementation { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[cfg(not(feature = "mock_data"))] |  | ||||||
|     impl PokemonImpl { |     impl PokemonImpl { | ||||||
|         pub(crate) fn new(reference: ExternRef<Self>) -> Self { |         pub(crate) fn new(reference: ExternRef<Self>) -> Self { | ||||||
|             Self::from_ref(reference, &|reference| Self { |             Self::from_ref(reference, &|reference| Self { | ||||||
| @@ -371,7 +377,6 @@ mod implementation { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[cfg(not(feature = "mock_data"))] |  | ||||||
|     wasm_reference_getters_extern! { |     wasm_reference_getters_extern! { | ||||||
|         PokemonImpl, Pokemon, |         PokemonImpl, Pokemon, | ||||||
|         pub fn species(&self) -> Species; |         pub fn species(&self) -> Species; | ||||||
| @@ -380,7 +385,6 @@ mod implementation { | |||||||
|         pub fn nature(&self) -> Nature; |         pub fn nature(&self) -> Nature; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[cfg(not(feature = "mock_data"))] |  | ||||||
|     wasm_optional_reference_getters_extern! { |     wasm_optional_reference_getters_extern! { | ||||||
|         PokemonImpl, Pokemon, |         PokemonImpl, Pokemon, | ||||||
|         pub fn display_species(&self) -> Option<Species>; |         pub fn display_species(&self) -> Option<Species>; | ||||||
| @@ -389,7 +393,6 @@ mod implementation { | |||||||
|         pub fn battle(&self) -> Option<BattleImpl>; |         pub fn battle(&self) -> Option<BattleImpl>; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[cfg(not(feature = "mock_data"))] |  | ||||||
|     wasm_value_getters_extern! { |     wasm_value_getters_extern! { | ||||||
|         PokemonImpl, Pokemon, |         PokemonImpl, Pokemon, | ||||||
|         pub fn level(&self) -> LevelInt; |         pub fn level(&self) -> LevelInt; | ||||||
| @@ -418,14 +421,12 @@ mod implementation { | |||||||
|  |  | ||||||
|     crate::handling::cacheable::cacheable!(PokemonImpl); |     crate::handling::cacheable::cacheable!(PokemonImpl); | ||||||
|  |  | ||||||
|     #[cfg(not(feature = "mock_data"))] |  | ||||||
|     impl ExternalReferenceType for PokemonImpl { |     impl ExternalReferenceType for PokemonImpl { | ||||||
|         fn from_extern_value(reference: ExternRef<Self>) -> Self { |         fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||||
|             Self::new(reference) |             Self::new(reference) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[cfg(not(feature = "mock_data"))] |  | ||||||
|     extern "wasm" { |     extern "wasm" { | ||||||
|         fn pokemon_get_library(r: ExternRef<PokemonImpl>) -> ExternRef<DynamicLibrary>; |         fn pokemon_get_library(r: ExternRef<PokemonImpl>) -> ExternRef<DynamicLibrary>; | ||||||
|         fn pokemon_get_flat_stats(r: ExternRef<PokemonImpl>) -> ExternRef<StatisticSetImpl<u32>>; |         fn pokemon_get_flat_stats(r: ExternRef<PokemonImpl>) -> ExternRef<StatisticSetImpl<u32>>; | ||||||
| @@ -489,7 +490,7 @@ mockall::mock!( | |||||||
|         fn reference(&self) -> u32; |         fn reference(&self) -> u32; | ||||||
|         fn species(&self) -> Species; |         fn species(&self) -> Species; | ||||||
|         fn form(&self) -> Form; |         fn form(&self) -> Form; | ||||||
|         fn active_ability(&self) -> AbilityImpl; |         fn active_ability(&self) -> Ability; | ||||||
|         fn nature(&self) -> Nature; |         fn nature(&self) -> Nature; | ||||||
|         fn display_species(&self) -> Option<Species>; |         fn display_species(&self) -> Option<Species>; | ||||||
|         fn display_form(&self) -> Option<Form>; |         fn display_form(&self) -> Option<Form>; | ||||||
|   | |||||||
| @@ -1,114 +1,205 @@ | |||||||
| use crate::{ExternalReferenceType, VecExternRef}; | use crate::{ExternalReferenceType, VecExternRef}; | ||||||
| use alloc::boxed::Box; |  | ||||||
| #[cfg(feature = "mock_data")] |  | ||||||
| use alloc::rc::Rc; | use alloc::rc::Rc; | ||||||
| use alloc::vec::Vec; |  | ||||||
| use core::marker::PhantomData; |  | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] | pub trait ImmutableListTrait<T> { | ||||||
| struct ImmutableListInner<T: Clone> { |     fn get(&self, index: u32) -> Option<T>; | ||||||
|     extern_ref: VecExternRef<T>, |  | ||||||
|     resource_type: PhantomData<T>, |  | ||||||
|     values: spin::RwLock<Vec<Option<Option<T>>>>, |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Clone)] | pub type ImmutableList<T> = Rc<dyn ImmutableListTrait<T>>; | ||||||
| #[cfg(not(feature = "mock_data"))] |  | ||||||
| pub struct ImmutableList<T> |  | ||||||
| where |  | ||||||
|     T: Clone, |  | ||||||
|     T: ExternalReferenceType, |  | ||||||
| { |  | ||||||
|     inner: *const ImmutableListInner<T>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] | #[cfg(not(feature = "mock_data"))] | ||||||
| impl<T> ImmutableList<T> | mod implementation { | ||||||
| where |     use super::*; | ||||||
|     T: Clone, |     use crate::app_interface::{ | ||||||
|     T: ExternalReferenceType, |         BattleParty, BattlePartyImpl, BattleSide, BattleSideImpl, EffectParameter, StringKey, | ||||||
| { |     }; | ||||||
|     fn new(extern_ref: VecExternRef<T>) -> Self { |     use crate::handling::extern_ref::{ExternalReferenceType, VecExternRef}; | ||||||
|         let mut values = Vec::new(); |     use alloc::boxed::Box; | ||||||
|         values.resize(extern_ref.len() as usize, None); |     use alloc::vec::Vec; | ||||||
|         let inner = Box::new(ImmutableListInner { |     use core::marker::PhantomData; | ||||||
|             extern_ref, |  | ||||||
|             resource_type: Default::default(), |     pub(crate) struct ImmutableListInner<T: Clone> { | ||||||
|             values: spin::RwLock::new(values), |         extern_ref: VecExternRef<T>, | ||||||
|         }); |         resource_type: PhantomData<T>, | ||||||
|         let inner_ptr = Box::into_raw(inner); |         values: spin::RwLock<Vec<Option<Option<Rc<T>>>>>, | ||||||
|         ImmutableList { |  | ||||||
|             inner: inner_ptr as *const ImmutableListInner<T>, |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub(crate) fn from_ref(extern_ref: VecExternRef<T>) -> Self { |     pub(crate) trait ImmutableListWasm<T: Clone + ExternalReferenceType> { | ||||||
|         unsafe { |         fn initialize(inner: *const ImmutableListInner<T>) -> Self | ||||||
|             if let None = CACHE { |         where | ||||||
|                 CACHE = Some(hashbrown::HashMap::new()); |             Self: Sized; | ||||||
|             } |  | ||||||
|             let existing = CACHE |         fn new(extern_ref: VecExternRef<T>) -> Self | ||||||
|                 .as_ref() |         where | ||||||
|                 .unwrap() |             Self: Sized, | ||||||
|                 .get(&extern_ref.get_internal_index()); |         { | ||||||
|             if let Some(v) = existing { |             let mut values = Vec::new(); | ||||||
|                 let inner = *v as *const ImmutableListInner<T>; |             values.resize(extern_ref.len() as usize, None); | ||||||
|                 ImmutableList { inner } |             let inner = Box::new(ImmutableListInner { | ||||||
|             } else { |                 extern_ref, | ||||||
|                 let v = Self::new(extern_ref); |                 resource_type: Default::default(), | ||||||
|                 CACHE |                 values: spin::RwLock::new(values), | ||||||
|                     .as_mut() |             }); | ||||||
|  |             let inner_ptr = Box::into_raw(inner); | ||||||
|  |             Self::initialize(inner_ptr) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fn from_ref(extern_ref: VecExternRef<T>) -> Self | ||||||
|  |         where | ||||||
|  |             Self: Sized, | ||||||
|  |         { | ||||||
|  |             unsafe { | ||||||
|  |                 if let None = CACHE { | ||||||
|  |                     CACHE = Some(hashbrown::HashMap::new()); | ||||||
|  |                 } | ||||||
|  |                 let existing = CACHE | ||||||
|  |                     .as_ref() | ||||||
|                     .unwrap() |                     .unwrap() | ||||||
|                     .insert(extern_ref.get_internal_index(), v.inner as *const u8); |                     .get(&extern_ref.get_internal_index()); | ||||||
|                 v |                 if let Some(v) = existing { | ||||||
|             } |                     let inner = *v as *const ImmutableListInner<T>; | ||||||
|         } |                     Self::initialize(inner) | ||||||
|     } |                 } else { | ||||||
|  |                     let v = Self::new(extern_ref); | ||||||
|     pub fn get(&self, index: u32) -> Option<T> { |                     CACHE.as_mut().unwrap().insert( | ||||||
|         unsafe { |                         extern_ref.get_internal_index(), | ||||||
|             let inner = self.inner.as_ref().unwrap(); |                         v.get_inner_ptr() as *const u8, | ||||||
|             { |                     ); | ||||||
|                 let rg = inner.values.read(); |                     v | ||||||
|                 let v = rg.get(index as usize).unwrap(); |  | ||||||
|                 if let Some(v) = v { |  | ||||||
|                     return v.clone(); |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fn get_inner(&self) -> &ImmutableListInner<T> { | ||||||
|  |             unsafe { self.get_inner_ptr().as_ref().unwrap() } | ||||||
|  |         } | ||||||
|  |         fn get_inner_ptr(&self) -> *const ImmutableListInner<T>; | ||||||
|  |  | ||||||
|  |         fn get_cached(&self, index: u32) -> Option<Rc<T>> { | ||||||
|  |             let inner = self.get_inner(); | ||||||
|  |             let rg = inner.values.read(); | ||||||
|  |             let v = rg.get(index as usize).unwrap(); | ||||||
|  |             if let Some(v) = v { | ||||||
|  |                 return v.clone(); | ||||||
|  |             } | ||||||
|  |             return None; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fn get_value(&self, index: u32) -> Option<Rc<T>> { | ||||||
|  |             if let Some(cached) = self.get_cached(index) { | ||||||
|  |                 return Some(cached); | ||||||
|  |             } | ||||||
|  |             let inner = self.get_inner(); | ||||||
|             let r = inner.extern_ref.at(index); |             let r = inner.extern_ref.at(index); | ||||||
|             let value = r.get_value(); |             let value = r.get_value(); | ||||||
|  |             let value = if let Some(value) = value { | ||||||
|  |                 Some(Rc::new(value)) | ||||||
|  |             } else { | ||||||
|  |                 None | ||||||
|  |             }; | ||||||
|             let mut wg = inner.values.write(); |             let mut wg = inner.values.write(); | ||||||
|             wg[index as usize] = Some(value); |             wg[index as usize] = Some(value); | ||||||
|             wg[index as usize].as_ref().unwrap().clone() |             let v = wg[index as usize].as_ref().unwrap().clone(); | ||||||
|         } |             v | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(feature = "mock_data")] |  | ||||||
| pub struct ImmutableListInner<T> { |  | ||||||
|     values: Vec<T>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(feature = "mock_data")] |  | ||||||
| #[derive(Clone)] |  | ||||||
| pub struct ImmutableList<T> { |  | ||||||
|     inner: Rc<ImmutableListInner<T>>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(feature = "mock_data")] |  | ||||||
| impl<T> ImmutableList<T> |  | ||||||
| where |  | ||||||
|     T: Clone, |  | ||||||
| { |  | ||||||
|     pub fn mock(values: Vec<T>) -> Self { |  | ||||||
|         Self { |  | ||||||
|             inner: Rc::new(ImmutableListInner { values }), |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub fn get(&self, index: u32) -> Option<T> { |     macro_rules! immutable_list_type { | ||||||
|         self.inner.values.get(index as usize).cloned() |         ($type_name:ident, $underlying:ident) => { | ||||||
|  |             paste::paste! { | ||||||
|  |                 pub struct [<$type_name ImmutableList>] { | ||||||
|  |                     inner: *const ImmutableListInner<$underlying>, | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 impl ImmutableListWasm<$underlying> for [<$type_name ImmutableList>] { | ||||||
|  |                     fn initialize(inner: *const ImmutableListInner<$underlying>) -> Self | ||||||
|  |                     where | ||||||
|  |                         Self: Sized, | ||||||
|  |                     { | ||||||
|  |                         Self { inner } | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     fn get_inner_ptr(&self) -> *const ImmutableListInner<$underlying> { | ||||||
|  |                         self.inner | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 impl ImmutableListTrait<$type_name> for [<$type_name ImmutableList>] { | ||||||
|  |                     fn get(&self, index: u32) -> Option<$type_name> { | ||||||
|  |                         let v = self.get_value(index); | ||||||
|  |                         if let Some(v) = v { | ||||||
|  |                             Some(v) | ||||||
|  |                         } else { | ||||||
|  |                             None | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     immutable_list_type!(BattleSide, BattleSideImpl); | ||||||
|  |     immutable_list_type!(BattleParty, BattlePartyImpl); | ||||||
|  |  | ||||||
|  |     pub struct EffectParameterImmutableList { | ||||||
|  |         inner: *const ImmutableListInner<EffectParameter>, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl ImmutableListWasm<EffectParameter> for EffectParameterImmutableList { | ||||||
|  |         fn initialize(inner: *const ImmutableListInner<EffectParameter>) -> Self | ||||||
|  |         where | ||||||
|  |             Self: Sized, | ||||||
|  |         { | ||||||
|  |             Self { inner } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fn get_inner_ptr(&self) -> *const ImmutableListInner<EffectParameter> { | ||||||
|  |             self.inner | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl ImmutableListTrait<Rc<EffectParameter>> for EffectParameterImmutableList { | ||||||
|  |         fn get(&self, index: u32) -> Option<Rc<EffectParameter>> { | ||||||
|  |             let v = self.get_value(index); | ||||||
|  |             if let Some(v) = v { | ||||||
|  |                 Some(v) | ||||||
|  |             } else { | ||||||
|  |                 None | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[derive(Clone)] | ||||||
|  |     pub struct StringKeyImmutableList { | ||||||
|  |         inner: *const ImmutableListInner<StringKey>, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl ImmutableListWasm<StringKey> for StringKeyImmutableList { | ||||||
|  |         fn initialize(inner: *const ImmutableListInner<StringKey>) -> Self | ||||||
|  |         where | ||||||
|  |             Self: Sized, | ||||||
|  |         { | ||||||
|  |             Self { inner } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         fn get_inner_ptr(&self) -> *const ImmutableListInner<StringKey> { | ||||||
|  |             self.inner | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl ImmutableListTrait<Rc<StringKey>> for StringKeyImmutableList { | ||||||
|  |         fn get(&self, index: u32) -> Option<Rc<StringKey>> { | ||||||
|  |             let v = self.get_value(index); | ||||||
|  |             if let Some(v) = v { | ||||||
|  |                 Some(v) | ||||||
|  |             } else { | ||||||
|  |                 None | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static mut CACHE: Option<hashbrown::HashMap<u32, *const u8>> = None; | ||||||
| } | } | ||||||
|  |  | ||||||
| static mut CACHE: Option<hashbrown::HashMap<u32, *const u8>> = None; | #[cfg(not(feature = "mock_data"))] | ||||||
|  | pub use implementation::*; | ||||||
|   | |||||||
| @@ -1,60 +1,13 @@ | |||||||
| use crate::handling::cacheable::Cacheable; | use crate::StringKey; | ||||||
| use crate::handling::cached_value::CachedValue; |  | ||||||
| use crate::{ |  | ||||||
|     cached_value, cached_value_getters, EffectParameter, ExternRef, ExternalReferenceType, |  | ||||||
|     ImmutableList, StringKey, VecExternRef, |  | ||||||
| }; |  | ||||||
| use alloc::rc::Rc; | use alloc::rc::Rc; | ||||||
|  |  | ||||||
| struct AbilityInner { |  | ||||||
|     reference: ExternRef<AbilityImpl>, |  | ||||||
|     name: CachedValue<StringKey>, |  | ||||||
|     effect: CachedValue<StringKey>, |  | ||||||
|     parameters: CachedValue<ImmutableList<EffectParameter>>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg_attr(test, mockall::automock)] | #[cfg_attr(test, mockall::automock)] | ||||||
| pub trait Ability { | pub trait AbilityTrait { | ||||||
|     fn name(&self) -> StringKey; |     fn name(&self) -> StringKey; | ||||||
|     fn effect(&self) -> StringKey; |     fn effect(&self) -> StringKey; | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Clone)] | pub type Ability = Rc<dyn AbilityTrait>; | ||||||
| pub struct AbilityImpl { |  | ||||||
|     inner: Rc<AbilityInner>, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl AbilityImpl { |  | ||||||
|     #[cfg(not(feature = "mock_data"))] |  | ||||||
|     pub fn new(reference: ExternRef<Self>) -> Self { |  | ||||||
|         Self::from_ref(reference, &|reference| Self { |  | ||||||
|             inner: Rc::new(AbilityInner { |  | ||||||
|                 reference, |  | ||||||
|                 name: cached_value!({ ability_get_name(reference).get_value().unwrap() }), |  | ||||||
|                 effect: cached_value!({ ability_get_effect(reference).get_value().unwrap() }), |  | ||||||
|                 parameters: cached_value!({ |  | ||||||
|                     ability_get_parameters(reference).get_immutable_list() |  | ||||||
|                 }), |  | ||||||
|             }), |  | ||||||
|         }) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| impl Ability for AbilityImpl { |  | ||||||
|     cached_value_getters! { |  | ||||||
|         fn name(&self) -> StringKey; |  | ||||||
|         fn effect(&self) -> StringKey; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] |  | ||||||
| impl ExternalReferenceType for AbilityImpl { |  | ||||||
|     fn from_extern_value(reference: ExternRef<Self>) -> Self { |  | ||||||
|         Self::new(reference) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| crate::handling::cacheable::cacheable!(AbilityImpl); |  | ||||||
|  |  | ||||||
| #[derive(Copy, Clone, Debug, Eq, PartialEq)] | #[derive(Copy, Clone, Debug, Eq, PartialEq)] | ||||||
| #[repr(C)] | #[repr(C)] | ||||||
| @@ -64,8 +17,71 @@ pub struct AbilityIndex { | |||||||
| } | } | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] | #[cfg(not(feature = "mock_data"))] | ||||||
| extern "wasm" { | mod implementation { | ||||||
|     fn ability_get_name(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>; |     use super::*; | ||||||
|     fn ability_get_effect(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>; |     use crate::app_interface::list::{ | ||||||
|     fn ability_get_parameters(r: ExternRef<AbilityImpl>) -> VecExternRef<EffectParameter>; |         EffectParameterImmutableList, ImmutableList, ImmutableListWasm, | ||||||
|  |     }; | ||||||
|  |     use crate::app_interface::{EffectParameter, StringKey}; | ||||||
|  |     use crate::handling::cached_value::CachedValue; | ||||||
|  |     use crate::handling::extern_ref::{ExternRef, ExternalReferenceType, VecExternRef}; | ||||||
|  |     use crate::handling::Cacheable; | ||||||
|  |     use crate::{cached_value, cached_value_getters}; | ||||||
|  |     use alloc::rc::Rc; | ||||||
|  |  | ||||||
|  |     struct AbilityInner { | ||||||
|  |         reference: ExternRef<AbilityImpl>, | ||||||
|  |         name: CachedValue<StringKey>, | ||||||
|  |         effect: CachedValue<StringKey>, | ||||||
|  |         parameters: CachedValue<ImmutableList<Rc<EffectParameter>>>, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[derive(Clone)] | ||||||
|  |     pub struct AbilityImpl { | ||||||
|  |         inner: Rc<AbilityInner>, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl AbilityImpl { | ||||||
|  |         #[cfg(not(feature = "mock_data"))] | ||||||
|  |         pub fn new(reference: ExternRef<Self>) -> Self { | ||||||
|  |             Self::from_ref(reference, &|reference| Self { | ||||||
|  |                 inner: Rc::new(AbilityInner { | ||||||
|  |                     reference, | ||||||
|  |                     name: cached_value!({ ability_get_name(reference).get_value().unwrap() }), | ||||||
|  |                     effect: cached_value!({ ability_get_effect(reference).get_value().unwrap() }), | ||||||
|  |                     parameters: cached_value!({ | ||||||
|  |                         Rc::new(EffectParameterImmutableList::from_ref( | ||||||
|  |                             ability_get_parameters(reference), | ||||||
|  |                         )) | ||||||
|  |                     }), | ||||||
|  |                 }), | ||||||
|  |             }) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     impl AbilityTrait for AbilityImpl { | ||||||
|  |         cached_value_getters! { | ||||||
|  |             fn name(&self) -> StringKey; | ||||||
|  |             fn effect(&self) -> StringKey; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     #[cfg(not(feature = "mock_data"))] | ||||||
|  |     impl ExternalReferenceType for AbilityImpl { | ||||||
|  |         fn from_extern_value(reference: ExternRef<Self>) -> Self { | ||||||
|  |             Self::new(reference) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     crate::handling::cacheable::cacheable!(AbilityImpl); | ||||||
|  |  | ||||||
|  |     #[cfg(not(feature = "mock_data"))] | ||||||
|  |     extern "wasm" { | ||||||
|  |         fn ability_get_name(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>; | ||||||
|  |         fn ability_get_effect(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>; | ||||||
|  |         fn ability_get_parameters(r: ExternRef<AbilityImpl>) -> VecExternRef<EffectParameter>; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[cfg(not(feature = "mock_data"))] | ||||||
|  | pub use implementation::*; | ||||||
|   | |||||||
| @@ -1,4 +1,5 @@ | |||||||
| use crate::{ExternRef, ExternalReferenceType, TypeIdentifier}; | use crate::app_interface::TypeIdentifier; | ||||||
|  | use crate::{ExternRef, ExternalReferenceType}; | ||||||
| use alloc::rc::Rc; | use alloc::rc::Rc; | ||||||
| use alloc::string::{String, ToString}; | use alloc::string::{String, ToString}; | ||||||
| use cstr_core::{c_char, CString}; | use cstr_core::{c_char, CString}; | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ impl EffectParameter { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |  | ||||||
|     pub fn as_bool(&self) -> bool { |     pub fn as_bool(&self) -> bool { | ||||||
|         if let EffectParameter::Bool(b) = self { |         if let EffectParameter::Bool(b) = self { | ||||||
|             return *b; |             return *b; | ||||||
| @@ -63,7 +63,6 @@ impl EffectParameter { | |||||||
|         } |         } | ||||||
|         panic!("Unexpected effect parameter type: {}", self); |         panic!("Unexpected effect parameter type: {}", self); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] | #[cfg(not(feature = "mock_data"))] | ||||||
|   | |||||||
| @@ -1,9 +1,12 @@ | |||||||
| use crate::app_interface::get_hash; | use crate::app_interface::get_hash; | ||||||
|  | use crate::app_interface::list::ImmutableList; | ||||||
|  | #[cfg(not(feature = "mock_data"))] | ||||||
|  | use crate::app_interface::list::ImmutableListWasm; | ||||||
| use crate::handling::cached_value::CachedValue; | use crate::handling::cached_value::CachedValue; | ||||||
|  | use crate::handling::ffi_array::FFIArray; | ||||||
| use crate::handling::Cacheable; | use crate::handling::Cacheable; | ||||||
| use crate::{ | use crate::{ | ||||||
|     cached_value, cached_value_getters, ExternRef, ExternalReferenceType, FFIArray, ImmutableList, |     cached_value, cached_value_getters, ExternRef, ExternalReferenceType, StringKey, VecExternRef, | ||||||
|     StringKey, VecExternRef, |  | ||||||
| }; | }; | ||||||
| use alloc::rc::Rc; | use alloc::rc::Rc; | ||||||
| use alloc::vec::Vec; | use alloc::vec::Vec; | ||||||
| @@ -97,8 +100,8 @@ struct FormInner { | |||||||
|     types: CachedValue<Vec<u8>>, |     types: CachedValue<Vec<u8>>, | ||||||
|     base_experience: CachedValue<u32>, |     base_experience: CachedValue<u32>, | ||||||
|     base_stats: CachedValue<ImmutableStatisticSet>, |     base_stats: CachedValue<ImmutableStatisticSet>, | ||||||
|     abilities: CachedValue<ImmutableList<StringKey>>, |     abilities: CachedValue<ImmutableList<Rc<StringKey>>>, | ||||||
|     hidden_abilities: CachedValue<ImmutableList<StringKey>>, |     hidden_abilities: CachedValue<ImmutableList<Rc<StringKey>>>, | ||||||
|     // moves: CachedValue<LearnableMoves>, |     // moves: CachedValue<LearnableMoves>, | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -122,9 +125,19 @@ impl Form { | |||||||
|                 }), |                 }), | ||||||
|                 base_experience: cached_value!({ form_get_base_experience(reference) }), |                 base_experience: cached_value!({ form_get_base_experience(reference) }), | ||||||
|                 base_stats: cached_value!({ form_get_base_stats(reference).get_value().unwrap() }), |                 base_stats: cached_value!({ form_get_base_stats(reference).get_value().unwrap() }), | ||||||
|                 abilities: cached_value!({ form_get_abilities(reference).get_immutable_list() }), |                 abilities: cached_value!({ | ||||||
|  |                     Rc::new( | ||||||
|  |                         crate::app_interface::list::StringKeyImmutableList::from_ref( | ||||||
|  |                             form_get_abilities(reference), | ||||||
|  |                         ), | ||||||
|  |                     ) | ||||||
|  |                 }), | ||||||
|                 hidden_abilities: cached_value!({ |                 hidden_abilities: cached_value!({ | ||||||
|                     form_get_hidden_abilities(reference).get_immutable_list() |                     Rc::new( | ||||||
|  |                         crate::app_interface::list::StringKeyImmutableList::from_ref( | ||||||
|  |                             form_get_hidden_abilities(reference), | ||||||
|  |                         ), | ||||||
|  |                     ) | ||||||
|                 }), |                 }), | ||||||
|             }), |             }), | ||||||
|         }) |         }) | ||||||
| @@ -140,8 +153,8 @@ impl Form { | |||||||
|         pub fn weight(&self) -> f32; |         pub fn weight(&self) -> f32; | ||||||
|         pub fn base_experience(&self) -> u32; |         pub fn base_experience(&self) -> u32; | ||||||
|         pub fn base_stats(&self) -> ImmutableStatisticSet; |         pub fn base_stats(&self) -> ImmutableStatisticSet; | ||||||
|         pub fn abilities(&self) -> ImmutableList<StringKey>; |         pub fn abilities(&self) -> ImmutableList<Rc<StringKey>>; | ||||||
|         pub fn hidden_abilities(&self) -> ImmutableList<StringKey>; |         pub fn hidden_abilities(&self) -> ImmutableList<Rc<StringKey>>; | ||||||
|     } |     } | ||||||
|     pub fn types(&self) -> &Vec<u8> { |     pub fn types(&self) -> &Vec<u8> { | ||||||
|         self.inner.types.value_ref() |         self.inner.types.value_ref() | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| use crate::app_interface::list::ImmutableList; |  | ||||||
| use alloc::rc::Rc; | use alloc::rc::Rc; | ||||||
| use core::cmp::Ordering; | use core::cmp::Ordering; | ||||||
| use core::hash::{Hash, Hasher}; | use core::hash::{Hash, Hasher}; | ||||||
| @@ -152,15 +151,6 @@ impl<T> VecExternRef<T> { | |||||||
|             resource_type: Default::default(), |             resource_type: Default::default(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[cfg(not(feature = "mock_data"))] |  | ||||||
|     pub(crate) fn get_immutable_list(&self) -> ImmutableList<T> |  | ||||||
|     where |  | ||||||
|         T: Clone, |  | ||||||
|         T: ExternalReferenceType, |  | ||||||
|     { |  | ||||||
|         ImmutableList::from_ref(*self) |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
| impl<T> Clone for VecExternRef<T> { | impl<T> Clone for VecExternRef<T> { | ||||||
|   | |||||||
| @@ -1,10 +1,12 @@ | |||||||
| use crate::app_interface::list::ImmutableList; | use crate::app_interface::list::ImmutableList; | ||||||
| use crate::app_interface::{ | use crate::app_interface::{ | ||||||
|     Battle, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item, Pokemon, Statistic, |     Battle, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove, Item, Pokemon, Statistic, | ||||||
|  |     TurnChoice, TypeIdentifier, | ||||||
| }; | }; | ||||||
| use crate::handling::ScriptCapabilities; | use crate::handling::ScriptCapabilities; | ||||||
| use crate::{ExternRef, ExternalReferenceType, ScriptPtr, StringKey, TurnChoice, TypeIdentifier}; | use crate::{ExternRef, ExternalReferenceType, StringKey}; | ||||||
| use alloc::boxed::Box; | use alloc::boxed::Box; | ||||||
|  | use alloc::rc::Rc; | ||||||
| use core::any::Any; | use core::any::Any; | ||||||
| use core::fmt::Debug; | use core::fmt::Debug; | ||||||
|  |  | ||||||
| @@ -25,7 +27,7 @@ pub trait Script { | |||||||
|     fn on_initialize( |     fn on_initialize( | ||||||
|         &self, |         &self, | ||||||
|         _library: &DynamicLibrary, |         _library: &DynamicLibrary, | ||||||
|         _parameters: Option<ImmutableList<EffectParameter>>, |         _parameters: Option<ImmutableList<Rc<EffectParameter>>>, | ||||||
|     ) { |     ) { | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -352,7 +354,7 @@ pub trait Script { | |||||||
|         Self: Sized, |         Self: Sized, | ||||||
|     { |     { | ||||||
|         unsafe { |         unsafe { | ||||||
|             script_get_owner(ScriptPtr::from_existing(self)) |             script_get_owner(crate::implementation::ScriptPtr::from_existing(self)) | ||||||
|                 .cast::<T>() |                 .cast::<T>() | ||||||
|                 .get_value() |                 .get_value() | ||||||
|         } |         } | ||||||
| @@ -375,5 +377,5 @@ impl Debug for dyn Script { | |||||||
|  |  | ||||||
| #[cfg(not(feature = "mock_data"))] | #[cfg(not(feature = "mock_data"))] | ||||||
| extern "wasm" { | extern "wasm" { | ||||||
|     fn script_get_owner(pointer: ScriptPtr) -> ExternRef<u8>; |     fn script_get_owner(pointer: crate::implementation::ScriptPtr) -> ExternRef<u8>; | ||||||
| } | } | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user