diff --git a/Cargo.toml b/Cargo.toml index 3ac6ea5..0cec100 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,4 @@ [workspace] -edition = "2021" resolver = "2" members = [ diff --git a/gen_7_scripts/src/lib.rs b/gen_7_scripts/src/lib.rs index 43ece70..1678d46 100755 --- a/gen_7_scripts/src/lib.rs +++ b/gen_7_scripts/src/lib.rs @@ -7,6 +7,7 @@ extern crate alloc; +#[cfg(not(test))] use alloc::boxed::Box; #[cfg(not(test))] use pkmn_lib_interface::set_load_script_fn; diff --git a/gen_7_scripts/src/moves/acupressure.rs b/gen_7_scripts/src/moves/acupressure.rs index 864b0d1..7f005bf 100755 --- a/gen_7_scripts/src/moves/acupressure.rs +++ b/gen_7_scripts/src/moves/acupressure.rs @@ -44,7 +44,7 @@ mod tests { use super::*; use alloc::rc::Rc; use pkmn_lib_interface::app_interface::{ - MockBattle, MockBattleRandom, MockExecutingMove, MockHitData, MockItem, MockPokemon, + MockBattle, MockBattleRandom, MockExecutingMove, MockHitData, MockPokemon, }; #[test] diff --git a/gen_7_scripts/src/moves/assurance.rs b/gen_7_scripts/src/moves/assurance.rs index c75975a..4056b1d 100755 --- a/gen_7_scripts/src/moves/assurance.rs +++ b/gen_7_scripts/src/moves/assurance.rs @@ -3,9 +3,8 @@ use alloc::boxed::Box; use core::any::Any; use core::sync::atomic::{AtomicBool, Ordering}; use pkmn_lib_interface::app_interface::{ - BattleSide, DamageSource, ExecutingMove, Pokemon, TurnChoice, WithVolatile, + BattleSide, DamageSource, ExecutingMove, Pokemon, TurnChoice, }; -use pkmn_lib_interface::handling::script::ScriptOwner; use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; script!(Assurance, "assurance"); diff --git a/gen_7_scripts/src/moves/aurora_veil.rs b/gen_7_scripts/src/moves/aurora_veil.rs index 815d8da..261494a 100644 --- a/gen_7_scripts/src/moves/aurora_veil.rs +++ b/gen_7_scripts/src/moves/aurora_veil.rs @@ -5,7 +5,7 @@ use crate::weather::hail::Hail; use alloc::boxed::Box; use core::any::Any; use core::sync::atomic::{AtomicU32, Ordering}; -use pkmn_lib_interface::app_interface::{ExecutingMove, MoveCategory, Pokemon, WithVolatile}; +use pkmn_lib_interface::app_interface::{ExecutingMove, MoveCategory, Pokemon}; use pkmn_lib_interface::handling::ScriptCapabilities::OnEndTurn; use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs index 84e4152..2e3890d 100755 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs @@ -129,7 +129,7 @@ mod implementation { } fn has_weather(&self, name: &str) -> bool { if let Some(weather) = self.weather_name() { - if weather.eq(name) { + if weather.equals_str(name) { return true; } } diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/executing_move.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/executing_move.rs index 7ffbd2d..d7fd8c2 100755 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/executing_move.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/executing_move.rs @@ -43,7 +43,7 @@ pub use implementation::*; #[cfg(not(feature = "mock_data"))] mod implementation { use super::*; - use crate::app_interface::{LearnedMoveImpl, PokemonImpl}; + use crate::app_interface::{LearnedMoveImpl, MoveDataImpl, PokemonImpl}; use crate::cached_value; use crate::handling::cached_value::CachedValue; use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; @@ -84,7 +84,7 @@ mod implementation { ) }), use_move: cached_value!({ - executing_move_get_use_move(reference).get_value().unwrap() + Rc::new(executing_move_get_use_move(reference).get_value().unwrap()) }), }, ), @@ -200,7 +200,7 @@ mod implementation { fn executing_move_get_chosen_move( r: ExternRef, ) -> ExternRef; - fn executing_move_get_use_move(r: ExternRef) -> ExternRef; + fn executing_move_get_use_move(r: ExternRef) -> ExternRef; #[allow(improper_ctypes)] fn executing_move_get_script(r: ExternRef) -> *const dyn Script; diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/learned_move.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/learned_move.rs index 7a24ebc..ec0dbf3 100755 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/learned_move.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/learned_move.rs @@ -23,6 +23,7 @@ pub type LearnedMove = Rc; #[cfg(not(feature = "mock_data"))] mod implementation { use super::*; + use crate::app_interface::MoveDataImpl; use crate::handling::cached_value::CachedValue; use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; use crate::handling::Cacheable; @@ -54,7 +55,7 @@ mod implementation { inner: Rc::new(LearnedMoveInner { reference, move_data: cached_value!({ - learned_move_get_move_data(reference).get_value().unwrap() + Rc::new(learned_move_get_move_data(reference).get_value().unwrap()) }), learn_method: cached_value!({ learned_move_get_learn_method(reference) }), }), @@ -88,7 +89,7 @@ mod implementation { } extern "wasm" { - fn learned_move_get_move_data(r: ExternRef) -> ExternRef; + fn learned_move_get_move_data(r: ExternRef) -> ExternRef; fn learned_move_get_learn_method(r: ExternRef) -> MoveLearnMethod; fn learned_move_restore_uses(r: ExternRef, uses: u8); fn learned_move_restore_all_uses(r: ExternRef); diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs index 4587bfc..78ac7fc 100755 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs @@ -18,8 +18,8 @@ pub trait PokemonTrait: WithVolatile { fn form(&self) -> Form; fn active_ability(&self) -> Ability; fn nature(&self) -> Nature; - fn display_species(&self) -> Option; - fn display_form(&self) -> Option
; + fn display_species(&self) -> Species; + fn display_form(&self) -> Form; fn held_item(&self) -> Option; fn battle(&self) -> Option; fn level(&self) -> LevelInt; @@ -88,15 +88,15 @@ mod implementation { use crate::app_interface::dynamic_data::dynamic_library::DynamicLibraryImpl; use crate::app_interface::{ - AbilityImpl, BattleImpl, ItemImpl, LearnedMoveImpl, StatisticSetImpl, + AbilityImpl, BattleImpl, FormImpl, ItemImpl, LearnedMoveImpl, NatureImpl, SpeciesImpl, + StatisticSetImpl, }; use crate::handling::cached_value::CachedValue; use crate::handling::Cacheable; use crate::implementation::ScriptPtr; use crate::{ cached_value, cached_value_getters, wasm_optional_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_extern, wasm_value_getters_extern, wasm_value_getters_funcs, ExternRef, ExternalReferenceType, }; @@ -235,12 +235,20 @@ mod implementation { } fn change_species(&self, species: Species, form: Form) { unsafe { - pokemon_change_species(self.inner.reference, species.reference(), form.reference()); + let species_impl = species.as_any().downcast_ref_unchecked::(); + let form_impl = form.as_any().downcast_ref_unchecked::(); + + pokemon_change_species( + self.inner.reference, + species_impl.reference(), + form_impl.reference(), + ); } } fn change_form(&self, form: Form) { unsafe { - pokemon_change_form(self.inner.reference, form.reference()); + let form_impl = form.as_any().downcast_ref_unchecked::(); + pokemon_change_form(self.inner.reference, form_impl.reference()); } } fn is_fainted(&self) -> bool { @@ -258,11 +266,27 @@ mod implementation { } } - wasm_reference_getters_funcs! { - Pokemon, - fn species(&self) -> Species; - fn form(&self) -> Form; - fn nature(&self) -> Nature; + fn nature(&self) -> Nature { + unsafe { + Rc::new( + pokemon_get_nature(self.inner.reference) + .get_value() + .unwrap(), + ) + } + } + + fn species(&self) -> Species { + unsafe { + Rc::new( + pokemon_get_species(self.inner.reference) + .get_value() + .unwrap(), + ) + } + } + fn form(&self) -> Form { + unsafe { Rc::new(pokemon_get_form(self.inner.reference).get_value().unwrap()) } } fn clear_status(&self) { @@ -271,10 +295,23 @@ mod implementation { } } - wasm_optional_reference_getters_funcs! { - Pokemon, - fn display_species(&self) -> Option; - fn display_form(&self) -> Option; + fn display_species(&self) -> Species { + unsafe { + Rc::new( + pokemon_get_display_species(self.inner.reference) + .get_value() + .unwrap(), + ) + } + } + fn display_form(&self) -> Form { + unsafe { + Rc::new( + pokemon_get_display_form(self.inner.reference) + .get_value() + .unwrap(), + ) + } } fn battle_side(&self) -> BattleSide { @@ -391,16 +428,16 @@ mod implementation { wasm_reference_getters_extern! { PokemonImpl, Pokemon, - pub fn species(&self) -> Species; - pub fn form(&self) -> Form; + pub fn species(&self) -> SpeciesImpl; + pub fn form(&self) -> FormImpl; pub fn active_ability(&self) -> AbilityImpl; - pub fn nature(&self) -> Nature; + pub fn nature(&self) -> NatureImpl; } wasm_optional_reference_getters_extern! { PokemonImpl, Pokemon, - pub fn display_species(&self) -> Option; - pub fn display_form(&self) -> Option; + pub fn display_species(&self) -> Option; + pub fn display_form(&self) -> Option; pub fn held_item(&self) -> Option; pub fn battle(&self) -> Option; } @@ -475,10 +512,10 @@ mod implementation { fn pokemon_get_ability_script(r: ExternRef) -> *const Box; fn pokemon_change_species( r: ExternRef, - species: ExternRef, - form: ExternRef, + species: ExternRef, + form: ExternRef, ); - fn pokemon_change_form(r: ExternRef, form: ExternRef); + fn pokemon_change_form(r: ExternRef, form: ExternRef); fn pokemon_damage(r: ExternRef, damage: u32, source: DamageSource); fn pokemon_heal(r: ExternRef, amount: u32, allow_revive: bool) -> bool; fn pokemon_set_weight(r: ExternRef, weight: f32); @@ -504,8 +541,8 @@ mockall::mock!( fn form(&self) -> Form; fn active_ability(&self) -> Ability; fn nature(&self) -> Nature; - fn display_species(&self) -> Option; - fn display_form(&self) -> Option; + fn display_species(&self) -> Species; + fn display_form(&self) -> Form; fn held_item(&self) -> Option; fn battle(&self) -> Option; fn level(&self) -> LevelInt; @@ -556,19 +593,19 @@ mockall::mock!( #[cfg(feature = "mock_data")] impl WithVolatile for MockPokemon { - fn has_volatile(&self, script_name: &str) -> bool { + fn has_volatile(&self, _script_name: &str) -> bool { unimplemented!() } - fn add_volatile(&self, script: Box) -> &dyn Script { + fn add_volatile(&self, _script: Box) -> &dyn Script { unimplemented!() } - fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script { + fn add_volatile_by_name(&self, _script_name: &str) -> &dyn Script { unimplemented!() } - fn remove_volatile<'a, 'b>(&'a self, script: &dyn Script) { + fn remove_volatile(&self, _script: &dyn Script) { unimplemented!() } - fn get_volatile_script<'a>(&'a self, script_name: &str) -> Option<&'a dyn Script> { + fn get_volatile_script<'a>(&'a self, _script_name: &str) -> Option<&'a dyn Script> { unimplemented!() } } diff --git a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/item_library.rs b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/item_library.rs index 4925aae..cd23acc 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/item_library.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/item_library.rs @@ -1,77 +1,86 @@ -use crate::app_interface::{DataLibrary, ItemImpl}; -use crate::{ExternRef, ExternalReferenceType, StringKey}; +use crate::app_interface::{DataLibrary, Item}; use alloc::rc::Rc; -use spin::rwlock::RwLock; -struct ItemLibraryInner { - ptr: ExternRef, - cache: RwLock>, -} +pub trait ItemLibraryTrait: DataLibrary {} -#[derive(Clone)] -pub struct ItemLibrary { - inner: Rc, -} - -impl ItemLibrary { - #[cfg(not(feature = "mock_data"))] - pub(crate) fn new(ptr: ExternRef) -> Self { - Self { - inner: Rc::new(ItemLibraryInner { - ptr, - cache: Default::default(), - }), - } - } -} - -impl DataLibrary for ItemLibrary { - fn get_cache(&self) -> &spin::rwlock::RwLock> { - &self.inner.cache - } - - fn get_self_ref(&self) -> ExternRef { - self.inner.ptr - } - - #[cfg(not(feature = "mock_data"))] - fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> ExternRef { - unsafe { item_library_get_item(ptr, name) } - } - - #[cfg(not(feature = "mock_data"))] - fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> ExternRef { - unsafe { item_library_get_item_by_hash(ptr, hash) } - } -} - -crate::handling::cacheable::cacheable!(ItemLibrary); +pub type ItemLibrary = Rc; #[cfg(not(feature = "mock_data"))] -impl ExternalReferenceType for ItemLibrary { - fn from_extern_value(reference: ExternRef) -> Self { - Self::new(reference) +mod implementation { + use super::*; + use crate::app_interface::{ItemImpl, StringKey}; + use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; + use spin::RwLock; + + struct ItemLibraryInner { + ptr: ExternRef, + cache: RwLock>, + } + + #[derive(Clone)] + pub struct ItemLibraryImpl { + inner: Rc, + } + + impl ItemLibraryImpl { + pub(crate) fn new(ptr: ExternRef) -> Self { + Self { + inner: Rc::new(ItemLibraryInner { + ptr, + cache: Default::default(), + }), + } + } + } + + impl ItemLibraryTrait for ItemLibraryImpl {} + + impl DataLibrary for ItemLibraryImpl { + fn get_cache(&self) -> &spin::rwlock::RwLock> { + &self.inner.cache + } + + fn get_self_ref(&self) -> ExternRef { + self.inner.ptr + } + + fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> u32 { + unsafe { item_library_get_item(ptr, name).get_internal_index() } + } + + fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> u32 { + unsafe { item_library_get_item_by_hash(ptr, hash).get_internal_index() } + } + + fn _from_external_ref_index(index: u32) -> Option { + let v = ExternRef::::from(index).get_value(); + if let Some(v) = v { + Some(Rc::new(v)) + } else { + None + } + } + } + + crate::handling::cacheable::cacheable!(ItemLibraryImpl); + + impl ExternalReferenceType for ItemLibraryImpl { + fn from_extern_value(reference: ExternRef) -> Self { + Self::new(reference) + } + } + + extern "wasm" { + fn item_library_get_item( + ptr: ExternRef, + name: ExternRef, + ) -> ExternRef; + fn item_library_get_item_by_hash( + ptr: ExternRef, + hash: u32, + ) -> ExternRef; } } #[cfg(not(feature = "mock_data"))] -extern "wasm" { - fn item_library_get_item( - ptr: ExternRef, - name: ExternRef, - ) -> ExternRef; - fn item_library_get_item_by_hash(ptr: ExternRef, hash: u32) - -> ExternRef; -} - -#[cfg(feature = "mock_data")] -impl ItemLibrary { - pub fn mock() -> Self { - Self { - inner: Rc::new(ItemLibraryInner { - ptr: ExternRef::mock(), - cache: Default::default(), - }), - } - } -} +pub use implementation::*; diff --git a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/mod.rs b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/mod.rs index cae27d4..a7d2d93 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/mod.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/mod.rs @@ -1,7 +1,7 @@ use crate::app_interface::item_library::ItemLibrary; use crate::app_interface::move_library::MoveLibrary; use crate::app_interface::species_library::SpeciesLibrary; -use crate::app_interface::type_library::TypeLibrary; +use crate::app_interface::type_library::Typelibrary; use crate::app_interface::LevelInt; use alloc::rc::Rc; @@ -14,7 +14,7 @@ pub trait StaticDataTrait { fn move_library(&self) -> MoveLibrary; fn item_library(&self) -> ItemLibrary; fn species_library(&self) -> SpeciesLibrary; - fn type_library(&self) -> TypeLibrary; + fn type_library(&self) -> Typelibrary; } pub type StaticData = Rc; @@ -28,6 +28,10 @@ pub type LibrarySettings = Rc; #[cfg(not(feature = "mock_data"))] mod implementation { use super::*; + use crate::app_interface::item_library::ItemLibraryImpl; + use crate::app_interface::move_library::MoveLibraryImpl; + use crate::app_interface::species_library::SpeciesLibraryImpl; + use crate::app_interface::type_library::TypeLibraryImpl; use crate::app_interface::{get_hash, StringKey}; use crate::handling::cached_value::CachedValue; use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; @@ -40,7 +44,7 @@ mod implementation { move_library: CachedValue, item_library: CachedValue, species_library: CachedValue, - type_library: CachedValue, + type_library: CachedValue, settings: CachedValue, } @@ -56,18 +60,20 @@ mod implementation { inner: Rc::new(StaticDataInner { reference, move_library: cached_value!({ - static_data_get_move_library(reference).get_value().unwrap() + Rc::new(static_data_get_move_library(reference).get_value().unwrap()) }), item_library: cached_value!({ - static_data_get_item_library(reference).get_value().unwrap() + Rc::new(static_data_get_item_library(reference).get_value().unwrap()) }), species_library: cached_value!({ - static_data_get_species_library(reference) - .get_value() - .unwrap() + Rc::new( + static_data_get_species_library(reference) + .get_value() + .unwrap(), + ) }), type_library: cached_value!({ - static_data_get_type_library(reference).get_value().unwrap() + Rc::new(static_data_get_type_library(reference).get_value().unwrap()) }), settings: cached_value!({ Rc::new( @@ -86,7 +92,7 @@ mod implementation { fn move_library(&self) -> MoveLibrary; fn item_library(&self) -> ItemLibrary; fn species_library(&self) -> SpeciesLibrary; - fn type_library(&self) -> TypeLibrary; + fn type_library(&self) -> Typelibrary; } } @@ -134,12 +140,18 @@ mod implementation { #[cfg(not(feature = "mock_data"))] extern "wasm" { - fn static_data_get_move_library(ptr: ExternRef) -> ExternRef; - fn static_data_get_item_library(ptr: ExternRef) -> ExternRef; + fn static_data_get_move_library( + ptr: ExternRef, + ) -> ExternRef; + fn static_data_get_item_library( + ptr: ExternRef, + ) -> ExternRef; fn static_data_get_species_library( ptr: ExternRef, - ) -> ExternRef; - fn static_data_get_type_library(ptr: ExternRef) -> ExternRef; + ) -> ExternRef; + fn static_data_get_type_library( + ptr: ExternRef, + ) -> ExternRef; fn static_data_get_library_settings( ptr: ExternRef, ) -> ExternRef; @@ -149,17 +161,20 @@ mod implementation { pub trait DataLibrary: Cacheable where - T: ExternalReferenceType, T: Clone, { fn get_cache(&self) -> &RwLock>; fn get_self_ref(&self) -> ExternRef where Self: Sized; - fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> ExternRef + fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> u32 where Self: Sized; - fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> ExternRef + fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> u32 + where + Self: Sized; + + fn _from_external_ref_index(index: u32) -> Option where Self: Sized; @@ -171,7 +186,8 @@ mod implementation { return Some(v.clone()); } - let v = Self::_get_ref_by_name(self.get_self_ref(), name.ptr()).get_value(); + let index = Self::_get_ref_by_name(self.get_self_ref(), name.ptr()); + let v = Self::_from_external_ref_index(index); if let Some(v) = &v { self.get_cache().write().insert(name.hash(), v.clone()); } @@ -193,7 +209,8 @@ mod implementation { return Some(v.clone()); } - let v = Self::_get_ref_by_hash(self.get_self_ref(), hash).get_value(); + let index = Self::_get_ref_by_hash(self.get_self_ref(), hash); + let v = Self::_from_external_ref_index(index); if let Some(v) = &v { self.get_cache().write().insert(hash, v.clone()); } @@ -207,16 +224,12 @@ pub use implementation::*; #[cfg(feature = "mock_data")] mod mocked { - use super::*; use crate::app_interface::StringKey; - use crate::handling::cached_value::CachedValue; - use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; - use crate::handling::Cacheable; - use crate::{cached_value, cached_value_getters}; + use crate::handling::extern_ref::ExternRef; use spin::RwLock; #[cfg(feature = "mock_data")] - pub trait DataLibrary: Cacheable + pub trait DataLibrary where T: Clone, { diff --git a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/move_library.rs b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/move_library.rs index e03242b..b79f83c 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/move_library.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/move_library.rs @@ -1,76 +1,101 @@ -use crate::app_interface::data_libraries::DataLibrary; -use crate::app_interface::{MoveData, StringKey}; -use crate::{ExternRef, ExternalReferenceType}; +use crate::app_interface::{DataLibrary, MoveData}; use alloc::rc::Rc; -use spin::RwLock; -struct MoveLibraryInner { - ptr: ExternRef, - cache: RwLock>, -} +pub trait MoveLibraryTrait: DataLibrary {} -#[derive(Clone)] -pub struct MoveLibrary { - inner: Rc, -} - -impl MoveLibrary { - #[cfg(not(feature = "mock_data"))] - pub(crate) fn new(ptr: ExternRef) -> Self { - Self { - inner: Rc::new(MoveLibraryInner { - ptr, - cache: Default::default(), - }), - } - } - - #[cfg(feature = "mock_data")] - pub fn mock() -> Self { - Self { - inner: Rc::new(MoveLibraryInner { - ptr: ExternRef::mock(), - cache: Default::default(), - }), - } - } -} - -impl DataLibrary for MoveLibrary { - fn get_cache(&self) -> &spin::rwlock::RwLock> { - &self.inner.cache - } - - fn get_self_ref(&self) -> ExternRef { - self.inner.ptr - } - - #[cfg(not(feature = "mock_data"))] - fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> ExternRef { - unsafe { move_library_get_move(ptr, name) } - } - - #[cfg(not(feature = "mock_data"))] - fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> ExternRef { - unsafe { move_library_get_move_by_hash(ptr, hash) } - } -} - -crate::handling::cacheable::cacheable!(MoveLibrary); +pub type MoveLibrary = Rc; #[cfg(not(feature = "mock_data"))] -impl ExternalReferenceType for MoveLibrary { - fn from_extern_value(reference: ExternRef) -> Self { - Self::new(reference) +mod implementation { + use super::*; + use crate::app_interface::{MoveDataImpl, StringKey}; + use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; + use spin::RwLock; + + struct MoveLibraryInner { + ptr: ExternRef, + cache: RwLock>, + } + + #[derive(Clone)] + pub struct MoveLibraryImpl { + inner: Rc, + } + + impl MoveLibraryImpl { + #[cfg(not(feature = "mock_data"))] + pub(crate) fn new(ptr: ExternRef) -> Self { + Self { + inner: Rc::new(MoveLibraryInner { + ptr, + cache: Default::default(), + }), + } + } + + #[cfg(feature = "mock_data")] + pub fn mock() -> Self { + Self { + inner: Rc::new(MoveLibraryInner { + ptr: ExternRef::mock(), + cache: Default::default(), + }), + } + } + } + + impl MoveLibraryTrait for MoveLibraryImpl {} + + impl DataLibrary for MoveLibraryImpl { + fn get_cache(&self) -> &spin::rwlock::RwLock> { + &self.inner.cache + } + + fn get_self_ref(&self) -> ExternRef { + self.inner.ptr + } + + #[cfg(not(feature = "mock_data"))] + fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> u32 { + unsafe { move_library_get_move(ptr, name).get_internal_index() } + } + + #[cfg(not(feature = "mock_data"))] + fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> u32 { + unsafe { move_library_get_move_by_hash(ptr, hash).get_internal_index() } + } + + fn _from_external_ref_index(index: u32) -> Option { + let v = ExternRef::::from(index).get_value(); + if let Some(v) = v { + Some(Rc::new(v)) + } else { + None + } + } + } + + crate::handling::cacheable::cacheable!(MoveLibraryImpl); + + #[cfg(not(feature = "mock_data"))] + impl ExternalReferenceType for MoveLibraryImpl { + fn from_extern_value(reference: ExternRef) -> Self { + Self::new(reference) + } + } + + #[cfg(not(feature = "mock_data"))] + extern "wasm" { + fn move_library_get_move( + ptr: ExternRef, + name: ExternRef, + ) -> ExternRef; + fn move_library_get_move_by_hash( + ptr: ExternRef, + hash: u32, + ) -> ExternRef; } } #[cfg(not(feature = "mock_data"))] -extern "wasm" { - fn move_library_get_move( - ptr: ExternRef, - name: ExternRef, - ) -> ExternRef; - fn move_library_get_move_by_hash(ptr: ExternRef, hash: u32) - -> ExternRef; -} +pub use implementation::*; diff --git a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/species_library.rs b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/species_library.rs index 0db69ec..78548e6 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/species_library.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/species_library.rs @@ -1,77 +1,88 @@ use crate::app_interface::{DataLibrary, Species}; -use crate::{ExternRef, ExternalReferenceType, StringKey}; use alloc::rc::Rc; -use spin::RwLock; -struct SpeciesLibraryInner { - ptr: ExternRef, - cache: RwLock>, -} +pub trait SpeciesLibraryTrait: DataLibrary {} -#[derive(Clone)] -pub struct SpeciesLibrary { - inner: Rc, -} - -impl SpeciesLibrary { - #[cfg(not(feature = "mock_data"))] - pub fn new(ptr: ExternRef) -> Self { - Self { - inner: Rc::new(SpeciesLibraryInner { - ptr, - cache: Default::default(), - }), - } - } - - #[cfg(feature = "mock_data")] - pub fn mock() -> Self { - Self { - inner: Rc::new(SpeciesLibraryInner { - ptr: ExternRef::mock(), - cache: Default::default(), - }), - } - } -} - -impl DataLibrary for SpeciesLibrary { - fn get_cache(&self) -> &spin::rwlock::RwLock> { - &self.inner.cache - } - - fn get_self_ref(&self) -> ExternRef { - self.inner.ptr - } - - #[cfg(not(feature = "mock_data"))] - fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> ExternRef { - unsafe { species_library_get_species(ptr, name) } - } - - #[cfg(not(feature = "mock_data"))] - fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> ExternRef { - unsafe { species_library_get_species_by_hash(ptr, hash) } - } -} - -crate::handling::cacheable::cacheable!(SpeciesLibrary); +pub type SpeciesLibrary = Rc; #[cfg(not(feature = "mock_data"))] -impl ExternalReferenceType for SpeciesLibrary { - fn from_extern_value(reference: ExternRef) -> Self { - Self::new(reference) +mod implementation { + use crate::app_interface::species_library::SpeciesLibraryTrait; + use crate::app_interface::{DataLibrary, Species, SpeciesImpl, StringKey}; + use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; + use alloc::rc::Rc; + use spin::RwLock; + + struct SpeciesLibraryInner { + ptr: ExternRef, + cache: RwLock>, + } + + #[derive(Clone)] + pub struct SpeciesLibraryImpl { + inner: Rc, + } + + impl SpeciesLibraryImpl { + pub fn new(ptr: ExternRef) -> Self { + Self { + inner: Rc::new(SpeciesLibraryInner { + ptr, + cache: Default::default(), + }), + } + } + } + + impl SpeciesLibraryTrait for SpeciesLibraryImpl {} + + impl DataLibrary for SpeciesLibraryImpl { + fn get_cache(&self) -> &spin::rwlock::RwLock> { + &self.inner.cache + } + + fn get_self_ref(&self) -> ExternRef { + self.inner.ptr + } + + #[cfg(not(feature = "mock_data"))] + fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> u32 { + unsafe { species_library_get_species(ptr, name).get_internal_index() } + } + + fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> u32 { + unsafe { species_library_get_species_by_hash(ptr, hash).get_internal_index() } + } + + fn _from_external_ref_index(index: u32) -> Option { + let v = ExternRef::::from(index).get_value(); + if let Some(v) = v { + Some(Rc::new(v)) + } else { + None + } + } + } + + crate::handling::cacheable::cacheable!(SpeciesLibraryImpl); + + impl ExternalReferenceType for SpeciesLibraryImpl { + fn from_extern_value(reference: ExternRef) -> Self { + Self::new(reference) + } + } + + extern "wasm" { + fn species_library_get_species( + ptr: ExternRef, + name: ExternRef, + ) -> ExternRef; + fn species_library_get_species_by_hash( + ptr: ExternRef, + hash: u32, + ) -> ExternRef; } } #[cfg(not(feature = "mock_data"))] -extern "wasm" { - fn species_library_get_species( - ptr: ExternRef, - name: ExternRef, - ) -> ExternRef; - fn species_library_get_species_by_hash( - ptr: ExternRef, - hash: u32, - ) -> ExternRef; -} +pub use implementation::*; diff --git a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/type_library.rs b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/type_library.rs index 5d328fe..58f30ca 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/type_library.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/type_library.rs @@ -1,118 +1,132 @@ use crate::app_interface::TypeIdentifier; -use crate::{ExternRef, ExternalReferenceType}; use alloc::rc::Rc; -use alloc::string::{String, ToString}; -use cstr_core::{c_char, CString}; -use spin::RwLock; -struct TypeLibraryInner { - reference: ExternRef, - name_to_type_cache: RwLock>, - effectiveness_cache: RwLock>, -} - -#[derive(Clone)] -pub struct TypeLibrary { - inner: Rc, -} - -impl TypeLibrary { - #[cfg(not(feature = "mock_data"))] - pub(crate) fn new(reference: ExternRef) -> Self { - Self { - inner: Rc::new(TypeLibraryInner { - reference, - name_to_type_cache: Default::default(), - effectiveness_cache: Default::default(), - }), - } - } - #[cfg(feature = "mock_data")] - pub fn mock() -> Self { - Self { - inner: Rc::new(TypeLibraryInner { - reference: ExternRef::mock(), - name_to_type_cache: Default::default(), - effectiveness_cache: Default::default(), - }), - } - } - - #[cfg(not(feature = "mock_data"))] - pub fn get_type_from_name(&self, name: &str) -> Option { - if let Some(cached) = self.inner.name_to_type_cache.read().get(name) { - return Some(*cached); - } - let cstr = CString::new(name).unwrap(); - let v = unsafe { type_library_get_type_by_name(self.inner.reference, cstr.as_ptr()) }; - if v == 255 { - return None; - } - let v = v.into(); - self.inner - .name_to_type_cache - .write() - .insert(name.to_string(), v); - Some(v) - } - - #[cfg(not(feature = "mock_data"))] - pub fn get_single_effectiveness( +pub trait TypeLibraryTrait { + fn get_type_from_name(&self, name: &str) -> Option; + fn get_single_effectiveness( &self, attacking_type: TypeIdentifier, defending_type: TypeIdentifier, - ) -> f32 { - if let Some(cached) = self - .inner - .effectiveness_cache - .read() - .get(&(attacking_type, defending_type)) - { - return *cached; - } - let effectiveness = unsafe { - type_library_get_single_effectiveness( - self.inner.reference, - attacking_type.into(), - defending_type.into(), - ) - }; - self.inner - .effectiveness_cache - .write() - .insert((attacking_type, defending_type), effectiveness); - effectiveness - } - - #[cfg(not(feature = "mock_data"))] - pub fn get_effectiveness( + ) -> f32; + fn get_effectiveness( &self, attacking_type: TypeIdentifier, defending_types: &[TypeIdentifier], - ) -> f32 { - let mut f = 1.0; - for defending_type in defending_types { - f *= self.get_single_effectiveness(attacking_type, *defending_type); - } - f - } -} - -crate::handling::cacheable::cacheable!(TypeLibrary); - -#[cfg(not(feature = "mock_data"))] -impl ExternalReferenceType for TypeLibrary { - fn from_extern_value(reference: ExternRef) -> Self { - Self::new(reference) - } -} - -#[cfg(not(feature = "mock_data"))] -extern "wasm" { - fn type_library_get_single_effectiveness( - r: ExternRef, - attacking_type: u8, - defending_type: u8, ) -> f32; - fn type_library_get_type_by_name(r: ExternRef, name: *const c_char) -> u8; } + +pub type Typelibrary = Rc; + +#[cfg(not(feature = "mock_data"))] +mod implementation { + use super::*; + use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; + use alloc::rc::Rc; + use alloc::string::{String, ToString}; + use cstr_core::{c_char, CString}; + use spin::RwLock; + + struct TypeLibraryInner { + reference: ExternRef, + name_to_type_cache: RwLock>, + effectiveness_cache: RwLock>, + } + + #[derive(Clone)] + pub struct TypeLibraryImpl { + inner: Rc, + } + + impl TypeLibraryImpl { + #[cfg(not(feature = "mock_data"))] + pub(crate) fn new(reference: ExternRef) -> Self { + Self { + inner: Rc::new(TypeLibraryInner { + reference, + name_to_type_cache: Default::default(), + effectiveness_cache: Default::default(), + }), + } + } + } + + impl TypeLibraryTrait for TypeLibraryImpl { + fn get_type_from_name(&self, name: &str) -> Option { + if let Some(cached) = self.inner.name_to_type_cache.read().get(name) { + return Some(*cached); + } + let cstr = CString::new(name).unwrap(); + let v = unsafe { type_library_get_type_by_name(self.inner.reference, cstr.as_ptr()) }; + if v == 255 { + return None; + } + let v = v.into(); + self.inner + .name_to_type_cache + .write() + .insert(name.to_string(), v); + Some(v) + } + + fn get_single_effectiveness( + &self, + attacking_type: TypeIdentifier, + defending_type: TypeIdentifier, + ) -> f32 { + if let Some(cached) = self + .inner + .effectiveness_cache + .read() + .get(&(attacking_type, defending_type)) + { + return *cached; + } + let effectiveness = unsafe { + type_library_get_single_effectiveness( + self.inner.reference, + attacking_type.into(), + defending_type.into(), + ) + }; + self.inner + .effectiveness_cache + .write() + .insert((attacking_type, defending_type), effectiveness); + effectiveness + } + + fn get_effectiveness( + &self, + attacking_type: TypeIdentifier, + defending_types: &[TypeIdentifier], + ) -> f32 { + let mut f = 1.0; + for defending_type in defending_types { + f *= self.get_single_effectiveness(attacking_type, *defending_type); + } + f + } + } + + crate::handling::cacheable::cacheable!(TypeLibraryImpl); + + #[cfg(not(feature = "mock_data"))] + impl ExternalReferenceType for TypeLibraryImpl { + fn from_extern_value(reference: ExternRef) -> Self { + Self::new(reference) + } + } + + #[cfg(not(feature = "mock_data"))] + extern "wasm" { + fn type_library_get_single_effectiveness( + r: ExternRef, + attacking_type: u8, + defending_type: u8, + ) -> f32; + fn type_library_get_type_by_name(r: ExternRef, name: *const c_char) -> u8; + } +} + +#[cfg(not(feature = "mock_data"))] +pub use implementation::*; diff --git a/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs b/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs index 616e391..da174df 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs @@ -1,4 +1,5 @@ use crate::app_interface::StringKey; +#[cfg(not(feature = "mock_data"))] use crate::{ExternRef, ExternalReferenceType}; use core::fmt::{Display, Formatter}; @@ -40,28 +41,28 @@ impl EffectParameter { if let EffectParameter::Bool(b) = self { return *b; } - panic!("Unexpected effect parameter type: {}", self); + panic!("Unexpected effect parameter type: {self}"); } pub fn as_int(&self) -> i64 { if let EffectParameter::Int(i) = self { return *i; } - panic!("Unexpected effect parameter type: {}", self); + panic!("Unexpected effect parameter type: {self}"); } pub fn as_float(&self) -> f32 { if let EffectParameter::Float(f) = self { return *f; } - panic!("Unexpected effect parameter type: {}", self); + panic!("Unexpected effect parameter type: {self}"); } pub fn as_string(&self) -> StringKey { if let EffectParameter::String(s) = self { return s.clone(); } - panic!("Unexpected effect parameter type: {}", self); + panic!("Unexpected effect parameter type: {self}"); } } @@ -79,11 +80,11 @@ impl Display for EffectParameter { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { match self { EffectParameter::None => f.write_str("EffectParameter::None"), - EffectParameter::Bool(b) => f.write_fmt(format_args!("EffectParameter::Bool({})", b)), - EffectParameter::Int(i) => f.write_fmt(format_args!("EffectParameter::Int({})", i)), - EffectParameter::Float(r) => f.write_fmt(format_args!("EffectParameter::Float({})", r)), + EffectParameter::Bool(b) => f.write_fmt(format_args!("EffectParameter::Bool({b})")), + EffectParameter::Int(i) => f.write_fmt(format_args!("EffectParameter::Int({i})")), + EffectParameter::Float(r) => f.write_fmt(format_args!("EffectParameter::Float({r})")), EffectParameter::String(s) => { - f.write_fmt(format_args!("EffectParameter::String(\"{}\")", s)) + f.write_fmt(format_args!("EffectParameter::String(\"{s}\")")) } } } diff --git a/pkmn_lib_interface/src/app_interface/static_data/item.rs b/pkmn_lib_interface/src/app_interface/static_data/item.rs index 066100a..5e3eaa4 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/item.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/item.rs @@ -1,6 +1,4 @@ -use crate::handling::cached_value::CachedValue; -use crate::handling::Cacheable; -use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType, StringKey}; +use crate::app_interface::StringKey; use alloc::rc::Rc; /// An item category defines which bag slot items are stored in. @@ -59,75 +57,87 @@ pub type Item = Rc; #[cfg(feature = "mock_data")] pub type MockItem = MockItemTrait; -struct ItemInner { - reference: ExternRef, - name: CachedValue, - category: CachedValue, - battle_category: CachedValue, - price: CachedValue, -} - -/// An item is an object which the player can pick up, keep in their Bag, and use in some manner -#[derive(Clone)] -pub struct ItemImpl { - inner: Rc, -} - #[cfg(not(feature = "mock_data"))] -impl ItemImpl { - pub(crate) fn new(reference: ExternRef) -> Self { - Self::from_ref(reference, &|reference| Self { - inner: Rc::new(ItemInner { - reference, - name: cached_value!({ StringKey::new(item_get_name(reference)) }), - category: cached_value!({ item_get_category(reference) }), - battle_category: cached_value!({ item_get_battle_category(reference) }), - price: cached_value!({ item_get_price(reference) }), - }), - }) +mod implementation { + use crate::app_interface::{BattleItemCategory, ItemCategory, ItemTrait, StringKey}; + use crate::handling::cached_value::CachedValue; + use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; + use crate::handling::Cacheable; + use crate::{cached_value, cached_value_getters}; + use alloc::rc::Rc; + + struct ItemInner { + reference: ExternRef, + name: CachedValue, + category: CachedValue, + battle_category: CachedValue, + price: CachedValue, } - pub(crate) fn reference(&self) -> ExternRef { - self.inner.reference + /// An item is an object which the player can pick up, keep in their Bag, and use in some manner + #[derive(Clone)] + pub struct ItemImpl { + inner: Rc, + } + + #[cfg(not(feature = "mock_data"))] + impl ItemImpl { + pub(crate) fn new(reference: ExternRef) -> Self { + Self::from_ref(reference, &|reference| Self { + inner: Rc::new(ItemInner { + reference, + name: cached_value!({ StringKey::new(item_get_name(reference)) }), + category: cached_value!({ item_get_category(reference) }), + battle_category: cached_value!({ item_get_battle_category(reference) }), + price: cached_value!({ item_get_price(reference) }), + }), + }) + } + + pub(crate) fn reference(&self) -> ExternRef { + self.inner.reference + } + } + + #[cfg(not(feature = "mock_data"))] + impl ItemTrait for ItemImpl { + fn reference(&self) -> u32 { + self.inner.reference.get_internal_index() + } + + cached_value_getters! { + /// The name of the item. + fn name(&self) -> StringKey; + /// Which bag slot items are stored in. + fn category(&self) -> ItemCategory; + /// How the item is categorized when in battle. + fn battle_category(&self) -> BattleItemCategory; + /// The buying value of the item. + fn price(&self) -> i32; + } + + fn has_flag(&self, flag: &StringKey) -> bool { + unsafe { item_has_flag(self.inner.reference, flag.ptr()) } + } + } + + crate::handling::cacheable::cacheable!(ItemImpl); + + #[cfg(not(feature = "mock_data"))] + impl ExternalReferenceType for ItemImpl { + fn from_extern_value(reference: ExternRef) -> Self { + ItemImpl::new(reference) + } + } + + extern "wasm" { + fn item_get_name(ptr: ExternRef) -> ExternRef; + fn item_get_category(ptr: ExternRef) -> ItemCategory; + fn item_get_battle_category(ptr: ExternRef) -> BattleItemCategory; + fn item_get_price(ptr: ExternRef) -> i32; + fn item_has_flag(ptr: ExternRef, flag: ExternRef) -> bool; } } #[cfg(not(feature = "mock_data"))] -impl ItemTrait for ItemImpl { - fn reference(&self) -> u32 { - self.inner.reference.get_internal_index() - } - - cached_value_getters! { - /// The name of the item. - fn name(&self) -> StringKey; - /// Which bag slot items are stored in. - fn category(&self) -> ItemCategory; - /// How the item is categorized when in battle. - fn battle_category(&self) -> BattleItemCategory; - /// The buying value of the item. - fn price(&self) -> i32; - } - - fn has_flag(&self, flag: &StringKey) -> bool { - unsafe { item_has_flag(self.inner.reference, flag.ptr()) } - } -} - -crate::handling::cacheable::cacheable!(ItemImpl); - -#[cfg(not(feature = "mock_data"))] -impl ExternalReferenceType for ItemImpl { - fn from_extern_value(reference: ExternRef) -> Self { - ItemImpl::new(reference) - } -} - -#[cfg(not(feature = "mock_data"))] -extern "wasm" { - fn item_get_name(ptr: ExternRef) -> ExternRef; - fn item_get_category(ptr: ExternRef) -> ItemCategory; - fn item_get_battle_category(ptr: ExternRef) -> BattleItemCategory; - fn item_get_price(ptr: ExternRef) -> i32; - fn item_has_flag(ptr: ExternRef, flag: ExternRef) -> bool; -} +pub use implementation::*; diff --git a/pkmn_lib_interface/src/app_interface/static_data/mod.rs b/pkmn_lib_interface/src/app_interface/static_data/mod.rs index 230a80e..cd2799d 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/mod.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/mod.rs @@ -5,14 +5,16 @@ pub mod item; pub mod move_data; mod nature; pub mod species; +pub mod statistics; pub use ability::*; pub use data_libraries::*; -pub use effect_parameter::EffectParameter; +pub use effect_parameter::*; pub use item::*; pub use move_data::*; pub use nature::*; pub use species::*; +pub use statistics::*; pub type LevelInt = u8; diff --git a/pkmn_lib_interface/src/app_interface/static_data/move_data.rs b/pkmn_lib_interface/src/app_interface/static_data/move_data.rs index 84a567d..8df5d6a 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/move_data.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/move_data.rs @@ -1,7 +1,4 @@ -use crate::app_interface::{get_hash, StringKey}; -use crate::handling::cached_value::CachedValue; -use crate::handling::Cacheable; -use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType}; +use crate::app_interface::StringKey; use alloc::rc::Rc; #[repr(u8)] @@ -32,102 +29,102 @@ pub enum MoveTarget { OnSelf, } -struct MoveDataInner { - ptr: ExternRef, - name: CachedValue, - move_type: CachedValue, - category: CachedValue, - base_power: CachedValue, - accuracy: CachedValue, - base_usages: CachedValue, - target: CachedValue, - priority: CachedValue, +pub trait MoveDataTrait { + fn name(&self) -> StringKey; + fn move_type(&self) -> u8; + fn category(&self) -> MoveCategory; + fn base_power(&self) -> u8; + fn accuracy(&self) -> u8; + fn base_usages(&self) -> u8; + fn target(&self) -> MoveTarget; + fn priority(&self) -> i8; + fn has_flag(&self, flag: &str) -> bool; } -#[derive(Clone)] -pub struct MoveData { - inner: Rc, -} +pub type MoveData = Rc; -impl MoveData { - #[cfg(not(feature = "mock_data"))] - pub(crate) fn new(ptr: ExternRef) -> Self { - MoveData::from_ref(ptr, &|ptr| Self { - inner: Rc::new(MoveDataInner { - ptr, - name: cached_value!({ StringKey::new(move_data_get_name(ptr)) }), - move_type: cached_value!({ move_data_get_type(ptr) }), - category: cached_value!({ move_data_get_category(ptr) }), - base_power: cached_value!({ move_data_get_base_power(ptr) }), - accuracy: cached_value!({ move_data_get_accuracy(ptr) }), - base_usages: cached_value!({ move_data_get_base_power(ptr) }), - target: cached_value!({ move_data_get_target(ptr) }), - priority: cached_value!({ move_data_get_priority(ptr) }), - }), - }) +#[cfg(not(feature = "mock_data"))] +mod implementation { + use super::*; + use crate::app_interface::get_hash; + use crate::handling::cached_value::CachedValue; + use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; + use crate::handling::Cacheable; + use crate::{cached_value, cached_value_getters}; + + struct MoveDataInner { + ptr: ExternRef, + name: CachedValue, + move_type: CachedValue, + category: CachedValue, + base_power: CachedValue, + accuracy: CachedValue, + base_usages: CachedValue, + target: CachedValue, + priority: CachedValue, } - #[cfg(feature = "mock_data")] - pub fn mock( - name: &str, - move_type: u8, - category: MoveCategory, - base_power: u8, - accuracy: u8, - base_usages: u8, - target: MoveTarget, - priority: i8, - ) -> Self { - Self { - inner: Rc::new(MoveDataInner { - ptr: ExternRef::mock(), - name: StringKey::new(name).into(), - move_type: move_type.into(), - category: category.into(), - base_power: base_power.into(), - accuracy: accuracy.into(), - base_usages: base_usages.into(), - target: target.into(), - priority: priority.into(), - }), + + #[derive(Clone)] + pub struct MoveDataImpl { + inner: Rc, + } + + impl MoveDataImpl { + pub(crate) fn new(ptr: ExternRef) -> Self { + MoveDataImpl::from_ref(ptr, &|ptr| Self { + inner: Rc::new(MoveDataInner { + ptr, + name: cached_value!({ StringKey::new(move_data_get_name(ptr)) }), + move_type: cached_value!({ move_data_get_type(ptr) }), + category: cached_value!({ move_data_get_category(ptr) }), + base_power: cached_value!({ move_data_get_base_power(ptr) }), + accuracy: cached_value!({ move_data_get_accuracy(ptr) }), + base_usages: cached_value!({ move_data_get_base_power(ptr) }), + target: cached_value!({ move_data_get_target(ptr) }), + priority: cached_value!({ move_data_get_priority(ptr) }), + }), + }) } } - cached_value_getters! { - pub fn name(&self) -> StringKey; - pub fn move_type(&self) -> u8; - pub fn category(&self) -> MoveCategory; - pub fn base_power(&self) -> u8; - pub fn accuracy(&self) -> u8; - pub fn base_usages(&self) -> u8; - pub fn target(&self) -> MoveTarget; - pub fn priority(&self) -> i8; + impl MoveDataTrait for MoveDataImpl { + cached_value_getters! { + fn name(&self) -> StringKey; + fn move_type(&self) -> u8; + fn category(&self) -> MoveCategory; + fn base_power(&self) -> u8; + fn accuracy(&self) -> u8; + fn base_usages(&self) -> u8; + fn target(&self) -> MoveTarget; + fn priority(&self) -> i8; + } + + fn has_flag(&self, flag: &str) -> bool { + let hash = get_hash(flag); + unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash) } + } } - #[cfg(not(feature = "mock_data"))] - pub fn has_flag(&self, flag: &str) -> bool { - let hash = get_hash(flag); - unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash) } + impl ExternalReferenceType for MoveDataImpl { + fn from_extern_value(reference: ExternRef) -> Self { + MoveDataImpl::new(reference) + } + } + + crate::handling::cacheable::cacheable!(MoveDataImpl); + + extern "wasm" { + fn move_data_get_name(ptr: ExternRef) -> ExternRef; + fn move_data_get_type(ptr: ExternRef) -> u8; + fn move_data_get_category(ptr: ExternRef) -> MoveCategory; + fn move_data_get_base_power(ptr: ExternRef) -> u8; + fn move_data_get_accuracy(ptr: ExternRef) -> u8; + fn move_data_get_base_usages(ptr: ExternRef) -> u8; + fn move_data_get_target(ptr: ExternRef) -> MoveTarget; + fn move_data_get_priority(ptr: ExternRef) -> i8; + fn move_data_has_flag_by_hash(ptr: ExternRef, flag_hash: u32) -> bool; } } #[cfg(not(feature = "mock_data"))] -impl ExternalReferenceType for MoveData { - fn from_extern_value(reference: ExternRef) -> Self { - MoveData::new(reference) - } -} - -crate::handling::cacheable::cacheable!(MoveData); - -#[cfg(not(feature = "mock_data"))] -extern "wasm" { - fn move_data_get_name(ptr: ExternRef) -> ExternRef; - fn move_data_get_type(ptr: ExternRef) -> u8; - fn move_data_get_category(ptr: ExternRef) -> MoveCategory; - fn move_data_get_base_power(ptr: ExternRef) -> u8; - fn move_data_get_accuracy(ptr: ExternRef) -> u8; - fn move_data_get_base_usages(ptr: ExternRef) -> u8; - fn move_data_get_target(ptr: ExternRef) -> MoveTarget; - fn move_data_get_priority(ptr: ExternRef) -> i8; - fn move_data_has_flag_by_hash(ptr: ExternRef, flag_hash: u32) -> bool; -} +pub use implementation::*; diff --git a/pkmn_lib_interface/src/app_interface/static_data/nature.rs b/pkmn_lib_interface/src/app_interface/static_data/nature.rs index a2a6449..5b7f55b 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/nature.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/nature.rs @@ -1,55 +1,87 @@ use crate::app_interface::Statistic; -use crate::handling::cacheable::Cacheable; -use crate::{ExternRef, ExternalReferenceType}; use alloc::rc::Rc; -struct NatureInner { - reference: ExternRef, - /// The stat that should receive the increased modifier. - increase_stat: Statistic, - /// The stat that should receive the decreased modifier. - decrease_stat: Statistic, - /// The amount by which the increased stat is multiplied. - increase_modifier: f32, - /// The amount by which the decreased stat is multiplied. - decrease_modifier: f32, +pub trait NatureTrait { + fn increase_stat(&self) -> Statistic; + fn decrease_stat(&self) -> Statistic; + fn increase_modifier(&self) -> f32; + fn decrease_modifier(&self) -> f32; } -#[derive(Clone)] -pub struct Nature { - inner: Rc, -} +pub type Nature = Rc; -crate::handling::cacheable::cacheable!(Nature); +#[cfg(not(feature = "mock_data"))] +mod implementation { + use super::*; + use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; + use crate::handling::Cacheable; -impl Nature { - #[cfg(not(feature = "mock_data"))] - pub fn new(reference: ExternRef) -> Self { - Self::from_ref(reference, &|reference| unsafe { - Self { - inner: Rc::new(NatureInner { - reference, - increase_stat: nature_get_increase_stat(reference), - decrease_stat: nature_get_decrease_stat(reference), - increase_modifier: nature_get_increase_modifier(reference), - decrease_modifier: nature_get_decrease_modifier(reference), - }), - } - }) + struct NatureInner { + reference: ExternRef, + /// The stat that should receive the increased modifier. + increase_stat: Statistic, + /// The stat that should receive the decreased modifier. + decrease_stat: Statistic, + /// The amount by which the increased stat is multiplied. + increase_modifier: f32, + /// The amount by which the decreased stat is multiplied. + decrease_modifier: f32, + } + + #[derive(Clone)] + pub struct NatureImpl { + inner: Rc, + } + + crate::handling::cacheable::cacheable!(NatureImpl); + + impl NatureImpl { + pub fn new(reference: ExternRef) -> Self { + Self::from_ref(reference, &|reference| unsafe { + Self { + inner: Rc::new(NatureInner { + reference, + increase_stat: nature_get_increase_stat(reference), + decrease_stat: nature_get_decrease_stat(reference), + increase_modifier: nature_get_increase_modifier(reference), + decrease_modifier: nature_get_decrease_modifier(reference), + }), + } + }) + } + } + + impl NatureTrait for NatureImpl { + fn increase_stat(&self) -> Statistic { + self.inner.increase_stat + } + + fn decrease_stat(&self) -> Statistic { + self.inner.decrease_stat + } + + fn increase_modifier(&self) -> f32 { + self.inner.increase_modifier + } + + fn decrease_modifier(&self) -> f32 { + self.inner.decrease_modifier + } + } + + impl ExternalReferenceType for NatureImpl { + fn from_extern_value(reference: ExternRef) -> Self { + Self::new(reference) + } + } + + extern "wasm" { + fn nature_get_increase_stat(r: ExternRef) -> Statistic; + fn nature_get_decrease_stat(r: ExternRef) -> Statistic; + fn nature_get_increase_modifier(r: ExternRef) -> f32; + fn nature_get_decrease_modifier(r: ExternRef) -> f32; } } #[cfg(not(feature = "mock_data"))] -impl ExternalReferenceType for Nature { - fn from_extern_value(reference: ExternRef) -> Self { - Self::new(reference) - } -} - -#[cfg(not(feature = "mock_data"))] -extern "wasm" { - fn nature_get_increase_stat(r: ExternRef) -> Statistic; - fn nature_get_decrease_stat(r: ExternRef) -> Statistic; - fn nature_get_increase_modifier(r: ExternRef) -> f32; - fn nature_get_decrease_modifier(r: ExternRef) -> f32; -} +pub use implementation::*; diff --git a/pkmn_lib_interface/src/app_interface/static_data/species.rs b/pkmn_lib_interface/src/app_interface/static_data/species.rs index 2ff4399..49e55e3 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/species.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/species.rs @@ -1,16 +1,8 @@ -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::ffi_array::FFIArray; -use crate::handling::Cacheable; -use crate::{ - cached_value, cached_value_getters, ExternRef, ExternalReferenceType, StringKey, VecExternRef, -}; +use crate::app_interface::{ImmutableStatisticSet, StringKey}; use alloc::rc::Rc; use alloc::vec::Vec; -use spin::RwLock; +use core::any::Any; #[repr(u8)] #[derive(Eq, PartialEq, Debug)] @@ -20,275 +12,250 @@ pub enum Gender { Genderless = 2, } -#[repr(u8)] -#[derive(Eq, PartialEq, Debug)] -pub enum Statistic { - HP = 0, - Attack = 1, - Defense = 2, - SpecialAttack = 3, - SpecialDefense = 4, - Speed = 5, +pub trait FormTrait { + fn name(&self) -> StringKey; + fn height(&self) -> f32; + fn weight(&self) -> f32; + fn base_experience(&self) -> u32; + fn base_stats(&self) -> ImmutableStatisticSet; + fn abilities(&self) -> ImmutableList>; + fn hidden_abilities(&self) -> ImmutableList>; + fn types(&self) -> &Vec; + fn has_flag(&self, flag: &str) -> bool; + + fn as_any(&self) -> &dyn Any; } -pub struct ImmutableStatisticSetInner { - reference: ExternRef, - /// The health point stat value. - hp: CachedValue, - /// The physical attack stat value. - attack: CachedValue, - /// The physical defense stat value. - defense: CachedValue, - /// The special attack stat value. - special_attack: CachedValue, - /// The special defense stat value. - special_defense: CachedValue, - /// The speed stat value. - speed: CachedValue, +pub trait SpeciesTrait { + /// The national dex identifier of the Pokemon. + fn id(&self) -> u16; + /// The name of the Pokemon species. + fn name(&self) -> StringKey; + /// The chance between 0.0 and 1.0 that a Pokemon is female. + fn gender_rate(&self) -> f32; + /// How much experience is required for a level. + fn growth_rate(&self) -> StringKey; + /// How hard it is to capture a Pokemon. 255 means this will be always caught, 0 means this is + /// uncatchable. + fn capture_rate(&self) -> u8; + fn get_form(&self, form_name: &str) -> Option; + fn has_flag(&self, flag: &str) -> bool; + + fn as_any(&self) -> &dyn Any; } -#[derive(Clone)] -pub struct ImmutableStatisticSet { - inner: Rc, -} +pub type Form = Rc; +pub type Species = Rc; -impl ImmutableStatisticSet { - #[cfg(not(feature = "mock_data"))] - pub(crate) fn new(reference: ExternRef) -> Self { - Self::from_ref(reference, &|reference| Self { - inner: Rc::new(ImmutableStatisticSetInner { - reference, - hp: cached_value!({ static_statistics_set_get_hp(reference) }), - attack: cached_value!({ static_statistics_set_get_attack(reference) }), - defense: cached_value!({ static_statistics_set_get_defense(reference) }), - special_attack: cached_value!({ - static_statistics_set_get_special_attack(reference) +#[cfg(not(feature = "mock_data"))] +mod implementation { + use super::*; + use crate::app_interface::list::ImmutableListWasm; + use crate::app_interface::{get_hash, ImmutableStatisticSetImpl}; + use crate::handling::cached_value::CachedValue; + use crate::handling::extern_ref::{ExternRef, ExternalReferenceType, VecExternRef}; + use crate::handling::ffi_array::FFIArray; + use crate::handling::Cacheable; + use crate::{cached_value, cached_value_getters}; + use spin::RwLock; + + struct FormInner { + reference: ExternRef, + name: CachedValue, + height: CachedValue, + weight: CachedValue, + types: CachedValue>, + base_experience: CachedValue, + base_stats: CachedValue, + abilities: CachedValue>>, + hidden_abilities: CachedValue>>, + // moves: CachedValue, + } + + #[derive(Clone)] + pub struct FormImpl { + inner: Rc, + } + + impl FormImpl { + pub(crate) fn new(reference: ExternRef) -> Self { + Self::from_ref(reference, &|reference| Self { + inner: Rc::new(FormInner { + reference, + name: cached_value!({ form_get_name(reference).get_value().unwrap() }), + height: cached_value!({ form_get_height(reference) }), + weight: cached_value!({ form_get_weight(reference) }), + types: cached_value!({ + let raw = form_get_types(reference); + Vec::from_raw_parts(raw.ptr(), raw.len(), raw.len()) + }), + base_experience: cached_value!({ form_get_base_experience(reference) }), + base_stats: cached_value!({ + Rc::new(form_get_base_stats(reference).get_value().unwrap()) + }), + abilities: cached_value!({ + Rc::new( + crate::app_interface::list::StringKeyImmutableList::from_ref( + form_get_abilities(reference), + ), + ) + }), + hidden_abilities: cached_value!({ + Rc::new( + crate::app_interface::list::StringKeyImmutableList::from_ref( + form_get_hidden_abilities(reference), + ), + ) + }), }), - special_defense: cached_value!({ - static_statistics_set_get_special_defense(reference) - }), - speed: cached_value!({ static_statistics_set_get_speed(reference) }), - }), - }) - } + }) + } - pub fn hp(&self) -> u16 { - self.inner.hp.value() - } - pub fn attack(&self) -> u16 { - self.inner.attack.value() - } - pub fn defense(&self) -> u16 { - self.inner.defense.value() - } - pub fn special_attack(&self) -> u16 { - self.inner.special_attack.value() - } - pub fn special_defense(&self) -> u16 { - self.inner.special_defense.value() - } - pub fn speed(&self) -> u16 { - self.inner.speed.value() - } -} - -struct FormInner { - reference: ExternRef, - name: CachedValue, - height: CachedValue, - weight: CachedValue, - types: CachedValue>, - base_experience: CachedValue, - base_stats: CachedValue, - abilities: CachedValue>>, - hidden_abilities: CachedValue>>, - // moves: CachedValue, -} - -#[derive(Clone)] -pub struct Form { - inner: Rc, -} - -impl Form { - #[cfg(not(feature = "mock_data"))] - pub(crate) fn new(reference: ExternRef) -> Self { - Self::from_ref(reference, &|reference| Self { - inner: Rc::new(FormInner { - reference, - name: cached_value!({ form_get_name(reference).get_value().unwrap() }), - height: cached_value!({ form_get_height(reference) }), - weight: cached_value!({ form_get_weight(reference) }), - types: cached_value!({ - let raw = form_get_types(reference); - Vec::from_raw_parts(raw.ptr(), raw.len(), raw.len()) - }), - base_experience: cached_value!({ form_get_base_experience(reference) }), - base_stats: cached_value!({ form_get_base_stats(reference).get_value().unwrap() }), - abilities: cached_value!({ - Rc::new( - crate::app_interface::list::StringKeyImmutableList::from_ref( - form_get_abilities(reference), - ), - ) - }), - hidden_abilities: cached_value!({ - Rc::new( - crate::app_interface::list::StringKeyImmutableList::from_ref( - form_get_hidden_abilities(reference), - ), - ) - }), - }), - }) - } - - pub(crate) fn reference(&self) -> ExternRef { - self.inner.reference - } - - cached_value_getters! { - pub fn name(&self) -> StringKey; - pub fn height(&self) -> f32; - pub fn weight(&self) -> f32; - pub fn base_experience(&self) -> u32; - pub fn base_stats(&self) -> ImmutableStatisticSet; - pub fn abilities(&self) -> ImmutableList>; - pub fn hidden_abilities(&self) -> ImmutableList>; - } - pub fn types(&self) -> &Vec { - self.inner.types.value_ref() - } - - #[cfg(not(feature = "mock_data"))] - pub fn has_flag(&self, flag: &str) -> bool { - let hash = get_hash(flag); - unsafe { form_has_flag_by_hash(self.inner.reference, hash) } - } -} - -pub struct SpeciesInner { - reference: ExternRef, - id: CachedValue, - name: CachedValue, - gender_rate: CachedValue, - growth_rate: CachedValue, - capture_rate: CachedValue, - forms: RwLock>>, -} - -#[derive(Clone)] -pub struct Species { - inner: Rc, -} - -impl Species { - #[cfg(not(feature = "mock_data"))] - pub(crate) fn new(reference: ExternRef) -> Self { - Self { - inner: Rc::new(SpeciesInner { - reference, - id: cached_value!({ species_get_id(reference) }), - name: cached_value!({ species_get_name(reference).get_value().unwrap() }), - gender_rate: cached_value!({ species_get_gender_rate(reference) }), - growth_rate: cached_value!({ - species_get_growth_rate(reference).get_value().unwrap() - }), - capture_rate: cached_value!({ species_get_capture_rate(reference) }), - forms: Default::default(), - }), + pub(crate) fn reference(&self) -> ExternRef { + self.inner.reference } } - pub(crate) fn reference(&self) -> ExternRef { - self.inner.reference + impl FormTrait for FormImpl { + cached_value_getters! { + fn name(&self) -> StringKey; + fn height(&self) -> f32; + fn weight(&self) -> f32; + fn base_experience(&self) -> u32; + fn base_stats(&self) -> ImmutableStatisticSet; + fn abilities(&self) -> ImmutableList>; + fn hidden_abilities(&self) -> ImmutableList>; + } + fn types(&self) -> &Vec { + self.inner.types.value_ref() + } + + fn has_flag(&self, flag: &str) -> bool { + let hash = get_hash(flag); + unsafe { form_has_flag_by_hash(self.inner.reference, hash) } + } + + fn as_any(&self) -> &dyn Any { + self + } } - cached_value_getters! { - /// The national dex identifier of the Pokemon. - pub fn id(&self) -> u16; - /// The name of the Pokemon species. - pub fn name(&self) -> StringKey; - /// The chance between 0.0 and 1.0 that a Pokemon is female. - pub fn gender_rate(&self) -> f32; - /// How much experience is required for a level. - pub fn growth_rate(&self) -> StringKey; - /// How hard it is to capture a Pokemon. 255 means this will be always caught, 0 means this is - /// uncatchable. - pub fn capture_rate(&self) -> u8; + pub struct SpeciesInner { + reference: ExternRef, + id: CachedValue, + name: CachedValue, + gender_rate: CachedValue, + growth_rate: CachedValue, + capture_rate: CachedValue, + forms: RwLock>>, } - #[cfg(not(feature = "mock_data"))] - pub fn get_form(&self, form_name: &str) -> Option { - let hash = get_hash(form_name); - unsafe { - if let Some(v) = self.inner.forms.read().get(&hash) { - v.clone() - } else { - let r = species_get_form_by_hash(self.inner.reference, hash); - let value = r.get_value(); - self.inner.forms.write().insert(hash, value.clone()); - value + #[derive(Clone)] + pub struct SpeciesImpl { + inner: Rc, + } + + impl SpeciesImpl { + pub(crate) fn new(reference: ExternRef) -> Self { + Self { + inner: Rc::new(SpeciesInner { + reference, + id: cached_value!({ species_get_id(reference) }), + name: cached_value!({ species_get_name(reference).get_value().unwrap() }), + gender_rate: cached_value!({ species_get_gender_rate(reference) }), + growth_rate: cached_value!({ + species_get_growth_rate(reference).get_value().unwrap() + }), + capture_rate: cached_value!({ species_get_capture_rate(reference) }), + forms: Default::default(), + }), } } + + pub(crate) fn reference(&self) -> ExternRef { + self.inner.reference + } } - #[cfg(not(feature = "mock_data"))] - pub fn has_flag(&self, flag: &str) -> bool { - let hash = get_hash(flag); - unsafe { species_has_flag_by_hash(self.inner.reference, hash) } + impl SpeciesTrait for SpeciesImpl { + cached_value_getters! { + /// The national dex identifier of the Pokemon. + fn id(&self) -> u16; + /// The name of the Pokemon species. + fn name(&self) -> StringKey; + /// The chance between 0.0 and 1.0 that a Pokemon is female. + fn gender_rate(&self) -> f32; + /// How much experience is required for a level. + fn growth_rate(&self) -> StringKey; + /// How hard it is to capture a Pokemon. 255 means this will be always caught, 0 means this is + /// uncatchable. + fn capture_rate(&self) -> u8; + } + + fn get_form(&self, form_name: &str) -> Option { + let hash = get_hash(form_name); + unsafe { + if let Some(v) = self.inner.forms.read().get(&hash) { + v.clone() + } else { + let r = species_get_form_by_hash(self.inner.reference, hash); + let value = r.get_value(); + let value: Option = if let Some(value) = value { + Some(Rc::new(value)) + } else { + None + }; + self.inner.forms.write().insert(hash, value.clone()); + value + } + } + } + + fn has_flag(&self, flag: &str) -> bool { + let hash = get_hash(flag); + unsafe { species_has_flag_by_hash(self.inner.reference, hash) } + } + + fn as_any(&self) -> &dyn Any { + self + } + } + + impl ExternalReferenceType for FormImpl { + fn from_extern_value(reference: ExternRef) -> Self { + Self::new(reference) + } + } + + impl ExternalReferenceType for SpeciesImpl { + fn from_extern_value(reference: ExternRef) -> Self { + Self::new(reference) + } + } + + crate::handling::cacheable::cacheable!(FormImpl); + crate::handling::cacheable::cacheable!(SpeciesImpl); + + extern "wasm" { + fn form_get_name(r: ExternRef) -> ExternRef; + fn form_get_height(r: ExternRef) -> f32; + fn form_get_weight(r: ExternRef) -> f32; + fn form_get_types(r: ExternRef) -> FFIArray; + fn form_get_base_experience(r: ExternRef) -> u32; + fn form_get_base_stats(r: ExternRef) -> ExternRef; + fn form_get_abilities(r: ExternRef) -> VecExternRef; + fn form_get_hidden_abilities(r: ExternRef) -> VecExternRef; + fn form_has_flag_by_hash(r: ExternRef, hash: u32) -> bool; + + fn species_get_id(r: ExternRef) -> u16; + fn species_get_name(r: ExternRef) -> ExternRef; + fn species_get_gender_rate(r: ExternRef) -> f32; + fn species_get_growth_rate(r: ExternRef) -> ExternRef; + fn species_get_capture_rate(r: ExternRef) -> u8; + fn species_get_form_by_hash(r: ExternRef, hash: u32) -> ExternRef; + fn species_has_flag_by_hash(r: ExternRef, flag_hash: u32) -> bool; } } #[cfg(not(feature = "mock_data"))] -impl ExternalReferenceType for ImmutableStatisticSet { - fn from_extern_value(reference: ExternRef) -> Self { - Self::new(reference) - } -} - -#[cfg(not(feature = "mock_data"))] -impl ExternalReferenceType for Form { - fn from_extern_value(reference: ExternRef) -> Self { - Self::new(reference) - } -} - -#[cfg(not(feature = "mock_data"))] -impl ExternalReferenceType for Species { - fn from_extern_value(reference: ExternRef) -> Self { - Self::new(reference) - } -} - -crate::handling::cacheable::cacheable!(ImmutableStatisticSet); -crate::handling::cacheable::cacheable!(Form); -crate::handling::cacheable::cacheable!(Species); - -#[cfg(not(feature = "mock_data"))] -extern "wasm" { - fn static_statistics_set_get_hp(r: ExternRef) -> u16; - fn static_statistics_set_get_attack(r: ExternRef) -> u16; - fn static_statistics_set_get_defense(r: ExternRef) -> u16; - fn static_statistics_set_get_special_attack(r: ExternRef) -> u16; - fn static_statistics_set_get_special_defense(r: ExternRef) -> u16; - fn static_statistics_set_get_speed(r: ExternRef) -> u16; - - fn form_get_name(r: ExternRef) -> ExternRef; - fn form_get_height(r: ExternRef) -> f32; - fn form_get_weight(r: ExternRef) -> f32; - fn form_get_types(r: ExternRef) -> FFIArray; - fn form_get_base_experience(r: ExternRef) -> u32; - fn form_get_base_stats(r: ExternRef) -> ExternRef; - fn form_get_abilities(r: ExternRef) -> VecExternRef; - fn form_get_hidden_abilities(r: ExternRef) -> VecExternRef; - fn form_has_flag_by_hash(r: ExternRef, hash: u32) -> bool; - - fn species_get_id(r: ExternRef) -> u16; - fn species_get_name(r: ExternRef) -> ExternRef; - fn species_get_gender_rate(r: ExternRef) -> f32; - fn species_get_growth_rate(r: ExternRef) -> ExternRef; - fn species_get_capture_rate(r: ExternRef) -> u8; - fn species_get_form_by_hash(r: ExternRef, hash: u32) -> ExternRef; - fn species_has_flag_by_hash(r: ExternRef, flag_hash: u32) -> bool; -} +pub use implementation::*; diff --git a/pkmn_lib_interface/src/app_interface/static_data/statistics.rs b/pkmn_lib_interface/src/app_interface/static_data/statistics.rs new file mode 100644 index 0000000..a0cb2ed --- /dev/null +++ b/pkmn_lib_interface/src/app_interface/static_data/statistics.rs @@ -0,0 +1,116 @@ +use alloc::rc::Rc; + +#[repr(u8)] +#[derive(Eq, PartialEq, Debug, Copy, Clone)] +pub enum Statistic { + HP = 0, + Attack = 1, + Defense = 2, + SpecialAttack = 3, + SpecialDefense = 4, + Speed = 5, +} + +pub trait ImmutableStatisticSetTrait { + fn hp(&self) -> u16; + fn attack(&self) -> u16; + fn defense(&self) -> u16; + fn special_attack(&self) -> u16; + fn special_defense(&self) -> u16; + fn speed(&self) -> u16; +} + +pub type ImmutableStatisticSet = Rc; + +#[cfg(not(feature = "mock_data"))] +mod implementation { + use super::*; + use crate::cached_value; + use crate::handling::cached_value::CachedValue; + use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; + use crate::handling::Cacheable; + + pub struct ImmutableStatisticSetInner { + reference: ExternRef, + /// The health point stat value. + hp: CachedValue, + /// The physical attack stat value. + attack: CachedValue, + /// The physical defense stat value. + defense: CachedValue, + /// The special attack stat value. + special_attack: CachedValue, + /// The special defense stat value. + special_defense: CachedValue, + /// The speed stat value. + speed: CachedValue, + } + + #[derive(Clone)] + pub struct ImmutableStatisticSetImpl { + inner: Rc, + } + + impl ImmutableStatisticSetImpl { + pub(crate) fn new(reference: ExternRef) -> Self { + Self::from_ref(reference, &|reference| Self { + inner: Rc::new(ImmutableStatisticSetInner { + reference, + hp: cached_value!({ static_statistics_set_get_hp(reference) }), + attack: cached_value!({ static_statistics_set_get_attack(reference) }), + defense: cached_value!({ static_statistics_set_get_defense(reference) }), + special_attack: cached_value!({ + static_statistics_set_get_special_attack(reference) + }), + special_defense: cached_value!({ + static_statistics_set_get_special_defense(reference) + }), + speed: cached_value!({ static_statistics_set_get_speed(reference) }), + }), + }) + } + } + + impl ImmutableStatisticSetTrait for ImmutableStatisticSetImpl { + fn hp(&self) -> u16 { + self.inner.hp.value() + } + fn attack(&self) -> u16 { + self.inner.attack.value() + } + fn defense(&self) -> u16 { + self.inner.defense.value() + } + fn special_attack(&self) -> u16 { + self.inner.special_attack.value() + } + fn special_defense(&self) -> u16 { + self.inner.special_defense.value() + } + fn speed(&self) -> u16 { + self.inner.speed.value() + } + } + + impl ExternalReferenceType for ImmutableStatisticSetImpl { + fn from_extern_value(reference: ExternRef) -> Self { + Self::new(reference) + } + } + + crate::handling::cacheable::cacheable!(ImmutableStatisticSetImpl); + + extern "wasm" { + fn static_statistics_set_get_hp(r: ExternRef) -> u16; + fn static_statistics_set_get_attack(r: ExternRef) -> u16; + fn static_statistics_set_get_defense(r: ExternRef) -> u16; + fn static_statistics_set_get_special_attack(r: ExternRef) + -> u16; + fn static_statistics_set_get_special_defense( + r: ExternRef, + ) -> u16; + fn static_statistics_set_get_speed(r: ExternRef) -> u16; + } +} +#[cfg(not(feature = "mock_data"))] +pub use implementation::*; diff --git a/pkmn_lib_interface/src/app_interface/string_key.rs b/pkmn_lib_interface/src/app_interface/string_key.rs index 4756459..f668582 100755 --- a/pkmn_lib_interface/src/app_interface/string_key.rs +++ b/pkmn_lib_interface/src/app_interface/string_key.rs @@ -1,11 +1,14 @@ +#[cfg(not(feature = "mock_data"))] use crate::handling::Cacheable; +#[cfg(not(feature = "mock_data"))] use crate::{ExternRef, ExternalReferenceType}; use alloc::rc::Rc; use core::cell::RefCell; use core::fmt::{Display, Formatter}; -use cstr_core::{c_char, CString}; +use cstr_core::CString; struct StringKeyInner { + #[cfg(not(feature = "mock_data"))] ptr: ExternRef, str: RefCell>, hash: RefCell>, @@ -69,17 +72,24 @@ impl StringKey { self.data.hash.borrow().unwrap() } - pub fn eq(&self, other: &str) -> bool { + pub fn equals_str(&self, other: &str) -> bool { self.hash() == get_hash(other) } } impl PartialEq for StringKey { + #[cfg(not(feature = "mock_data"))] fn eq(&self, other: &Self) -> bool { self.data.ptr == other.data.ptr } + + #[cfg(feature = "mock_data")] + fn eq(&self, other: &Self) -> bool { + self.data.hash == other.data.hash + } } +#[cfg(not(feature = "mock_data"))] crate::handling::cacheable::cacheable!(StringKey); #[cfg(not(feature = "mock_data"))] @@ -98,7 +108,7 @@ impl Display for StringKey { #[cfg(not(feature = "mock_data"))] extern "wasm" { - fn string_key_get_str(ptr: ExternRef) -> *mut c_char; + fn string_key_get_str(ptr: ExternRef) -> *mut cstr_core::c_char; fn string_key_get_hash(ptr: ExternRef) -> u32; } @@ -159,7 +169,7 @@ pub const fn get_hash(s: &str) -> u32 { mod test { use super::get_hash; use super::StringKeyInner; - use crate::{ExternRef, StringKey}; + use crate::StringKey; use alloc::rc::Rc; use core::cell::RefCell; use cstr_core::CString; @@ -169,7 +179,6 @@ mod test { let hash = get_hash(s); Self { data: Rc::new(StringKeyInner { - ptr: ExternRef::mock(), str: RefCell::new(Some(CString::new(s).unwrap())), hash: RefCell::new(Some(hash)), }), diff --git a/pkmn_lib_interface/src/handling/extern_ref.rs b/pkmn_lib_interface/src/handling/extern_ref.rs index 1b63d10..6b26b4d 100755 --- a/pkmn_lib_interface/src/handling/extern_ref.rs +++ b/pkmn_lib_interface/src/handling/extern_ref.rs @@ -1,6 +1,7 @@ use alloc::rc::Rc; use core::cmp::Ordering; use core::hash::{Hash, Hasher}; +#[cfg(not(feature = "mock_data"))] use core::intrinsics::transmute; use core::marker::PhantomData; @@ -15,6 +16,7 @@ impl ExternRef { self.p == 0 } + #[cfg(not(feature = "mock_data"))] pub(crate) fn get_internal_index(&self) -> u32 { self.p } @@ -60,20 +62,13 @@ impl ExternRef { } #[inline] + #[cfg(not(feature = "mock_data"))] pub(crate) fn cast(&self) -> ExternRef { ExternRef:: { p: self.p, resource_type: Default::default(), } } - - #[cfg(feature = "mock_data")] - pub(crate) fn mock() -> Self { - Self { - p: 0, - resource_type: Default::default(), - } - } } impl Clone for ExternRef { @@ -133,11 +128,13 @@ impl VecExternRef { self.v == 0 } + #[cfg(not(feature = "mock_data"))] pub(crate) fn get_internal_index(&self) -> u32 { let v: (u32, u32) = unsafe { transmute(self.v) }; v.0 } + #[cfg(not(feature = "mock_data"))] pub(crate) fn len(&self) -> u32 { let v: (u32, u32) = unsafe { transmute(self.v) }; v.1 diff --git a/pkmn_lib_interface/src/handling/ffi_array.rs b/pkmn_lib_interface/src/handling/ffi_array.rs index fe069d7..a0bf2f0 100755 --- a/pkmn_lib_interface/src/handling/ffi_array.rs +++ b/pkmn_lib_interface/src/handling/ffi_array.rs @@ -1,4 +1,5 @@ use alloc::boxed::Box; +#[cfg(not(feature = "mock_data"))] use alloc::vec::Vec; use core::mem; @@ -18,7 +19,10 @@ impl FFIArray { mem::forget(boxed_slice); r } +} +#[cfg(not(feature = "mock_data"))] +impl FFIArray { fn delete(&self) { unsafe { drop(Vec::from_raw_parts(self.ptr, self.len, self.len)); diff --git a/pkmn_lib_interface/src/handling/mod.rs b/pkmn_lib_interface/src/handling/mod.rs index a384542..34ffad5 100755 --- a/pkmn_lib_interface/src/handling/mod.rs +++ b/pkmn_lib_interface/src/handling/mod.rs @@ -1,13 +1,17 @@ +#[cfg(not(feature = "mock_data"))] pub(crate) mod cacheable; +#[cfg(not(feature = "mock_data"))] pub(crate) mod cached_value; pub mod capabilities; pub mod extern_ref; pub mod ffi_array; pub mod script; +#[cfg(not(feature = "mock_data"))] pub(crate) mod temporary; pub use capabilities::*; +#[cfg(not(feature = "mock_data"))] pub(crate) use cacheable::Cacheable; pub use script::Script; diff --git a/pkmn_lib_interface/src/handling/script.rs b/pkmn_lib_interface/src/handling/script.rs index 466d83e..a4702db 100755 --- a/pkmn_lib_interface/src/handling/script.rs +++ b/pkmn_lib_interface/src/handling/script.rs @@ -4,11 +4,10 @@ use crate::app_interface::{ Pokemon, Statistic, TurnChoice, TypeIdentifier, }; use crate::handling::ScriptCapabilities; -use crate::{ExternRef, ExternalReferenceType, StringKey}; +use crate::StringKey; use alloc::rc::Rc; use core::any::Any; use core::fmt::{Debug, Display, Formatter}; -use core::panicking::panic; pub trait Script { fn new() -> Self @@ -364,7 +363,7 @@ impl Debug for dyn Script { #[cfg(not(feature = "mock_data"))] extern "wasm" { fn script_get_owner_kind(pointer: crate::implementation::ScriptPtr) -> u8; - fn script_get_owner(pointer: crate::implementation::ScriptPtr) -> ExternRef; + fn script_get_owner(pointer: crate::implementation::ScriptPtr) -> crate::ExternRef; } pub enum ScriptOwner { @@ -417,7 +416,7 @@ impl ScriptOwner { } #[cfg(feature = "mock_data")] - fn from_script(script: &dyn Script) -> Option { + fn from_script(_script: &dyn Script) -> Option { unimplemented!(); } diff --git a/pkmn_lib_interface/src/handling/temporary.rs b/pkmn_lib_interface/src/handling/temporary.rs index cc36f6f..ea0dda1 100755 --- a/pkmn_lib_interface/src/handling/temporary.rs +++ b/pkmn_lib_interface/src/handling/temporary.rs @@ -1,7 +1,6 @@ use alloc::rc::Rc; use core::sync::atomic::{AtomicBool, Ordering}; -#[cfg(not(feature = "mock_data"))] pub struct Temporary { is_deleted: Rc, value: Rc, diff --git a/pkmn_lib_interface/src/utils.rs b/pkmn_lib_interface/src/utils.rs index 18e2fa8..2421dbe 100755 --- a/pkmn_lib_interface/src/utils.rs +++ b/pkmn_lib_interface/src/utils.rs @@ -1,7 +1,9 @@ #[macro_export] +#[cfg(not(feature = "mock_data"))] macro_rules! println { ($($args:tt)*) => { crate::utils::print_raw(alloc::format!($($args)*).as_bytes()); } } #[macro_export] +#[cfg(not(feature = "mock_data"))] #[cfg(debug_assertions)] macro_rules! dbg { ($($args:tt)*) => { crate::utils::print_raw(alloc::format!($($args)*).as_bytes()); } } @@ -75,17 +77,3 @@ mod implementation { #[cfg(not(feature = "mock_data"))] pub use implementation::*; - -#[cfg(feature = "mock_data")] -mod mocked { - use super::*; - - pub fn print_raw(s: &[u8]) { - unsafe { - println!("{}", String::from_utf8_lossy(s)); - } - } -} - -#[cfg(feature = "mock_data")] -pub use mocked::*;