More work on mocking and removing the impls from the interface
This commit is contained in:
parent
6e15a26813
commit
417b776a83
|
@ -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,21 +13,32 @@ 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 {
|
||||||
|
use super::*;
|
||||||
|
use crate::app_interface::{BattleImpl, PokemonImpl};
|
||||||
|
use crate::handling::cached_value::CachedValue;
|
||||||
|
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};
|
||||||
|
|
||||||
|
struct BattleSideInner {
|
||||||
reference: ExternRef<BattleSideImpl>,
|
reference: ExternRef<BattleSideImpl>,
|
||||||
side_index: CachedValue<u8>,
|
side_index: CachedValue<u8>,
|
||||||
pokemon_per_side: CachedValue<u8>,
|
pokemon_per_side: CachedValue<u8>,
|
||||||
battle: CachedValue<Rc<BattleImpl>>,
|
battle: CachedValue<Rc<BattleImpl>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BattleSideImpl {
|
pub struct BattleSideImpl {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
inner: Rc<BattleSideInner>,
|
inner: Rc<BattleSideInner>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
impl BattleSideImpl {
|
||||||
impl BattleSideImpl {
|
|
||||||
pub fn new(reference: ExternRef<Self>) -> Self {
|
pub fn new(reference: ExternRef<Self>) -> Self {
|
||||||
Self::from_ref(reference, &|reference| Self {
|
Self::from_ref(reference, &|reference| Self {
|
||||||
inner: Rc::new(BattleSideInner {
|
inner: Rc::new(BattleSideInner {
|
||||||
|
@ -50,10 +51,9 @@ impl BattleSideImpl {
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
impl BattleSideTrait for BattleSideImpl {
|
||||||
impl BattleSideTrait for BattleSideImpl {
|
|
||||||
cached_value_getters! {
|
cached_value_getters! {
|
||||||
fn side_index(&self) -> u8;
|
fn side_index(&self) -> u8;
|
||||||
fn pokemon_per_side(&self) -> u8;
|
fn pokemon_per_side(&self) -> u8;
|
||||||
|
@ -76,10 +76,9 @@ impl BattleSideTrait for BattleSideImpl {
|
||||||
fn has_fled_battle(&self) -> bool;
|
fn has_fled_battle(&self) -> bool;
|
||||||
fn is_defeated(&self) -> bool;
|
fn is_defeated(&self) -> bool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
impl WithVolatile for BattleSideImpl {
|
||||||
impl WithVolatile for BattleSideImpl {
|
|
||||||
fn has_volatile(&self, script_name: &str) -> bool {
|
fn has_volatile(&self, script_name: &str) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
let script_name = CString::new(script_name).unwrap();
|
let script_name = CString::new(script_name).unwrap();
|
||||||
|
@ -114,30 +113,30 @@ impl WithVolatile for BattleSideImpl {
|
||||||
let script_name = CString::new(script_name).unwrap();
|
let script_name = CString::new(script_name).unwrap();
|
||||||
unsafe { battleside_get_volatile(self.inner.reference, script_name.as_ptr()).val() }
|
unsafe { battleside_get_volatile(self.inner.reference, script_name.as_ptr()).val() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_value_getters_extern! {
|
wasm_value_getters_extern! {
|
||||||
BattleSideImpl, BattleSide,
|
BattleSideImpl, BattleSide,
|
||||||
pub fn has_fled_battle(&self) -> bool;
|
pub fn has_fled_battle(&self) -> bool;
|
||||||
pub fn is_defeated(&self) -> bool;
|
pub fn is_defeated(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(BattleSideImpl);
|
crate::handling::cacheable::cacheable!(BattleSideImpl);
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
impl ExternalReferenceType for BattleSideImpl {
|
||||||
impl ExternalReferenceType for BattleSideImpl {
|
|
||||||
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 battleside_get_side_index(r: ExternRef<BattleSideImpl>) -> u8;
|
fn battleside_get_side_index(r: ExternRef<BattleSideImpl>) -> u8;
|
||||||
fn battleside_get_pokemon_per_side(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_battle(r: ExternRef<BattleSideImpl>) -> ExternRef<BattleImpl>;
|
||||||
fn battleside_get_pokemon(r: ExternRef<BattleSideImpl>, index: usize)
|
fn battleside_get_pokemon(
|
||||||
-> ExternRef<PokemonImpl>;
|
r: ExternRef<BattleSideImpl>,
|
||||||
|
index: usize,
|
||||||
|
) -> ExternRef<PokemonImpl>;
|
||||||
|
|
||||||
fn battleside_add_volatile_by_name(
|
fn battleside_add_volatile_by_name(
|
||||||
r: ExternRef<BattleSideImpl>,
|
r: ExternRef<BattleSideImpl>,
|
||||||
|
@ -147,4 +146,8 @@ extern "wasm" {
|
||||||
fn battleside_has_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char) -> bool;
|
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_remove_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char);
|
||||||
fn battleside_get_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char) -> ScriptPtr;
|
fn battleside_get_volatile(r: ExternRef<BattleSideImpl>, name: *const c_char) -> ScriptPtr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
pub use implementation::*;
|
||||||
|
|
|
@ -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 {
|
||||||
|
use super::*;
|
||||||
|
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 {
|
pub fn new(reference: ExternRef<ChoiceQueueImpl>) -> Self {
|
||||||
Self { reference }
|
Self { reference }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
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()) }
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
impl ChoiceQueueTrait for ChoiceQueueImpl {
|
||||||
impl ExternalReferenceType 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 {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
Self::new(reference)
|
Self::new(reference)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
extern "wasm" {
|
||||||
extern "wasm" {
|
|
||||||
fn choice_queue_move_pokemon_choice_next(
|
fn choice_queue_move_pokemon_choice_next(
|
||||||
r: ExternRef<ChoiceQueueImpl>,
|
r: ExternRef<ChoiceQueueImpl>,
|
||||||
pokemon: ExternRef<PokemonImpl>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
pub use implementation::*;
|
||||||
|
|
|
@ -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,34 +1,38 @@
|
||||||
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;
|
pub trait ImmutableListTrait<T> {
|
||||||
|
fn get(&self, index: u32) -> Option<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type ImmutableList<T> = Rc<dyn ImmutableListTrait<T>>;
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
struct ImmutableListInner<T: Clone> {
|
mod implementation {
|
||||||
|
use super::*;
|
||||||
|
use crate::app_interface::{
|
||||||
|
BattleParty, BattlePartyImpl, BattleSide, BattleSideImpl, EffectParameter, StringKey,
|
||||||
|
};
|
||||||
|
use crate::handling::extern_ref::{ExternalReferenceType, VecExternRef};
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
|
pub(crate) struct ImmutableListInner<T: Clone> {
|
||||||
extern_ref: VecExternRef<T>,
|
extern_ref: VecExternRef<T>,
|
||||||
resource_type: PhantomData<T>,
|
resource_type: PhantomData<T>,
|
||||||
values: spin::RwLock<Vec<Option<Option<T>>>>,
|
values: spin::RwLock<Vec<Option<Option<Rc<T>>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub(crate) trait ImmutableListWasm<T: Clone + ExternalReferenceType> {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
fn initialize(inner: *const ImmutableListInner<T>) -> Self
|
||||||
pub struct ImmutableList<T>
|
where
|
||||||
where
|
Self: Sized;
|
||||||
T: Clone,
|
|
||||||
T: ExternalReferenceType,
|
|
||||||
{
|
|
||||||
inner: *const ImmutableListInner<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
fn new(extern_ref: VecExternRef<T>) -> Self
|
||||||
impl<T> ImmutableList<T>
|
where
|
||||||
where
|
Self: Sized,
|
||||||
T: Clone,
|
{
|
||||||
T: ExternalReferenceType,
|
|
||||||
{
|
|
||||||
fn new(extern_ref: VecExternRef<T>) -> Self {
|
|
||||||
let mut values = Vec::new();
|
let mut values = Vec::new();
|
||||||
values.resize(extern_ref.len() as usize, None);
|
values.resize(extern_ref.len() as usize, None);
|
||||||
let inner = Box::new(ImmutableListInner {
|
let inner = Box::new(ImmutableListInner {
|
||||||
|
@ -37,12 +41,13 @@ where
|
||||||
values: spin::RwLock::new(values),
|
values: spin::RwLock::new(values),
|
||||||
});
|
});
|
||||||
let inner_ptr = Box::into_raw(inner);
|
let inner_ptr = Box::into_raw(inner);
|
||||||
ImmutableList {
|
Self::initialize(inner_ptr)
|
||||||
inner: inner_ptr as *const ImmutableListInner<T>,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_ref(extern_ref: VecExternRef<T>) -> Self {
|
fn from_ref(extern_ref: VecExternRef<T>) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
if let None = CACHE {
|
if let None = CACHE {
|
||||||
CACHE = Some(hashbrown::HashMap::new());
|
CACHE = Some(hashbrown::HashMap::new());
|
||||||
|
@ -53,62 +58,148 @@ where
|
||||||
.get(&extern_ref.get_internal_index());
|
.get(&extern_ref.get_internal_index());
|
||||||
if let Some(v) = existing {
|
if let Some(v) = existing {
|
||||||
let inner = *v as *const ImmutableListInner<T>;
|
let inner = *v as *const ImmutableListInner<T>;
|
||||||
ImmutableList { inner }
|
Self::initialize(inner)
|
||||||
} else {
|
} else {
|
||||||
let v = Self::new(extern_ref);
|
let v = Self::new(extern_ref);
|
||||||
CACHE
|
CACHE.as_mut().unwrap().insert(
|
||||||
.as_mut()
|
extern_ref.get_internal_index(),
|
||||||
.unwrap()
|
v.get_inner_ptr() as *const u8,
|
||||||
.insert(extern_ref.get_internal_index(), v.inner as *const u8);
|
);
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self, index: u32) -> Option<T> {
|
fn get_inner(&self) -> &ImmutableListInner<T> {
|
||||||
unsafe {
|
unsafe { self.get_inner_ptr().as_ref().unwrap() }
|
||||||
let inner = self.inner.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 rg = inner.values.read();
|
||||||
let v = rg.get(index as usize).unwrap();
|
let v = rg.get(index as usize).unwrap();
|
||||||
if let Some(v) = v {
|
if let Some(v) = v {
|
||||||
return v.clone();
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! immutable_list_type {
|
||||||
|
($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;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "mock_data")]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
pub struct ImmutableListInner<T> {
|
pub use implementation::*;
|
||||||
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> {
|
|
||||||
self.inner.values.get(index as usize).cloned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static mut CACHE: Option<hashbrown::HashMap<u32, *const u8>> = None;
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
use super::*;
|
||||||
|
use crate::app_interface::list::{
|
||||||
|
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_name(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>;
|
||||||
fn ability_get_effect(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>;
|
fn ability_get_effect(r: ExternRef<AbilityImpl>) -> ExternRef<StringKey>;
|
||||||
fn ability_get_parameters(r: ExternRef<AbilityImpl>) -> VecExternRef<EffectParameter>;
|
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};
|
||||||
|
|
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,23 +22,9 @@ extern crate dlmalloc;
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc {};
|
static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc {};
|
||||||
|
|
||||||
use crate::app_interface::list::ImmutableList;
|
pub(crate) use crate::app_interface::StringKey;
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
use crate::app_interface::{BattleImpl, ExecutingMoveImpl, PokemonImpl};
|
|
||||||
use crate::app_interface::{
|
|
||||||
DamageSource, DynamicLibrary, EffectParameter, Item, ItemImpl, Pokemon, Statistic, StringKey,
|
|
||||||
TurnChoice, TypeIdentifier,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub(crate) use crate::handling::extern_ref::*;
|
pub(crate) use crate::handling::extern_ref::*;
|
||||||
use crate::handling::ffi_array::FFIArray;
|
pub(crate) use crate::handling::Script;
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
use crate::handling::ScriptCapabilities;
|
|
||||||
use crate::handling::{Script, ScriptCategory};
|
|
||||||
use alloc::boxed::Box;
|
|
||||||
use core::sync::atomic::{AtomicU32, Ordering};
|
|
||||||
use cstr_core::{c_char, CString};
|
|
||||||
use hashbrown::HashMap;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -46,17 +32,34 @@ pub mod app_interface;
|
||||||
pub mod handling;
|
pub mod handling;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
pub type LoadScriptFnType = Box<dyn Fn(ScriptCategory, &StringKey) -> Option<Box<dyn Script>>>;
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
mod implementation {
|
||||||
|
use crate::app_interface::list::{EffectParameterImmutableList, ImmutableListWasm};
|
||||||
|
use crate::app_interface::{
|
||||||
|
BattleImpl, DamageSource, DynamicLibrary, EffectParameter, ExecutingMoveImpl, ItemImpl,
|
||||||
|
PokemonImpl, Statistic, StringKey, TurnChoice, TypeIdentifier,
|
||||||
|
};
|
||||||
|
use crate::handling::extern_ref::ExternRef;
|
||||||
|
use crate::handling::extern_ref::VecExternRef;
|
||||||
|
use crate::handling::ffi_array::FFIArray;
|
||||||
|
use crate::handling::{Script, ScriptCapabilities, ScriptCategory};
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
use core::sync::atomic::{AtomicU32, Ordering};
|
||||||
|
use cstr_core::{c_char, CString};
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
|
||||||
static mut LOAD_SCRIPT_FN: Option<LoadScriptFnType> = None;
|
pub type LoadScriptFnType = Box<dyn Fn(ScriptCategory, &StringKey) -> Option<Box<dyn Script>>>;
|
||||||
|
|
||||||
pub fn set_load_script_fn(f: LoadScriptFnType) {
|
static mut LOAD_SCRIPT_FN: Option<LoadScriptFnType> = None;
|
||||||
|
|
||||||
|
pub fn set_load_script_fn(f: LoadScriptFnType) {
|
||||||
unsafe {
|
unsafe {
|
||||||
LOAD_SCRIPT_FN = Some(f);
|
LOAD_SCRIPT_FN = Some(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! exported_functions {
|
macro_rules! exported_functions {
|
||||||
(
|
(
|
||||||
$(
|
$(
|
||||||
fn $func_name:ident($($par_name:ident: $par_type:ty),*$(,)?) $(-> $return_type:ty)? $func_body:block
|
fn $func_name:ident($($par_name:ident: $par_type:ty),*$(,)?) $(-> $return_type:ty)? $func_body:block
|
||||||
|
@ -64,7 +67,6 @@ macro_rules! exported_functions {
|
||||||
) => {
|
) => {
|
||||||
$(
|
$(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
unsafe extern "wasm" fn $func_name(
|
unsafe extern "wasm" fn $func_name(
|
||||||
$(
|
$(
|
||||||
$par_name: $par_type,
|
$par_name: $par_type,
|
||||||
|
@ -74,16 +76,16 @@ macro_rules! exported_functions {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static mut SCRIPT_PTR_CACHE: Option<hashbrown::HashMap<*const dyn Script, u32>> = None;
|
static mut SCRIPT_PTR_CACHE: Option<hashbrown::HashMap<*const dyn Script, u32>> = None;
|
||||||
static mut SCRIPT_PTR_REVERSE_CACHE: Option<hashbrown::HashMap<u32, Box<dyn Script>>> = None;
|
static mut SCRIPT_PTR_REVERSE_CACHE: Option<hashbrown::HashMap<u32, Box<dyn Script>>> = None;
|
||||||
static mut SCRIPT_INDEX_COUNTER: AtomicU32 = AtomicU32::new(1);
|
static mut SCRIPT_INDEX_COUNTER: AtomicU32 = AtomicU32::new(1);
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ScriptPtr {
|
pub struct ScriptPtr {
|
||||||
index: u32,
|
index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScriptPtr {
|
impl ScriptPtr {
|
||||||
fn get_cache<'a>() -> &'a mut HashMap<*const dyn Script, u32> {
|
fn get_cache<'a>() -> &'a mut HashMap<*const dyn Script, u32> {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let None = SCRIPT_PTR_CACHE {
|
if let None = SCRIPT_PTR_CACHE {
|
||||||
|
@ -143,11 +145,11 @@ impl ScriptPtr {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exported_functions! {
|
exported_functions! {
|
||||||
|
|
||||||
fn load_script(category: ScriptCategory, name: ExternRef<StringKey>) -> ScriptPtr {
|
fn load_script(category: ScriptCategory, name: ExternRef<StringKey>) -> ScriptPtr {
|
||||||
let name_c = StringKey::new(name);
|
let name_c = StringKey::new(name);
|
||||||
let boxed_script = unsafe { &LOAD_SCRIPT_FN }.as_ref().unwrap()(category, &name_c);
|
let boxed_script = unsafe { &LOAD_SCRIPT_FN }.as_ref().unwrap()(category, &name_c);
|
||||||
if boxed_script.is_none() {
|
if boxed_script.is_none() {
|
||||||
|
@ -155,524 +157,511 @@ fn load_script(category: ScriptCategory, name: ExternRef<StringKey>) -> ScriptPt
|
||||||
}
|
}
|
||||||
let b = boxed_script.unwrap();
|
let b = boxed_script.unwrap();
|
||||||
ScriptPtr::new(b)
|
ScriptPtr::new(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_script(script: *mut Box<dyn Script>) {
|
fn destroy_script(script: *mut Box<dyn Script>) {
|
||||||
// By turning it from a raw pointer back into a Box with from_raw, we give ownership back to rust.
|
// By turning it from a raw pointer back into a Box with from_raw, we give ownership back to rust.
|
||||||
// This lets Rust do the cleanup.
|
// This lets Rust do the cleanup.
|
||||||
let boxed_script = Box::from_raw(script);
|
let boxed_script = Box::from_raw(script);
|
||||||
drop(boxed_script);
|
drop(boxed_script);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_get_name(script: ScriptPtr) -> *mut c_char {
|
fn script_get_name(script: ScriptPtr) -> *mut c_char {
|
||||||
let c = script.val().unwrap().get_name();
|
let c = script.val().unwrap().get_name();
|
||||||
CString::new(c).unwrap().into_raw()
|
CString::new(c).unwrap().into_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn get_script_capabilities(script: ScriptPtr) -> FFIArray<ScriptCapabilities> {
|
fn get_script_capabilities(script: ScriptPtr) -> FFIArray<ScriptCapabilities> {
|
||||||
let c = script.val().unwrap().get_capabilities();
|
let c = script.val().unwrap().get_capabilities();
|
||||||
FFIArray::new(c)
|
FFIArray::new(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_stack(script: ScriptPtr) {
|
fn script_stack(script: ScriptPtr) {
|
||||||
script.val().unwrap().stack();
|
script.val().unwrap().stack();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_remove(script: ScriptPtr) {
|
fn script_on_remove(script: ScriptPtr) {
|
||||||
script.val().unwrap().on_remove();
|
script.val().unwrap().on_remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_initialize(
|
fn script_on_initialize(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
library: ExternRef<DynamicLibrary>,
|
library: ExternRef<DynamicLibrary>,
|
||||||
parameters: VecExternRef<EffectParameter>,
|
parameters: VecExternRef<EffectParameter>,
|
||||||
) {
|
) {
|
||||||
let parameters = ImmutableList::from_ref(parameters);
|
let parameters = Rc::new(EffectParameterImmutableList::from_ref(parameters));
|
||||||
script.val().unwrap().on_initialize(&library.not_null(), Some(parameters));
|
script.val().unwrap().on_initialize(&library.not_null(), Some(parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_before_turn(
|
fn script_on_before_turn(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
choice: ExternRef<TurnChoice>,
|
choice: ExternRef<TurnChoice>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_before_turn(choice.not_null())
|
script.val().unwrap().on_before_turn(choice.not_null())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_speed(
|
fn script_change_speed(
|
||||||
script:ScriptPtr,
|
script:ScriptPtr,
|
||||||
choice: ExternRef<TurnChoice>,
|
choice: ExternRef<TurnChoice>,
|
||||||
speed: *mut u32,
|
speed: *mut u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_speed(choice.not_null(), speed.as_mut().unwrap())
|
script.val().unwrap().change_speed(choice.not_null(), speed.as_mut().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_priority(
|
fn script_change_priority(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
choice: ExternRef<TurnChoice>,
|
choice: ExternRef<TurnChoice>,
|
||||||
priority: *mut i8,
|
priority: *mut i8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_priority(choice.not_null(), priority.as_mut().unwrap())
|
script.val().unwrap().change_priority(choice.not_null(), priority.as_mut().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_move(
|
fn script_change_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
choice: ExternRef<TurnChoice>,
|
choice: ExternRef<TurnChoice>,
|
||||||
mv: *mut ExternRef<StringKey>,
|
mv: *mut ExternRef<StringKey>,
|
||||||
) {
|
) {
|
||||||
let old = mv.as_ref().unwrap().not_null();
|
let old = mv.as_ref().unwrap().not_null();
|
||||||
let mut new = old.clone();
|
let mut new = old.clone();
|
||||||
script.val().unwrap().change_move(choice.not_null(), &mut new);
|
script.val().unwrap().change_move(choice.not_null(), &mut new);
|
||||||
if old != new {
|
if old != new {
|
||||||
*mv = new.ptr();
|
*mv = new.ptr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_number_of_hits(
|
fn script_change_number_of_hits(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
choice: ExternRef<TurnChoice>,
|
choice: ExternRef<TurnChoice>,
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_number_of_hits(choice.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().change_number_of_hits(choice.not_null(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_prevent_move(
|
fn script_prevent_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().prevent_move(mv.not_null_rc(), out.as_mut().unwrap());
|
script.val().unwrap().prevent_move(mv.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_fail_move(
|
fn script_fail_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().fail_move(mv.not_null_rc(), out.as_mut().unwrap());
|
script.val().unwrap().fail_move(mv.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_stop_before_move(
|
fn script_stop_before_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().stop_before_move(mv.not_null_rc(), out.as_mut().unwrap());
|
script.val().unwrap().stop_before_move(mv.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_before_move(
|
fn script_on_before_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_before_move(mv.not_null_rc());
|
script.val().unwrap().on_before_move(mv.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_fail_incoming_move(
|
fn script_fail_incoming_move(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().fail_incoming_move(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap());
|
script.val().unwrap().fail_incoming_move(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_is_invulnerable(
|
fn script_is_invulnerable(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().is_invulnerable(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap());
|
script.val().unwrap().is_invulnerable(mv.not_null_rc(), target.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_move_miss(
|
fn script_on_move_miss(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_move_miss(mv.not_null_rc(), target.not_null_rc());
|
script.val().unwrap().on_move_miss(mv.not_null_rc(), target.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_move_type(
|
fn script_change_move_type(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut TypeIdentifier,
|
out: *mut TypeIdentifier,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_move_type(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_move_type(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_effectiveness(
|
fn script_change_effectiveness(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_effectiveness(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_effectiveness(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_block_critical(
|
fn script_block_critical(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().block_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().block_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_block_incoming_critical(
|
fn script_block_incoming_critical(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().block_incoming_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().block_incoming_critical(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_accuracy(
|
fn script_change_accuracy(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_accuracy(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_accuracy(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_critical_stage(
|
fn script_change_critical_stage(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_critical_stage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_critical_stage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_critical_modifier(
|
fn script_change_critical_modifier(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_critical_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_critical_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_stab_modifier(
|
fn script_change_stab_modifier(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_stab_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_stab_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_base_power(
|
fn script_change_base_power(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_base_power(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_base_power(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_bypass_defensive_stat_boost(
|
fn script_bypass_defensive_stat_boost(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().bypass_defensive_stat_boost(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().bypass_defensive_stat_boost(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_bypass_offensive_stat_boost(
|
fn script_bypass_offensive_stat_boost(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().bypass_offensive_stat_boost(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().bypass_offensive_stat_boost(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_defensive_stat_value(
|
fn script_change_defensive_stat_value(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u32,
|
out: *mut u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_defensive_stat_value(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_defensive_stat_value(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_offensive_stat_value(
|
fn script_change_offensive_stat_value(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u32,
|
out: *mut u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_offensive_stat_value(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_offensive_stat_value(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_damage_stat_modifier(
|
fn script_change_damage_stat_modifier(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_damage_stat_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_damage_stat_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_damage_modifier(
|
fn script_change_damage_modifier(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_damage_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_damage_modifier(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_damage(
|
fn script_change_damage(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u32,
|
out: *mut u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_incoming_damage(
|
fn script_change_incoming_damage(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut u32,
|
out: *mut u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_incoming_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_incoming_damage(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_incoming_hit(
|
fn script_on_incoming_hit(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_incoming_hit(mv.not_null_rc(), target.not_null_rc(), hit);
|
script.val().unwrap().on_incoming_hit(mv.not_null_rc(), target.not_null_rc(), hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_opponent_faints(
|
fn script_on_opponent_faints(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_opponent_faints(mv.not_null_rc(), target.not_null_rc(), hit);
|
script.val().unwrap().on_opponent_faints(mv.not_null_rc(), target.not_null_rc(), hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_prevent_stat_boost_change(
|
fn script_prevent_stat_boost_change(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
stat: Statistic,
|
stat: Statistic,
|
||||||
amount: i8,
|
amount: i8,
|
||||||
self_inflicted: u8,
|
self_inflicted: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().prevent_stat_boost_change(target.not_null_rc(), stat, amount, self_inflicted == 1, out.as_mut().unwrap());
|
script.val().unwrap().prevent_stat_boost_change(target.not_null_rc(), stat, amount, self_inflicted == 1, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_prevent_secondary_effect(
|
fn script_prevent_secondary_effect(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().prevent_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().prevent_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_effect_chance(
|
fn script_change_effect_chance(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_effect_chance(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_effect_chance(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_incoming_effect_chance(
|
fn script_change_incoming_effect_chance(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
out: *mut f32,
|
out: *mut f32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_incoming_effect_chance(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
script.val().unwrap().change_incoming_effect_chance(mv.not_null_rc(), target.not_null_rc(), hit, out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_secondary_effect(
|
fn script_on_secondary_effect(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
hit: u8,
|
hit: u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit);
|
script.val().unwrap().on_secondary_effect(mv.not_null_rc(), target.not_null_rc(), hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_after_hits(
|
fn script_on_after_hits(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
mv: ExternRef<ExecutingMoveImpl>,
|
mv: ExternRef<ExecutingMoveImpl>,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_after_hits(mv.not_null_rc(), target.not_null_rc());
|
script.val().unwrap().on_after_hits(mv.not_null_rc(), target.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_prevent_self_switch(
|
fn script_prevent_self_switch(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
choice: ExternRef<TurnChoice>,
|
choice: ExternRef<TurnChoice>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().prevent_self_switch(choice.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().prevent_self_switch(choice.not_null(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_prevent_opponent_switch(
|
fn script_prevent_opponent_switch(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
choice: ExternRef<TurnChoice>,
|
choice: ExternRef<TurnChoice>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().prevent_opponent_switch(choice.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().prevent_opponent_switch(choice.not_null(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_fail(
|
fn script_on_fail(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<PokemonImpl>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_fail(pokemon.not_null_rc());
|
script.val().unwrap().on_fail(pokemon.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_opponent_fail(
|
fn script_on_opponent_fail(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<PokemonImpl>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_opponent_fail(pokemon.not_null_rc());
|
script.val().unwrap().on_opponent_fail(pokemon.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_prevent_self_run_away(
|
fn script_prevent_self_run_away(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
choice: ExternRef<TurnChoice>,
|
choice: ExternRef<TurnChoice>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().prevent_self_run_away(choice.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().prevent_self_run_away(choice.not_null(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_prevent_opponent_run_away(
|
fn script_prevent_opponent_run_away(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
choice: ExternRef<TurnChoice>,
|
choice: ExternRef<TurnChoice>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().prevent_opponent_run_away(choice.not_null(), out.as_mut().unwrap());
|
script.val().unwrap().prevent_opponent_run_away(choice.not_null(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_end_turn(
|
fn script_on_end_turn(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_end_turn();
|
script.val().unwrap().on_end_turn();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_damage(
|
fn script_on_damage(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<PokemonImpl>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
source: DamageSource,
|
source: DamageSource,
|
||||||
old_health: u32,
|
old_health: u32,
|
||||||
new_health: u32,
|
new_health: u32,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_damage(pokemon.not_null_rc(), source, old_health, new_health);
|
script.val().unwrap().on_damage(pokemon.not_null_rc(), source, old_health, new_health);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_faint(
|
fn script_on_faint(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<PokemonImpl>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
source: DamageSource,
|
source: DamageSource,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_faint(pokemon.not_null_rc(), source);
|
script.val().unwrap().on_faint(pokemon.not_null_rc(), source);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_switch_in(
|
fn script_on_switch_in(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<PokemonImpl>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_switch_in(pokemon.not_null_rc());
|
script.val().unwrap().on_switch_in(pokemon.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_on_after_held_item_consume(
|
fn script_on_after_held_item_consume(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
pokemon: ExternRef<PokemonImpl>,
|
pokemon: ExternRef<PokemonImpl>,
|
||||||
item: ExternRef<ItemImpl>
|
item: ExternRef<ItemImpl>
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().on_after_held_item_consume(pokemon.not_null_rc(), item.not_null_rc());
|
script.val().unwrap().on_after_held_item_consume(pokemon.not_null_rc(), item.not_null_rc());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_experience_gained(
|
fn script_change_experience_gained(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
fainted_pokemon: ExternRef<PokemonImpl>,
|
fainted_pokemon: ExternRef<PokemonImpl>,
|
||||||
winning_pokemon: ExternRef<PokemonImpl>,
|
winning_pokemon: ExternRef<PokemonImpl>,
|
||||||
out: *mut u32
|
out: *mut u32
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_experience_gained(fainted_pokemon.not_null_rc(), winning_pokemon.not_null_rc(), out.as_mut().unwrap());
|
script.val().unwrap().change_experience_gained(fainted_pokemon.not_null_rc(), winning_pokemon.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_share_experience(
|
fn script_share_experience(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
fainted_pokemon: ExternRef<PokemonImpl>,
|
fainted_pokemon: ExternRef<PokemonImpl>,
|
||||||
winning_pokemon: ExternRef<PokemonImpl>,
|
winning_pokemon: ExternRef<PokemonImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().share_experience(fainted_pokemon.not_null_rc(), winning_pokemon.not_null_rc(), out.as_mut().unwrap());
|
script.val().unwrap().share_experience(fainted_pokemon.not_null_rc(), winning_pokemon.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_block_weather(
|
fn script_block_weather(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
battle: ExternRef<BattleImpl>,
|
battle: ExternRef<BattleImpl>,
|
||||||
out: *mut bool,
|
out: *mut bool,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().block_weather(battle.not_null_rc(), out.as_mut().unwrap());
|
script.val().unwrap().block_weather(battle.not_null_rc(), out.as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_change_capture_rate_bonus(
|
fn script_change_capture_rate_bonus(
|
||||||
script: ScriptPtr,
|
script: ScriptPtr,
|
||||||
target: ExternRef<PokemonImpl>,
|
target: ExternRef<PokemonImpl>,
|
||||||
pokeball: ExternRef<ItemImpl>,
|
pokeball: ExternRef<ItemImpl>,
|
||||||
out: *mut u8,
|
out: *mut u8,
|
||||||
) {
|
) {
|
||||||
script.val().unwrap().change_capture_rate_bonus(target.not_null_rc(), pokeball.not_null_rc(), out.as_mut().unwrap());
|
script.val().unwrap().change_capture_rate_bonus(target.not_null_rc(), pokeball.not_null_rc(), out.as_mut().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
pub use implementation::*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue