Cleanup to resolve all warnings when unit testing.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2023-01-06 14:17:46 +01:00
parent 258c497982
commit 1d66e08d48
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
28 changed files with 1113 additions and 879 deletions

View File

@ -1,5 +1,4 @@
[workspace] [workspace]
edition = "2021"
resolver = "2" resolver = "2"
members = [ members = [

View File

@ -7,6 +7,7 @@
extern crate alloc; extern crate alloc;
#[cfg(not(test))]
use alloc::boxed::Box; use alloc::boxed::Box;
#[cfg(not(test))] #[cfg(not(test))]
use pkmn_lib_interface::set_load_script_fn; use pkmn_lib_interface::set_load_script_fn;

View File

@ -44,7 +44,7 @@ mod tests {
use super::*; use super::*;
use alloc::rc::Rc; use alloc::rc::Rc;
use pkmn_lib_interface::app_interface::{ use pkmn_lib_interface::app_interface::{
MockBattle, MockBattleRandom, MockExecutingMove, MockHitData, MockItem, MockPokemon, MockBattle, MockBattleRandom, MockExecutingMove, MockHitData, MockPokemon,
}; };
#[test] #[test]

View File

@ -3,9 +3,8 @@ 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, DamageSource, ExecutingMove, Pokemon, TurnChoice, WithVolatile, BattleSide, DamageSource, ExecutingMove, Pokemon, TurnChoice,
}; };
use pkmn_lib_interface::handling::script::ScriptOwner;
use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; use pkmn_lib_interface::handling::{Script, ScriptCapabilities};
script!(Assurance, "assurance"); script!(Assurance, "assurance");

View File

@ -5,7 +5,7 @@ use crate::weather::hail::Hail;
use alloc::boxed::Box; 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::{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::ScriptCapabilities::OnEndTurn;
use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; use pkmn_lib_interface::handling::{Script, ScriptCapabilities};

View File

@ -129,7 +129,7 @@ mod implementation {
} }
fn has_weather(&self, name: &str) -> bool { fn has_weather(&self, name: &str) -> bool {
if let Some(weather) = self.weather_name() { if let Some(weather) = self.weather_name() {
if weather.eq(name) { if weather.equals_str(name) {
return true; return true;
} }
} }

View File

@ -43,7 +43,7 @@ pub use implementation::*;
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
mod implementation { mod implementation {
use super::*; use super::*;
use crate::app_interface::{LearnedMoveImpl, PokemonImpl}; use crate::app_interface::{LearnedMoveImpl, MoveDataImpl, PokemonImpl};
use crate::cached_value; use crate::cached_value;
use crate::handling::cached_value::CachedValue; use crate::handling::cached_value::CachedValue;
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
@ -84,7 +84,7 @@ mod implementation {
) )
}), }),
use_move: cached_value!({ 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( fn executing_move_get_chosen_move(
r: ExternRef<ExecutingMoveImpl>, r: ExternRef<ExecutingMoveImpl>,
) -> ExternRef<LearnedMoveImpl>; ) -> ExternRef<LearnedMoveImpl>;
fn executing_move_get_use_move(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<MoveData>; fn executing_move_get_use_move(r: ExternRef<ExecutingMoveImpl>) -> ExternRef<MoveDataImpl>;
#[allow(improper_ctypes)] #[allow(improper_ctypes)]
fn executing_move_get_script(r: ExternRef<ExecutingMoveImpl>) -> *const dyn Script; fn executing_move_get_script(r: ExternRef<ExecutingMoveImpl>) -> *const dyn Script;

View File

@ -23,6 +23,7 @@ pub type LearnedMove = Rc<dyn LearnedMoveTrait>;
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
mod implementation { mod implementation {
use super::*; use super::*;
use crate::app_interface::MoveDataImpl;
use crate::handling::cached_value::CachedValue; use crate::handling::cached_value::CachedValue;
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
use crate::handling::Cacheable; use crate::handling::Cacheable;
@ -54,7 +55,7 @@ mod implementation {
inner: Rc::new(LearnedMoveInner { inner: Rc::new(LearnedMoveInner {
reference, reference,
move_data: cached_value!({ 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) }), learn_method: cached_value!({ learned_move_get_learn_method(reference) }),
}), }),
@ -88,7 +89,7 @@ mod implementation {
} }
extern "wasm" { extern "wasm" {
fn learned_move_get_move_data(r: ExternRef<LearnedMoveImpl>) -> ExternRef<MoveData>; fn learned_move_get_move_data(r: ExternRef<LearnedMoveImpl>) -> ExternRef<MoveDataImpl>;
fn learned_move_get_learn_method(r: ExternRef<LearnedMoveImpl>) -> MoveLearnMethod; fn learned_move_get_learn_method(r: ExternRef<LearnedMoveImpl>) -> MoveLearnMethod;
fn learned_move_restore_uses(r: ExternRef<LearnedMoveImpl>, uses: u8); fn learned_move_restore_uses(r: ExternRef<LearnedMoveImpl>, uses: u8);
fn learned_move_restore_all_uses(r: ExternRef<LearnedMoveImpl>); fn learned_move_restore_all_uses(r: ExternRef<LearnedMoveImpl>);

View File

@ -18,8 +18,8 @@ pub trait PokemonTrait: WithVolatile {
fn form(&self) -> Form; fn form(&self) -> Form;
fn active_ability(&self) -> Ability; fn active_ability(&self) -> Ability;
fn nature(&self) -> Nature; fn nature(&self) -> Nature;
fn display_species(&self) -> Option<Species>; fn display_species(&self) -> Species;
fn display_form(&self) -> Option<Form>; fn display_form(&self) -> Form;
fn held_item(&self) -> Option<Item>; fn held_item(&self) -> Option<Item>;
fn battle(&self) -> Option<Battle>; fn battle(&self) -> Option<Battle>;
fn level(&self) -> LevelInt; fn level(&self) -> LevelInt;
@ -88,15 +88,15 @@ mod implementation {
use crate::app_interface::dynamic_data::dynamic_library::DynamicLibraryImpl; use crate::app_interface::dynamic_data::dynamic_library::DynamicLibraryImpl;
use crate::app_interface::{ 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::cached_value::CachedValue;
use crate::handling::Cacheable; use crate::handling::Cacheable;
use crate::implementation::ScriptPtr; 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_reference_getters_extern, wasm_value_getters_extern, wasm_value_getters_funcs,
wasm_reference_getters_funcs, wasm_value_getters_extern, wasm_value_getters_funcs,
ExternRef, ExternalReferenceType, ExternRef, ExternalReferenceType,
}; };
@ -235,12 +235,20 @@ mod implementation {
} }
fn change_species(&self, species: Species, form: Form) { fn change_species(&self, species: Species, form: Form) {
unsafe { unsafe {
pokemon_change_species(self.inner.reference, species.reference(), form.reference()); let species_impl = species.as_any().downcast_ref_unchecked::<SpeciesImpl>();
let form_impl = form.as_any().downcast_ref_unchecked::<FormImpl>();
pokemon_change_species(
self.inner.reference,
species_impl.reference(),
form_impl.reference(),
);
} }
} }
fn change_form(&self, form: Form) { fn change_form(&self, form: Form) {
unsafe { unsafe {
pokemon_change_form(self.inner.reference, form.reference()); let form_impl = form.as_any().downcast_ref_unchecked::<FormImpl>();
pokemon_change_form(self.inner.reference, form_impl.reference());
} }
} }
fn is_fainted(&self) -> bool { fn is_fainted(&self) -> bool {
@ -258,11 +266,27 @@ mod implementation {
} }
} }
wasm_reference_getters_funcs! { fn nature(&self) -> Nature {
Pokemon, unsafe {
fn species(&self) -> Species; Rc::new(
fn form(&self) -> Form; pokemon_get_nature(self.inner.reference)
fn nature(&self) -> Nature; .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) { fn clear_status(&self) {
@ -271,10 +295,23 @@ mod implementation {
} }
} }
wasm_optional_reference_getters_funcs! { fn display_species(&self) -> Species {
Pokemon, unsafe {
fn display_species(&self) -> Option<Species>; Rc::new(
fn display_form(&self) -> Option<Form>; 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 { fn battle_side(&self) -> BattleSide {
@ -391,16 +428,16 @@ mod implementation {
wasm_reference_getters_extern! { wasm_reference_getters_extern! {
PokemonImpl, Pokemon, PokemonImpl, Pokemon,
pub fn species(&self) -> Species; pub fn species(&self) -> SpeciesImpl;
pub fn form(&self) -> Form; pub fn form(&self) -> FormImpl;
pub fn active_ability(&self) -> AbilityImpl; pub fn active_ability(&self) -> AbilityImpl;
pub fn nature(&self) -> Nature; pub fn nature(&self) -> NatureImpl;
} }
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<SpeciesImpl>;
pub fn display_form(&self) -> Option<Form>; pub fn display_form(&self) -> Option<FormImpl>;
pub fn held_item(&self) -> Option<ItemImpl>; pub fn held_item(&self) -> Option<ItemImpl>;
pub fn battle(&self) -> Option<BattleImpl>; pub fn battle(&self) -> Option<BattleImpl>;
} }
@ -475,10 +512,10 @@ mod implementation {
fn pokemon_get_ability_script(r: ExternRef<PokemonImpl>) -> *const Box<dyn Script>; fn pokemon_get_ability_script(r: ExternRef<PokemonImpl>) -> *const Box<dyn Script>;
fn pokemon_change_species( fn pokemon_change_species(
r: ExternRef<PokemonImpl>, r: ExternRef<PokemonImpl>,
species: ExternRef<Species>, species: ExternRef<SpeciesImpl>,
form: ExternRef<Form>, form: ExternRef<FormImpl>,
); );
fn pokemon_change_form(r: ExternRef<PokemonImpl>, form: ExternRef<Form>); fn pokemon_change_form(r: ExternRef<PokemonImpl>, form: ExternRef<FormImpl>);
fn pokemon_damage(r: ExternRef<PokemonImpl>, damage: u32, source: DamageSource); fn pokemon_damage(r: ExternRef<PokemonImpl>, damage: u32, source: DamageSource);
fn pokemon_heal(r: ExternRef<PokemonImpl>, amount: u32, allow_revive: bool) -> bool; fn pokemon_heal(r: ExternRef<PokemonImpl>, amount: u32, allow_revive: bool) -> bool;
fn pokemon_set_weight(r: ExternRef<PokemonImpl>, weight: f32); fn pokemon_set_weight(r: ExternRef<PokemonImpl>, weight: f32);
@ -504,8 +541,8 @@ mockall::mock!(
fn form(&self) -> Form; fn form(&self) -> Form;
fn active_ability(&self) -> Ability; fn active_ability(&self) -> Ability;
fn nature(&self) -> Nature; fn nature(&self) -> Nature;
fn display_species(&self) -> Option<Species>; fn display_species(&self) -> Species;
fn display_form(&self) -> Option<Form>; fn display_form(&self) -> Form;
fn held_item(&self) -> Option<Item>; fn held_item(&self) -> Option<Item>;
fn battle(&self) -> Option<Battle>; fn battle(&self) -> Option<Battle>;
fn level(&self) -> LevelInt; fn level(&self) -> LevelInt;
@ -556,19 +593,19 @@ mockall::mock!(
#[cfg(feature = "mock_data")] #[cfg(feature = "mock_data")]
impl WithVolatile for MockPokemon { impl WithVolatile for MockPokemon {
fn has_volatile(&self, script_name: &str) -> bool { fn has_volatile(&self, _script_name: &str) -> bool {
unimplemented!() unimplemented!()
} }
fn add_volatile(&self, script: Box<dyn Script>) -> &dyn Script { fn add_volatile(&self, _script: Box<dyn Script>) -> &dyn Script {
unimplemented!() unimplemented!()
} }
fn add_volatile_by_name(&self, script_name: &str) -> &dyn Script { fn add_volatile_by_name(&self, _script_name: &str) -> &dyn Script {
unimplemented!() unimplemented!()
} }
fn remove_volatile<'a, 'b>(&'a self, script: &dyn Script) { fn remove_volatile(&self, _script: &dyn Script) {
unimplemented!() 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!() unimplemented!()
} }
} }

View File

@ -1,20 +1,28 @@
use crate::app_interface::{DataLibrary, ItemImpl}; use crate::app_interface::{DataLibrary, Item};
use crate::{ExternRef, ExternalReferenceType, StringKey};
use alloc::rc::Rc; use alloc::rc::Rc;
use spin::rwlock::RwLock;
pub trait ItemLibraryTrait: DataLibrary<Item> {}
pub type ItemLibrary = Rc<dyn ItemLibraryTrait>;
#[cfg(not(feature = "mock_data"))]
mod implementation {
use super::*;
use crate::app_interface::{ItemImpl, StringKey};
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
use spin::RwLock;
struct ItemLibraryInner { struct ItemLibraryInner {
ptr: ExternRef<ItemLibrary>, ptr: ExternRef<ItemLibraryImpl>,
cache: RwLock<hashbrown::HashMap<u32, ItemImpl>>, cache: RwLock<hashbrown::HashMap<u32, Item>>,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct ItemLibrary { pub struct ItemLibraryImpl {
inner: Rc<ItemLibraryInner>, inner: Rc<ItemLibraryInner>,
} }
impl ItemLibrary { impl ItemLibraryImpl {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(ptr: ExternRef<Self>) -> Self { pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
Self { Self {
inner: Rc::new(ItemLibraryInner { inner: Rc::new(ItemLibraryInner {
@ -25,8 +33,10 @@ impl ItemLibrary {
} }
} }
impl DataLibrary<ItemImpl> for ItemLibrary { impl ItemLibraryTrait for ItemLibraryImpl {}
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, ItemImpl>> {
impl DataLibrary<Item> for ItemLibraryImpl {
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, Item>> {
&self.inner.cache &self.inner.cache
} }
@ -34,44 +44,43 @@ impl DataLibrary<ItemImpl> for ItemLibrary {
self.inner.ptr self.inner.ptr
} }
#[cfg(not(feature = "mock_data"))] fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> u32 {
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<ItemImpl> { unsafe { item_library_get_item(ptr, name).get_internal_index() }
unsafe { item_library_get_item(ptr, name) }
} }
#[cfg(not(feature = "mock_data"))] fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> u32 {
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<ItemImpl> { unsafe { item_library_get_item_by_hash(ptr, hash).get_internal_index() }
unsafe { item_library_get_item_by_hash(ptr, hash) } }
fn _from_external_ref_index(index: u32) -> Option<Item> {
let v = ExternRef::<ItemImpl>::from(index).get_value();
if let Some(v) = v {
Some(Rc::new(v))
} else {
None
}
} }
} }
crate::handling::cacheable::cacheable!(ItemLibrary); crate::handling::cacheable::cacheable!(ItemLibraryImpl);
#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for ItemLibraryImpl {
impl ExternalReferenceType for ItemLibrary {
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 item_library_get_item( fn item_library_get_item(
ptr: ExternRef<ItemLibrary>, ptr: ExternRef<ItemLibraryImpl>,
name: ExternRef<StringKey>, name: ExternRef<StringKey>,
) -> ExternRef<ItemImpl>; ) -> ExternRef<ItemImpl>;
fn item_library_get_item_by_hash(ptr: ExternRef<ItemLibrary>, hash: u32) fn item_library_get_item_by_hash(
-> ExternRef<ItemImpl>; ptr: ExternRef<ItemLibraryImpl>,
hash: u32,
) -> ExternRef<ItemImpl>;
}
} }
#[cfg(feature = "mock_data")] #[cfg(not(feature = "mock_data"))]
impl ItemLibrary { pub use implementation::*;
pub fn mock() -> Self {
Self {
inner: Rc::new(ItemLibraryInner {
ptr: ExternRef::mock(),
cache: Default::default(),
}),
}
}
}

View File

@ -1,7 +1,7 @@
use crate::app_interface::item_library::ItemLibrary; use crate::app_interface::item_library::ItemLibrary;
use crate::app_interface::move_library::MoveLibrary; use crate::app_interface::move_library::MoveLibrary;
use crate::app_interface::species_library::SpeciesLibrary; 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 crate::app_interface::LevelInt;
use alloc::rc::Rc; use alloc::rc::Rc;
@ -14,7 +14,7 @@ pub trait StaticDataTrait {
fn move_library(&self) -> MoveLibrary; fn move_library(&self) -> MoveLibrary;
fn item_library(&self) -> ItemLibrary; fn item_library(&self) -> ItemLibrary;
fn species_library(&self) -> SpeciesLibrary; fn species_library(&self) -> SpeciesLibrary;
fn type_library(&self) -> TypeLibrary; fn type_library(&self) -> Typelibrary;
} }
pub type StaticData = Rc<dyn StaticDataTrait>; pub type StaticData = Rc<dyn StaticDataTrait>;
@ -28,6 +28,10 @@ pub type LibrarySettings = Rc<dyn LibrarySettingsTrait>;
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
mod implementation { mod implementation {
use super::*; 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::app_interface::{get_hash, StringKey};
use crate::handling::cached_value::CachedValue; use crate::handling::cached_value::CachedValue;
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType}; use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
@ -40,7 +44,7 @@ mod implementation {
move_library: CachedValue<MoveLibrary>, move_library: CachedValue<MoveLibrary>,
item_library: CachedValue<ItemLibrary>, item_library: CachedValue<ItemLibrary>,
species_library: CachedValue<SpeciesLibrary>, species_library: CachedValue<SpeciesLibrary>,
type_library: CachedValue<TypeLibrary>, type_library: CachedValue<Typelibrary>,
settings: CachedValue<LibrarySettings>, settings: CachedValue<LibrarySettings>,
} }
@ -56,18 +60,20 @@ mod implementation {
inner: Rc::new(StaticDataInner { inner: Rc::new(StaticDataInner {
reference, reference,
move_library: cached_value!({ 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!({ 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!({ species_library: cached_value!({
Rc::new(
static_data_get_species_library(reference) static_data_get_species_library(reference)
.get_value() .get_value()
.unwrap() .unwrap(),
)
}), }),
type_library: cached_value!({ 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!({ settings: cached_value!({
Rc::new( Rc::new(
@ -86,7 +92,7 @@ mod implementation {
fn move_library(&self) -> MoveLibrary; fn move_library(&self) -> MoveLibrary;
fn item_library(&self) -> ItemLibrary; fn item_library(&self) -> ItemLibrary;
fn species_library(&self) -> SpeciesLibrary; 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"))] #[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn static_data_get_move_library(ptr: ExternRef<StaticDataImpl>) -> ExternRef<MoveLibrary>; fn static_data_get_move_library(
fn static_data_get_item_library(ptr: ExternRef<StaticDataImpl>) -> ExternRef<ItemLibrary>; ptr: ExternRef<StaticDataImpl>,
) -> ExternRef<MoveLibraryImpl>;
fn static_data_get_item_library(
ptr: ExternRef<StaticDataImpl>,
) -> ExternRef<ItemLibraryImpl>;
fn static_data_get_species_library( fn static_data_get_species_library(
ptr: ExternRef<StaticDataImpl>, ptr: ExternRef<StaticDataImpl>,
) -> ExternRef<SpeciesLibrary>; ) -> ExternRef<SpeciesLibraryImpl>;
fn static_data_get_type_library(ptr: ExternRef<StaticDataImpl>) -> ExternRef<TypeLibrary>; fn static_data_get_type_library(
ptr: ExternRef<StaticDataImpl>,
) -> ExternRef<TypeLibraryImpl>;
fn static_data_get_library_settings( fn static_data_get_library_settings(
ptr: ExternRef<StaticDataImpl>, ptr: ExternRef<StaticDataImpl>,
) -> ExternRef<LibrarySettingsImpl>; ) -> ExternRef<LibrarySettingsImpl>;
@ -149,17 +161,20 @@ mod implementation {
pub trait DataLibrary<T>: Cacheable pub trait DataLibrary<T>: Cacheable
where where
T: ExternalReferenceType,
T: Clone, T: Clone,
{ {
fn get_cache(&self) -> &RwLock<hashbrown::HashMap<u32, T>>; fn get_cache(&self) -> &RwLock<hashbrown::HashMap<u32, T>>;
fn get_self_ref(&self) -> ExternRef<Self> fn get_self_ref(&self) -> ExternRef<Self>
where where
Self: Sized; Self: Sized;
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<T> fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> u32
where where
Self: Sized; Self: Sized;
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<T> fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> u32
where
Self: Sized;
fn _from_external_ref_index(index: u32) -> Option<T>
where where
Self: Sized; Self: Sized;
@ -171,7 +186,8 @@ mod implementation {
return Some(v.clone()); 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 { if let Some(v) = &v {
self.get_cache().write().insert(name.hash(), v.clone()); self.get_cache().write().insert(name.hash(), v.clone());
} }
@ -193,7 +209,8 @@ mod implementation {
return Some(v.clone()); 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 { if let Some(v) = &v {
self.get_cache().write().insert(hash, v.clone()); self.get_cache().write().insert(hash, v.clone());
} }
@ -207,16 +224,12 @@ pub use implementation::*;
#[cfg(feature = "mock_data")] #[cfg(feature = "mock_data")]
mod mocked { mod mocked {
use super::*;
use crate::app_interface::StringKey; use crate::app_interface::StringKey;
use crate::handling::cached_value::CachedValue; use crate::handling::extern_ref::ExternRef;
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
use crate::handling::Cacheable;
use crate::{cached_value, cached_value_getters};
use spin::RwLock; use spin::RwLock;
#[cfg(feature = "mock_data")] #[cfg(feature = "mock_data")]
pub trait DataLibrary<T>: Cacheable pub trait DataLibrary<T>
where where
T: Clone, T: Clone,
{ {

View File

@ -1,20 +1,28 @@
use crate::app_interface::data_libraries::DataLibrary; use crate::app_interface::{DataLibrary, MoveData};
use crate::app_interface::{MoveData, StringKey};
use crate::{ExternRef, ExternalReferenceType};
use alloc::rc::Rc; use alloc::rc::Rc;
pub trait MoveLibraryTrait: DataLibrary<MoveData> {}
pub type MoveLibrary = Rc<dyn MoveLibraryTrait>;
#[cfg(not(feature = "mock_data"))]
mod implementation {
use super::*;
use crate::app_interface::{MoveDataImpl, StringKey};
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
use spin::RwLock; use spin::RwLock;
struct MoveLibraryInner { struct MoveLibraryInner {
ptr: ExternRef<MoveLibrary>, ptr: ExternRef<MoveLibraryImpl>,
cache: RwLock<hashbrown::HashMap<u32, MoveData>>, cache: RwLock<hashbrown::HashMap<u32, MoveData>>,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct MoveLibrary { pub struct MoveLibraryImpl {
inner: Rc<MoveLibraryInner>, inner: Rc<MoveLibraryInner>,
} }
impl MoveLibrary { impl MoveLibraryImpl {
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
pub(crate) fn new(ptr: ExternRef<Self>) -> Self { pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
Self { Self {
@ -36,7 +44,9 @@ impl MoveLibrary {
} }
} }
impl DataLibrary<MoveData> for MoveLibrary { impl MoveLibraryTrait for MoveLibraryImpl {}
impl DataLibrary<MoveData> for MoveLibraryImpl {
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, MoveData>> { fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, MoveData>> {
&self.inner.cache &self.inner.cache
} }
@ -46,20 +56,29 @@ impl DataLibrary<MoveData> for MoveLibrary {
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<MoveData> { fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> u32 {
unsafe { move_library_get_move(ptr, name) } unsafe { move_library_get_move(ptr, name).get_internal_index() }
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<MoveData> { fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> u32 {
unsafe { move_library_get_move_by_hash(ptr, hash) } unsafe { move_library_get_move_by_hash(ptr, hash).get_internal_index() }
}
fn _from_external_ref_index(index: u32) -> Option<MoveData> {
let v = ExternRef::<MoveDataImpl>::from(index).get_value();
if let Some(v) = v {
Some(Rc::new(v))
} else {
None
}
} }
} }
crate::handling::cacheable::cacheable!(MoveLibrary); crate::handling::cacheable::cacheable!(MoveLibraryImpl);
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for MoveLibrary { impl ExternalReferenceType for MoveLibraryImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self { fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference) Self::new(reference)
} }
@ -68,9 +87,15 @@ impl ExternalReferenceType for MoveLibrary {
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn move_library_get_move( fn move_library_get_move(
ptr: ExternRef<MoveLibrary>, ptr: ExternRef<MoveLibraryImpl>,
name: ExternRef<StringKey>, name: ExternRef<StringKey>,
) -> ExternRef<MoveData>; ) -> ExternRef<MoveDataImpl>;
fn move_library_get_move_by_hash(ptr: ExternRef<MoveLibrary>, hash: u32) fn move_library_get_move_by_hash(
-> ExternRef<MoveData>; ptr: ExternRef<MoveLibraryImpl>,
hash: u32,
) -> ExternRef<MoveDataImpl>;
} }
}
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;

View File

@ -1,21 +1,30 @@
use crate::app_interface::{DataLibrary, Species}; use crate::app_interface::{DataLibrary, Species};
use crate::{ExternRef, ExternalReferenceType, StringKey}; use alloc::rc::Rc;
pub trait SpeciesLibraryTrait: DataLibrary<Species> {}
pub type SpeciesLibrary = Rc<dyn SpeciesLibraryTrait>;
#[cfg(not(feature = "mock_data"))]
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 alloc::rc::Rc;
use spin::RwLock; use spin::RwLock;
struct SpeciesLibraryInner { struct SpeciesLibraryInner {
ptr: ExternRef<SpeciesLibrary>, ptr: ExternRef<SpeciesLibraryImpl>,
cache: RwLock<hashbrown::HashMap<u32, Species>>, cache: RwLock<hashbrown::HashMap<u32, Species>>,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct SpeciesLibrary { pub struct SpeciesLibraryImpl {
inner: Rc<SpeciesLibraryInner>, inner: Rc<SpeciesLibraryInner>,
} }
impl SpeciesLibrary { impl SpeciesLibraryImpl {
#[cfg(not(feature = "mock_data"))] pub fn new(ptr: ExternRef<SpeciesLibraryImpl>) -> Self {
pub fn new(ptr: ExternRef<SpeciesLibrary>) -> Self {
Self { Self {
inner: Rc::new(SpeciesLibraryInner { inner: Rc::new(SpeciesLibraryInner {
ptr, ptr,
@ -23,19 +32,11 @@ impl SpeciesLibrary {
}), }),
} }
} }
#[cfg(feature = "mock_data")]
pub fn mock() -> Self {
Self {
inner: Rc::new(SpeciesLibraryInner {
ptr: ExternRef::mock(),
cache: Default::default(),
}),
}
}
} }
impl DataLibrary<Species> for SpeciesLibrary { impl SpeciesLibraryTrait for SpeciesLibraryImpl {}
impl DataLibrary<Species> for SpeciesLibraryImpl {
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, Species>> { fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, Species>> {
&self.inner.cache &self.inner.cache
} }
@ -45,33 +46,43 @@ impl DataLibrary<Species> for SpeciesLibrary {
} }
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<Species> { fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> u32 {
unsafe { species_library_get_species(ptr, name) } unsafe { species_library_get_species(ptr, name).get_internal_index() }
} }
#[cfg(not(feature = "mock_data"))] fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> u32 {
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<Species> { unsafe { species_library_get_species_by_hash(ptr, hash).get_internal_index() }
unsafe { species_library_get_species_by_hash(ptr, hash) } }
fn _from_external_ref_index(index: u32) -> Option<Species> {
let v = ExternRef::<SpeciesImpl>::from(index).get_value();
if let Some(v) = v {
Some(Rc::new(v))
} else {
None
}
} }
} }
crate::handling::cacheable::cacheable!(SpeciesLibrary); crate::handling::cacheable::cacheable!(SpeciesLibraryImpl);
#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for SpeciesLibraryImpl {
impl ExternalReferenceType for SpeciesLibrary {
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 species_library_get_species( fn species_library_get_species(
ptr: ExternRef<SpeciesLibrary>, ptr: ExternRef<SpeciesLibraryImpl>,
name: ExternRef<StringKey>, name: ExternRef<StringKey>,
) -> ExternRef<Species>; ) -> ExternRef<SpeciesImpl>;
fn species_library_get_species_by_hash( fn species_library_get_species_by_hash(
ptr: ExternRef<SpeciesLibrary>, ptr: ExternRef<SpeciesLibraryImpl>,
hash: u32, hash: u32,
) -> ExternRef<Species>; ) -> ExternRef<SpeciesImpl>;
} }
}
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;

View File

@ -1,22 +1,43 @@
use crate::app_interface::TypeIdentifier; use crate::app_interface::TypeIdentifier;
use crate::{ExternRef, ExternalReferenceType}; use alloc::rc::Rc;
pub trait TypeLibraryTrait {
fn get_type_from_name(&self, name: &str) -> Option<TypeIdentifier>;
fn get_single_effectiveness(
&self,
attacking_type: TypeIdentifier,
defending_type: TypeIdentifier,
) -> f32;
fn get_effectiveness(
&self,
attacking_type: TypeIdentifier,
defending_types: &[TypeIdentifier],
) -> f32;
}
pub type Typelibrary = Rc<dyn TypeLibraryTrait>;
#[cfg(not(feature = "mock_data"))]
mod implementation {
use super::*;
use crate::handling::extern_ref::{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};
use spin::RwLock; use spin::RwLock;
struct TypeLibraryInner { struct TypeLibraryInner {
reference: ExternRef<TypeLibrary>, reference: ExternRef<TypeLibraryImpl>,
name_to_type_cache: RwLock<hashbrown::HashMap<String, TypeIdentifier>>, name_to_type_cache: RwLock<hashbrown::HashMap<String, TypeIdentifier>>,
effectiveness_cache: RwLock<hashbrown::HashMap<(TypeIdentifier, TypeIdentifier), f32>>, effectiveness_cache: RwLock<hashbrown::HashMap<(TypeIdentifier, TypeIdentifier), f32>>,
} }
#[derive(Clone)] #[derive(Clone)]
pub struct TypeLibrary { pub struct TypeLibraryImpl {
inner: Rc<TypeLibraryInner>, inner: Rc<TypeLibraryInner>,
} }
impl TypeLibrary { impl TypeLibraryImpl {
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
pub(crate) fn new(reference: ExternRef<Self>) -> Self { pub(crate) fn new(reference: ExternRef<Self>) -> Self {
Self { Self {
@ -27,19 +48,10 @@ impl TypeLibrary {
}), }),
} }
} }
#[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"))] impl TypeLibraryTrait for TypeLibraryImpl {
pub fn get_type_from_name(&self, name: &str) -> Option<TypeIdentifier> { fn get_type_from_name(&self, name: &str) -> Option<TypeIdentifier> {
if let Some(cached) = self.inner.name_to_type_cache.read().get(name) { if let Some(cached) = self.inner.name_to_type_cache.read().get(name) {
return Some(*cached); return Some(*cached);
} }
@ -56,8 +68,7 @@ impl TypeLibrary {
Some(v) Some(v)
} }
#[cfg(not(feature = "mock_data"))] fn get_single_effectiveness(
pub fn get_single_effectiveness(
&self, &self,
attacking_type: TypeIdentifier, attacking_type: TypeIdentifier,
defending_type: TypeIdentifier, defending_type: TypeIdentifier,
@ -84,8 +95,7 @@ impl TypeLibrary {
effectiveness effectiveness
} }
#[cfg(not(feature = "mock_data"))] fn get_effectiveness(
pub fn get_effectiveness(
&self, &self,
attacking_type: TypeIdentifier, attacking_type: TypeIdentifier,
defending_types: &[TypeIdentifier], defending_types: &[TypeIdentifier],
@ -98,10 +108,10 @@ impl TypeLibrary {
} }
} }
crate::handling::cacheable::cacheable!(TypeLibrary); crate::handling::cacheable::cacheable!(TypeLibraryImpl);
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for TypeLibrary { impl ExternalReferenceType for TypeLibraryImpl {
fn from_extern_value(reference: ExternRef<Self>) -> Self { fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference) Self::new(reference)
} }
@ -110,9 +120,13 @@ impl ExternalReferenceType for TypeLibrary {
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn type_library_get_single_effectiveness( fn type_library_get_single_effectiveness(
r: ExternRef<TypeLibrary>, r: ExternRef<TypeLibraryImpl>,
attacking_type: u8, attacking_type: u8,
defending_type: u8, defending_type: u8,
) -> f32; ) -> f32;
fn type_library_get_type_by_name(r: ExternRef<TypeLibrary>, name: *const c_char) -> u8; fn type_library_get_type_by_name(r: ExternRef<TypeLibraryImpl>, name: *const c_char) -> u8;
} }
}
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;

View File

@ -1,4 +1,5 @@
use crate::app_interface::StringKey; use crate::app_interface::StringKey;
#[cfg(not(feature = "mock_data"))]
use crate::{ExternRef, ExternalReferenceType}; use crate::{ExternRef, ExternalReferenceType};
use core::fmt::{Display, Formatter}; use core::fmt::{Display, Formatter};
@ -40,28 +41,28 @@ impl EffectParameter {
if let EffectParameter::Bool(b) = self { if let EffectParameter::Bool(b) = self {
return *b; return *b;
} }
panic!("Unexpected effect parameter type: {}", self); panic!("Unexpected effect parameter type: {self}");
} }
pub fn as_int(&self) -> i64 { pub fn as_int(&self) -> i64 {
if let EffectParameter::Int(i) = self { if let EffectParameter::Int(i) = self {
return *i; return *i;
} }
panic!("Unexpected effect parameter type: {}", self); panic!("Unexpected effect parameter type: {self}");
} }
pub fn as_float(&self) -> f32 { pub fn as_float(&self) -> f32 {
if let EffectParameter::Float(f) = self { if let EffectParameter::Float(f) = self {
return *f; return *f;
} }
panic!("Unexpected effect parameter type: {}", self); panic!("Unexpected effect parameter type: {self}");
} }
pub fn as_string(&self) -> StringKey { pub fn as_string(&self) -> StringKey {
if let EffectParameter::String(s) = self { if let EffectParameter::String(s) = self {
return s.clone(); 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 { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self { match self {
EffectParameter::None => f.write_str("EffectParameter::None"), EffectParameter::None => f.write_str("EffectParameter::None"),
EffectParameter::Bool(b) => f.write_fmt(format_args!("EffectParameter::Bool({})", b)), EffectParameter::Bool(b) => f.write_fmt(format_args!("EffectParameter::Bool({b})")),
EffectParameter::Int(i) => f.write_fmt(format_args!("EffectParameter::Int({})", i)), EffectParameter::Int(i) => f.write_fmt(format_args!("EffectParameter::Int({i})")),
EffectParameter::Float(r) => f.write_fmt(format_args!("EffectParameter::Float({})", r)), EffectParameter::Float(r) => f.write_fmt(format_args!("EffectParameter::Float({r})")),
EffectParameter::String(s) => { EffectParameter::String(s) => {
f.write_fmt(format_args!("EffectParameter::String(\"{}\")", s)) f.write_fmt(format_args!("EffectParameter::String(\"{s}\")"))
} }
} }
} }

View File

@ -1,6 +1,4 @@
use crate::handling::cached_value::CachedValue; use crate::app_interface::StringKey;
use crate::handling::Cacheable;
use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType, StringKey};
use alloc::rc::Rc; use alloc::rc::Rc;
/// An item category defines which bag slot items are stored in. /// An item category defines which bag slot items are stored in.
@ -59,6 +57,15 @@ pub type Item = Rc<dyn ItemTrait>;
#[cfg(feature = "mock_data")] #[cfg(feature = "mock_data")]
pub type MockItem = MockItemTrait; pub type MockItem = MockItemTrait;
#[cfg(not(feature = "mock_data"))]
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 { struct ItemInner {
reference: ExternRef<ItemImpl>, reference: ExternRef<ItemImpl>,
name: CachedValue<StringKey>, name: CachedValue<StringKey>,
@ -123,7 +130,6 @@ impl ExternalReferenceType for ItemImpl {
} }
} }
#[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn item_get_name(ptr: ExternRef<ItemImpl>) -> ExternRef<StringKey>; fn item_get_name(ptr: ExternRef<ItemImpl>) -> ExternRef<StringKey>;
fn item_get_category(ptr: ExternRef<ItemImpl>) -> ItemCategory; fn item_get_category(ptr: ExternRef<ItemImpl>) -> ItemCategory;
@ -131,3 +137,7 @@ extern "wasm" {
fn item_get_price(ptr: ExternRef<ItemImpl>) -> i32; fn item_get_price(ptr: ExternRef<ItemImpl>) -> i32;
fn item_has_flag(ptr: ExternRef<ItemImpl>, flag: ExternRef<StringKey>) -> bool; fn item_has_flag(ptr: ExternRef<ItemImpl>, flag: ExternRef<StringKey>) -> bool;
} }
}
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;

View File

@ -5,14 +5,16 @@ pub mod item;
pub mod move_data; pub mod move_data;
mod nature; mod nature;
pub mod species; pub mod species;
pub mod statistics;
pub use ability::*; pub use ability::*;
pub use data_libraries::*; pub use data_libraries::*;
pub use effect_parameter::EffectParameter; pub use effect_parameter::*;
pub use item::*; pub use item::*;
pub use move_data::*; pub use move_data::*;
pub use nature::*; pub use nature::*;
pub use species::*; pub use species::*;
pub use statistics::*;
pub type LevelInt = u8; pub type LevelInt = u8;

View File

@ -1,7 +1,4 @@
use crate::app_interface::{get_hash, StringKey}; use crate::app_interface::StringKey;
use crate::handling::cached_value::CachedValue;
use crate::handling::Cacheable;
use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType};
use alloc::rc::Rc; use alloc::rc::Rc;
#[repr(u8)] #[repr(u8)]
@ -32,8 +29,31 @@ pub enum MoveTarget {
OnSelf, OnSelf,
} }
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;
}
pub type MoveData = Rc<dyn MoveDataTrait>;
#[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 { struct MoveDataInner {
ptr: ExternRef<MoveData>, ptr: ExternRef<MoveDataImpl>,
name: CachedValue<StringKey>, name: CachedValue<StringKey>,
move_type: CachedValue<u8>, move_type: CachedValue<u8>,
category: CachedValue<MoveCategory>, category: CachedValue<MoveCategory>,
@ -45,14 +65,13 @@ struct MoveDataInner {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct MoveData { pub struct MoveDataImpl {
inner: Rc<MoveDataInner>, inner: Rc<MoveDataInner>,
} }
impl MoveData { impl MoveDataImpl {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(ptr: ExternRef<Self>) -> Self { pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
MoveData::from_ref(ptr, &|ptr| Self { MoveDataImpl::from_ref(ptr, &|ptr| Self {
inner: Rc::new(MoveDataInner { inner: Rc::new(MoveDataInner {
ptr, ptr,
name: cached_value!({ StringKey::new(move_data_get_name(ptr)) }), name: cached_value!({ StringKey::new(move_data_get_name(ptr)) }),
@ -66,68 +85,46 @@ impl MoveData {
}), }),
}) })
} }
#[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(),
}),
}
} }
impl MoveDataTrait for MoveDataImpl {
cached_value_getters! { cached_value_getters! {
pub fn name(&self) -> StringKey; fn name(&self) -> StringKey;
pub fn move_type(&self) -> u8; fn move_type(&self) -> u8;
pub fn category(&self) -> MoveCategory; fn category(&self) -> MoveCategory;
pub fn base_power(&self) -> u8; fn base_power(&self) -> u8;
pub fn accuracy(&self) -> u8; fn accuracy(&self) -> u8;
pub fn base_usages(&self) -> u8; fn base_usages(&self) -> u8;
pub fn target(&self) -> MoveTarget; fn target(&self) -> MoveTarget;
pub fn priority(&self) -> i8; fn priority(&self) -> i8;
} }
#[cfg(not(feature = "mock_data"))] fn has_flag(&self, flag: &str) -> bool {
pub fn has_flag(&self, flag: &str) -> bool {
let hash = get_hash(flag); let hash = get_hash(flag);
unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash) } unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash) }
} }
} }
#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for MoveDataImpl {
impl ExternalReferenceType for MoveData {
fn from_extern_value(reference: ExternRef<Self>) -> Self { fn from_extern_value(reference: ExternRef<Self>) -> Self {
MoveData::new(reference) MoveDataImpl::new(reference)
} }
} }
crate::handling::cacheable::cacheable!(MoveData); crate::handling::cacheable::cacheable!(MoveDataImpl);
extern "wasm" {
fn move_data_get_name(ptr: ExternRef<MoveDataImpl>) -> ExternRef<StringKey>;
fn move_data_get_type(ptr: ExternRef<MoveDataImpl>) -> u8;
fn move_data_get_category(ptr: ExternRef<MoveDataImpl>) -> MoveCategory;
fn move_data_get_base_power(ptr: ExternRef<MoveDataImpl>) -> u8;
fn move_data_get_accuracy(ptr: ExternRef<MoveDataImpl>) -> u8;
fn move_data_get_base_usages(ptr: ExternRef<MoveDataImpl>) -> u8;
fn move_data_get_target(ptr: ExternRef<MoveDataImpl>) -> MoveTarget;
fn move_data_get_priority(ptr: ExternRef<MoveDataImpl>) -> i8;
fn move_data_has_flag_by_hash(ptr: ExternRef<MoveDataImpl>, flag_hash: u32) -> bool;
}
}
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
extern "wasm" { pub use implementation::*;
fn move_data_get_name(ptr: ExternRef<MoveData>) -> ExternRef<StringKey>;
fn move_data_get_type(ptr: ExternRef<MoveData>) -> u8;
fn move_data_get_category(ptr: ExternRef<MoveData>) -> MoveCategory;
fn move_data_get_base_power(ptr: ExternRef<MoveData>) -> u8;
fn move_data_get_accuracy(ptr: ExternRef<MoveData>) -> u8;
fn move_data_get_base_usages(ptr: ExternRef<MoveData>) -> u8;
fn move_data_get_target(ptr: ExternRef<MoveData>) -> MoveTarget;
fn move_data_get_priority(ptr: ExternRef<MoveData>) -> i8;
fn move_data_has_flag_by_hash(ptr: ExternRef<MoveData>, flag_hash: u32) -> bool;
}

View File

@ -1,10 +1,23 @@
use crate::app_interface::Statistic; use crate::app_interface::Statistic;
use crate::handling::cacheable::Cacheable;
use crate::{ExternRef, ExternalReferenceType};
use alloc::rc::Rc; use alloc::rc::Rc;
pub trait NatureTrait {
fn increase_stat(&self) -> Statistic;
fn decrease_stat(&self) -> Statistic;
fn increase_modifier(&self) -> f32;
fn decrease_modifier(&self) -> f32;
}
pub type Nature = Rc<dyn NatureTrait>;
#[cfg(not(feature = "mock_data"))]
mod implementation {
use super::*;
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
use crate::handling::Cacheable;
struct NatureInner { struct NatureInner {
reference: ExternRef<Nature>, reference: ExternRef<NatureImpl>,
/// The stat that should receive the increased modifier. /// The stat that should receive the increased modifier.
increase_stat: Statistic, increase_stat: Statistic,
/// The stat that should receive the decreased modifier. /// The stat that should receive the decreased modifier.
@ -16,14 +29,13 @@ struct NatureInner {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct Nature { pub struct NatureImpl {
inner: Rc<NatureInner>, inner: Rc<NatureInner>,
} }
crate::handling::cacheable::cacheable!(Nature); crate::handling::cacheable::cacheable!(NatureImpl);
impl Nature { impl NatureImpl {
#[cfg(not(feature = "mock_data"))]
pub fn new(reference: ExternRef<Self>) -> Self { pub fn new(reference: ExternRef<Self>) -> Self {
Self::from_ref(reference, &|reference| unsafe { Self::from_ref(reference, &|reference| unsafe {
Self { Self {
@ -39,17 +51,37 @@ impl Nature {
} }
} }
#[cfg(not(feature = "mock_data"))] impl NatureTrait for NatureImpl {
impl ExternalReferenceType for Nature { 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 { fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference) Self::new(reference)
} }
} }
#[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn nature_get_increase_stat(r: ExternRef<Nature>) -> Statistic; fn nature_get_increase_stat(r: ExternRef<NatureImpl>) -> Statistic;
fn nature_get_decrease_stat(r: ExternRef<Nature>) -> Statistic; fn nature_get_decrease_stat(r: ExternRef<NatureImpl>) -> Statistic;
fn nature_get_increase_modifier(r: ExternRef<Nature>) -> f32; fn nature_get_increase_modifier(r: ExternRef<NatureImpl>) -> f32;
fn nature_get_decrease_modifier(r: ExternRef<Nature>) -> f32; fn nature_get_decrease_modifier(r: ExternRef<NatureImpl>) -> f32;
} }
}
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;

View File

@ -1,16 +1,8 @@
use crate::app_interface::get_hash;
use crate::app_interface::list::ImmutableList; use crate::app_interface::list::ImmutableList;
#[cfg(not(feature = "mock_data"))] use crate::app_interface::{ImmutableStatisticSet, StringKey};
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 alloc::rc::Rc; use alloc::rc::Rc;
use alloc::vec::Vec; use alloc::vec::Vec;
use spin::RwLock; use core::any::Any;
#[repr(u8)] #[repr(u8)]
#[derive(Eq, PartialEq, Debug)] #[derive(Eq, PartialEq, Debug)]
@ -20,80 +12,55 @@ pub enum Gender {
Genderless = 2, Genderless = 2,
} }
#[repr(u8)] pub trait FormTrait {
#[derive(Eq, PartialEq, Debug)] fn name(&self) -> StringKey;
pub enum Statistic { fn height(&self) -> f32;
HP = 0, fn weight(&self) -> f32;
Attack = 1, fn base_experience(&self) -> u32;
Defense = 2, fn base_stats(&self) -> ImmutableStatisticSet;
SpecialAttack = 3, fn abilities(&self) -> ImmutableList<Rc<StringKey>>;
SpecialDefense = 4, fn hidden_abilities(&self) -> ImmutableList<Rc<StringKey>>;
Speed = 5, fn types(&self) -> &Vec<u8>;
fn has_flag(&self, flag: &str) -> bool;
fn as_any(&self) -> &dyn Any;
} }
pub struct ImmutableStatisticSetInner { pub trait SpeciesTrait {
reference: ExternRef<ImmutableStatisticSet>, /// The national dex identifier of the Pokemon.
/// The health point stat value. fn id(&self) -> u16;
hp: CachedValue<u16>, /// The name of the Pokemon species.
/// The physical attack stat value. fn name(&self) -> StringKey;
attack: CachedValue<u16>, /// The chance between 0.0 and 1.0 that a Pokemon is female.
/// The physical defense stat value. fn gender_rate(&self) -> f32;
defense: CachedValue<u16>, /// How much experience is required for a level.
/// The special attack stat value. fn growth_rate(&self) -> StringKey;
special_attack: CachedValue<u16>, /// How hard it is to capture a Pokemon. 255 means this will be always caught, 0 means this is
/// The special defense stat value. /// uncatchable.
special_defense: CachedValue<u16>, fn capture_rate(&self) -> u8;
/// The speed stat value. fn get_form(&self, form_name: &str) -> Option<Form>;
speed: CachedValue<u16>, fn has_flag(&self, flag: &str) -> bool;
fn as_any(&self) -> &dyn Any;
} }
#[derive(Clone)] pub type Form = Rc<dyn FormTrait>;
pub struct ImmutableStatisticSet { pub type Species = Rc<dyn SpeciesTrait>;
inner: Rc<ImmutableStatisticSetInner>,
}
impl ImmutableStatisticSet {
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
pub(crate) fn new(reference: ExternRef<Self>) -> Self { mod implementation {
Self::from_ref(reference, &|reference| Self { use super::*;
inner: Rc::new(ImmutableStatisticSetInner { use crate::app_interface::list::ImmutableListWasm;
reference, use crate::app_interface::{get_hash, ImmutableStatisticSetImpl};
hp: cached_value!({ static_statistics_set_get_hp(reference) }), use crate::handling::cached_value::CachedValue;
attack: cached_value!({ static_statistics_set_get_attack(reference) }), use crate::handling::extern_ref::{ExternRef, ExternalReferenceType, VecExternRef};
defense: cached_value!({ static_statistics_set_get_defense(reference) }), use crate::handling::ffi_array::FFIArray;
special_attack: cached_value!({ use crate::handling::Cacheable;
static_statistics_set_get_special_attack(reference) use crate::{cached_value, cached_value_getters};
}), use spin::RwLock;
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 { struct FormInner {
reference: ExternRef<Form>, reference: ExternRef<FormImpl>,
name: CachedValue<StringKey>, name: CachedValue<StringKey>,
height: CachedValue<f32>, height: CachedValue<f32>,
weight: CachedValue<f32>, weight: CachedValue<f32>,
@ -106,12 +73,11 @@ struct FormInner {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct Form { pub struct FormImpl {
inner: Rc<FormInner>, inner: Rc<FormInner>,
} }
impl Form { impl FormImpl {
#[cfg(not(feature = "mock_data"))]
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 {
inner: Rc::new(FormInner { inner: Rc::new(FormInner {
@ -124,7 +90,9 @@ impl Form {
Vec::from_raw_parts(raw.ptr(), raw.len(), raw.len()) Vec::from_raw_parts(raw.ptr(), raw.len(), raw.len())
}), }),
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!({
Rc::new(form_get_base_stats(reference).get_value().unwrap())
}),
abilities: cached_value!({ abilities: cached_value!({
Rc::new( Rc::new(
crate::app_interface::list::StringKeyImmutableList::from_ref( crate::app_interface::list::StringKeyImmutableList::from_ref(
@ -146,29 +114,34 @@ impl Form {
pub(crate) fn reference(&self) -> ExternRef<Self> { pub(crate) fn reference(&self) -> ExternRef<Self> {
self.inner.reference 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<Rc<StringKey>>;
pub fn hidden_abilities(&self) -> ImmutableList<Rc<StringKey>>;
} }
pub fn types(&self) -> &Vec<u8> {
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<Rc<StringKey>>;
fn hidden_abilities(&self) -> ImmutableList<Rc<StringKey>>;
}
fn types(&self) -> &Vec<u8> {
self.inner.types.value_ref() self.inner.types.value_ref()
} }
#[cfg(not(feature = "mock_data"))] fn has_flag(&self, flag: &str) -> bool {
pub fn has_flag(&self, flag: &str) -> bool {
let hash = get_hash(flag); let hash = get_hash(flag);
unsafe { form_has_flag_by_hash(self.inner.reference, hash) } unsafe { form_has_flag_by_hash(self.inner.reference, hash) }
} }
fn as_any(&self) -> &dyn Any {
self
}
} }
pub struct SpeciesInner { pub struct SpeciesInner {
reference: ExternRef<Species>, reference: ExternRef<SpeciesImpl>,
id: CachedValue<u16>, id: CachedValue<u16>,
name: CachedValue<StringKey>, name: CachedValue<StringKey>,
gender_rate: CachedValue<f32>, gender_rate: CachedValue<f32>,
@ -178,13 +151,12 @@ pub struct SpeciesInner {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct Species { pub struct SpeciesImpl {
inner: Rc<SpeciesInner>, inner: Rc<SpeciesInner>,
} }
impl Species { impl SpeciesImpl {
#[cfg(not(feature = "mock_data"))] pub(crate) fn new(reference: ExternRef<SpeciesImpl>) -> Self {
pub(crate) fn new(reference: ExternRef<Species>) -> Self {
Self { Self {
inner: Rc::new(SpeciesInner { inner: Rc::new(SpeciesInner {
reference, reference,
@ -203,23 +175,24 @@ impl Species {
pub(crate) fn reference(&self) -> ExternRef<Self> { pub(crate) fn reference(&self) -> ExternRef<Self> {
self.inner.reference self.inner.reference
} }
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;
} }
#[cfg(not(feature = "mock_data"))] impl SpeciesTrait for SpeciesImpl {
pub fn get_form(&self, form_name: &str) -> Option<Form> { 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<Form> {
let hash = get_hash(form_name); let hash = get_hash(form_name);
unsafe { unsafe {
if let Some(v) = self.inner.forms.read().get(&hash) { if let Some(v) = self.inner.forms.read().get(&hash) {
@ -227,68 +200,62 @@ impl Species {
} else { } else {
let r = species_get_form_by_hash(self.inner.reference, hash); let r = species_get_form_by_hash(self.inner.reference, hash);
let value = r.get_value(); let value = r.get_value();
let value: Option<Form> = if let Some(value) = value {
Some(Rc::new(value))
} else {
None
};
self.inner.forms.write().insert(hash, value.clone()); self.inner.forms.write().insert(hash, value.clone());
value value
} }
} }
} }
#[cfg(not(feature = "mock_data"))] fn has_flag(&self, flag: &str) -> bool {
pub fn has_flag(&self, flag: &str) -> bool {
let hash = get_hash(flag); let hash = get_hash(flag);
unsafe { species_has_flag_by_hash(self.inner.reference, hash) } unsafe { species_has_flag_by_hash(self.inner.reference, hash) }
} }
fn as_any(&self) -> &dyn Any {
self
}
} }
#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for FormImpl {
impl ExternalReferenceType for ImmutableStatisticSet {
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"))] impl ExternalReferenceType for SpeciesImpl {
impl ExternalReferenceType for Form {
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"))] crate::handling::cacheable::cacheable!(FormImpl);
impl ExternalReferenceType for Species { crate::handling::cacheable::cacheable!(SpeciesImpl);
fn from_extern_value(reference: ExternRef<Self>) -> 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" { extern "wasm" {
fn static_statistics_set_get_hp(r: ExternRef<ImmutableStatisticSet>) -> u16; fn form_get_name(r: ExternRef<FormImpl>) -> ExternRef<StringKey>;
fn static_statistics_set_get_attack(r: ExternRef<ImmutableStatisticSet>) -> u16; fn form_get_height(r: ExternRef<FormImpl>) -> f32;
fn static_statistics_set_get_defense(r: ExternRef<ImmutableStatisticSet>) -> u16; fn form_get_weight(r: ExternRef<FormImpl>) -> f32;
fn static_statistics_set_get_special_attack(r: ExternRef<ImmutableStatisticSet>) -> u16; fn form_get_types(r: ExternRef<FormImpl>) -> FFIArray<u8>;
fn static_statistics_set_get_special_defense(r: ExternRef<ImmutableStatisticSet>) -> u16; fn form_get_base_experience(r: ExternRef<FormImpl>) -> u32;
fn static_statistics_set_get_speed(r: ExternRef<ImmutableStatisticSet>) -> u16; fn form_get_base_stats(r: ExternRef<FormImpl>) -> ExternRef<ImmutableStatisticSetImpl>;
fn form_get_abilities(r: ExternRef<FormImpl>) -> VecExternRef<StringKey>;
fn form_get_hidden_abilities(r: ExternRef<FormImpl>) -> VecExternRef<StringKey>;
fn form_has_flag_by_hash(r: ExternRef<FormImpl>, hash: u32) -> bool;
fn form_get_name(r: ExternRef<Form>) -> ExternRef<StringKey>; fn species_get_id(r: ExternRef<SpeciesImpl>) -> u16;
fn form_get_height(r: ExternRef<Form>) -> f32; fn species_get_name(r: ExternRef<SpeciesImpl>) -> ExternRef<StringKey>;
fn form_get_weight(r: ExternRef<Form>) -> f32; fn species_get_gender_rate(r: ExternRef<SpeciesImpl>) -> f32;
fn form_get_types(r: ExternRef<Form>) -> FFIArray<u8>; fn species_get_growth_rate(r: ExternRef<SpeciesImpl>) -> ExternRef<StringKey>;
fn form_get_base_experience(r: ExternRef<Form>) -> u32; fn species_get_capture_rate(r: ExternRef<SpeciesImpl>) -> u8;
fn form_get_base_stats(r: ExternRef<Form>) -> ExternRef<ImmutableStatisticSet>; fn species_get_form_by_hash(r: ExternRef<SpeciesImpl>, hash: u32) -> ExternRef<FormImpl>;
fn form_get_abilities(r: ExternRef<Form>) -> VecExternRef<StringKey>; fn species_has_flag_by_hash(r: ExternRef<SpeciesImpl>, flag_hash: u32) -> bool;
fn form_get_hidden_abilities(r: ExternRef<Form>) -> VecExternRef<StringKey>;
fn form_has_flag_by_hash(r: ExternRef<Form>, hash: u32) -> bool;
fn species_get_id(r: ExternRef<Species>) -> u16;
fn species_get_name(r: ExternRef<Species>) -> ExternRef<StringKey>;
fn species_get_gender_rate(r: ExternRef<Species>) -> f32;
fn species_get_growth_rate(r: ExternRef<Species>) -> ExternRef<StringKey>;
fn species_get_capture_rate(r: ExternRef<Species>) -> u8;
fn species_get_form_by_hash(r: ExternRef<Species>, hash: u32) -> ExternRef<Form>;
fn species_has_flag_by_hash(r: ExternRef<Species>, flag_hash: u32) -> bool;
} }
}
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;

View File

@ -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<dyn ImmutableStatisticSetTrait>;
#[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<ImmutableStatisticSetImpl>,
/// The health point stat value.
hp: CachedValue<u16>,
/// The physical attack stat value.
attack: CachedValue<u16>,
/// The physical defense stat value.
defense: CachedValue<u16>,
/// The special attack stat value.
special_attack: CachedValue<u16>,
/// The special defense stat value.
special_defense: CachedValue<u16>,
/// The speed stat value.
speed: CachedValue<u16>,
}
#[derive(Clone)]
pub struct ImmutableStatisticSetImpl {
inner: Rc<ImmutableStatisticSetInner>,
}
impl ImmutableStatisticSetImpl {
pub(crate) fn new(reference: ExternRef<Self>) -> 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 {
Self::new(reference)
}
}
crate::handling::cacheable::cacheable!(ImmutableStatisticSetImpl);
extern "wasm" {
fn static_statistics_set_get_hp(r: ExternRef<ImmutableStatisticSetImpl>) -> u16;
fn static_statistics_set_get_attack(r: ExternRef<ImmutableStatisticSetImpl>) -> u16;
fn static_statistics_set_get_defense(r: ExternRef<ImmutableStatisticSetImpl>) -> u16;
fn static_statistics_set_get_special_attack(r: ExternRef<ImmutableStatisticSetImpl>)
-> u16;
fn static_statistics_set_get_special_defense(
r: ExternRef<ImmutableStatisticSetImpl>,
) -> u16;
fn static_statistics_set_get_speed(r: ExternRef<ImmutableStatisticSetImpl>) -> u16;
}
}
#[cfg(not(feature = "mock_data"))]
pub use implementation::*;

View File

@ -1,11 +1,14 @@
#[cfg(not(feature = "mock_data"))]
use crate::handling::Cacheable; use crate::handling::Cacheable;
#[cfg(not(feature = "mock_data"))]
use crate::{ExternRef, ExternalReferenceType}; use crate::{ExternRef, ExternalReferenceType};
use alloc::rc::Rc; use alloc::rc::Rc;
use core::cell::RefCell; use core::cell::RefCell;
use core::fmt::{Display, Formatter}; use core::fmt::{Display, Formatter};
use cstr_core::{c_char, CString}; use cstr_core::CString;
struct StringKeyInner { struct StringKeyInner {
#[cfg(not(feature = "mock_data"))]
ptr: ExternRef<StringKey>, ptr: ExternRef<StringKey>,
str: RefCell<Option<CString>>, str: RefCell<Option<CString>>,
hash: RefCell<Option<u32>>, hash: RefCell<Option<u32>>,
@ -69,17 +72,24 @@ impl StringKey {
self.data.hash.borrow().unwrap() 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) self.hash() == get_hash(other)
} }
} }
impl PartialEq for StringKey { impl PartialEq for StringKey {
#[cfg(not(feature = "mock_data"))]
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.data.ptr == other.data.ptr 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); crate::handling::cacheable::cacheable!(StringKey);
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
@ -98,7 +108,7 @@ impl Display for StringKey {
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn string_key_get_str(ptr: ExternRef<StringKey>) -> *mut c_char; fn string_key_get_str(ptr: ExternRef<StringKey>) -> *mut cstr_core::c_char;
fn string_key_get_hash(ptr: ExternRef<StringKey>) -> u32; fn string_key_get_hash(ptr: ExternRef<StringKey>) -> u32;
} }
@ -159,7 +169,7 @@ pub const fn get_hash(s: &str) -> u32 {
mod test { mod test {
use super::get_hash; use super::get_hash;
use super::StringKeyInner; use super::StringKeyInner;
use crate::{ExternRef, StringKey}; use crate::StringKey;
use alloc::rc::Rc; use alloc::rc::Rc;
use core::cell::RefCell; use core::cell::RefCell;
use cstr_core::CString; use cstr_core::CString;
@ -169,7 +179,6 @@ mod test {
let hash = get_hash(s); let hash = get_hash(s);
Self { Self {
data: Rc::new(StringKeyInner { data: Rc::new(StringKeyInner {
ptr: ExternRef::mock(),
str: RefCell::new(Some(CString::new(s).unwrap())), str: RefCell::new(Some(CString::new(s).unwrap())),
hash: RefCell::new(Some(hash)), hash: RefCell::new(Some(hash)),
}), }),

View File

@ -1,6 +1,7 @@
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};
#[cfg(not(feature = "mock_data"))]
use core::intrinsics::transmute; use core::intrinsics::transmute;
use core::marker::PhantomData; use core::marker::PhantomData;
@ -15,6 +16,7 @@ impl<T> ExternRef<T> {
self.p == 0 self.p == 0
} }
#[cfg(not(feature = "mock_data"))]
pub(crate) fn get_internal_index(&self) -> u32 { pub(crate) fn get_internal_index(&self) -> u32 {
self.p self.p
} }
@ -60,20 +62,13 @@ impl<T> ExternRef<T> {
} }
#[inline] #[inline]
#[cfg(not(feature = "mock_data"))]
pub(crate) fn cast<TCast>(&self) -> ExternRef<TCast> { pub(crate) fn cast<TCast>(&self) -> ExternRef<TCast> {
ExternRef::<TCast> { ExternRef::<TCast> {
p: self.p, p: self.p,
resource_type: Default::default(), resource_type: Default::default(),
} }
} }
#[cfg(feature = "mock_data")]
pub(crate) fn mock() -> Self {
Self {
p: 0,
resource_type: Default::default(),
}
}
} }
impl<T> Clone for ExternRef<T> { impl<T> Clone for ExternRef<T> {
@ -133,11 +128,13 @@ impl<T> VecExternRef<T> {
self.v == 0 self.v == 0
} }
#[cfg(not(feature = "mock_data"))]
pub(crate) fn get_internal_index(&self) -> u32 { pub(crate) fn get_internal_index(&self) -> u32 {
let v: (u32, u32) = unsafe { transmute(self.v) }; let v: (u32, u32) = unsafe { transmute(self.v) };
v.0 v.0
} }
#[cfg(not(feature = "mock_data"))]
pub(crate) fn len(&self) -> u32 { pub(crate) fn len(&self) -> u32 {
let v: (u32, u32) = unsafe { transmute(self.v) }; let v: (u32, u32) = unsafe { transmute(self.v) };
v.1 v.1

View File

@ -1,4 +1,5 @@
use alloc::boxed::Box; use alloc::boxed::Box;
#[cfg(not(feature = "mock_data"))]
use alloc::vec::Vec; use alloc::vec::Vec;
use core::mem; use core::mem;
@ -18,7 +19,10 @@ impl<T> FFIArray<T> {
mem::forget(boxed_slice); mem::forget(boxed_slice);
r r
} }
}
#[cfg(not(feature = "mock_data"))]
impl<T> FFIArray<T> {
fn delete(&self) { fn delete(&self) {
unsafe { unsafe {
drop(Vec::from_raw_parts(self.ptr, self.len, self.len)); drop(Vec::from_raw_parts(self.ptr, self.len, self.len));

View File

@ -1,13 +1,17 @@
#[cfg(not(feature = "mock_data"))]
pub(crate) mod cacheable; pub(crate) mod cacheable;
#[cfg(not(feature = "mock_data"))]
pub(crate) mod cached_value; pub(crate) mod cached_value;
pub mod capabilities; pub mod capabilities;
pub mod extern_ref; pub mod extern_ref;
pub mod ffi_array; pub mod ffi_array;
pub mod script; pub mod script;
#[cfg(not(feature = "mock_data"))]
pub(crate) mod temporary; pub(crate) mod temporary;
pub use capabilities::*; pub use capabilities::*;
#[cfg(not(feature = "mock_data"))]
pub(crate) use cacheable::Cacheable; pub(crate) use cacheable::Cacheable;
pub use script::Script; pub use script::Script;

View File

@ -4,11 +4,10 @@ use crate::app_interface::{
Pokemon, Statistic, TurnChoice, TypeIdentifier, Pokemon, Statistic, TurnChoice, TypeIdentifier,
}; };
use crate::handling::ScriptCapabilities; use crate::handling::ScriptCapabilities;
use crate::{ExternRef, ExternalReferenceType, StringKey}; use crate::StringKey;
use alloc::rc::Rc; use alloc::rc::Rc;
use core::any::Any; use core::any::Any;
use core::fmt::{Debug, Display, Formatter}; use core::fmt::{Debug, Display, Formatter};
use core::panicking::panic;
pub trait Script { pub trait Script {
fn new() -> Self fn new() -> Self
@ -364,7 +363,7 @@ impl Debug for dyn Script {
#[cfg(not(feature = "mock_data"))] #[cfg(not(feature = "mock_data"))]
extern "wasm" { extern "wasm" {
fn script_get_owner_kind(pointer: crate::implementation::ScriptPtr) -> u8; fn script_get_owner_kind(pointer: crate::implementation::ScriptPtr) -> u8;
fn script_get_owner(pointer: crate::implementation::ScriptPtr) -> ExternRef<u8>; fn script_get_owner(pointer: crate::implementation::ScriptPtr) -> crate::ExternRef<u8>;
} }
pub enum ScriptOwner { pub enum ScriptOwner {
@ -417,7 +416,7 @@ impl ScriptOwner {
} }
#[cfg(feature = "mock_data")] #[cfg(feature = "mock_data")]
fn from_script(script: &dyn Script) -> Option<ScriptOwner> { fn from_script(_script: &dyn Script) -> Option<ScriptOwner> {
unimplemented!(); unimplemented!();
} }

View File

@ -1,7 +1,6 @@
use alloc::rc::Rc; use alloc::rc::Rc;
use core::sync::atomic::{AtomicBool, Ordering}; use core::sync::atomic::{AtomicBool, Ordering};
#[cfg(not(feature = "mock_data"))]
pub struct Temporary<T> { pub struct Temporary<T> {
is_deleted: Rc<AtomicBool>, is_deleted: Rc<AtomicBool>,
value: Rc<T>, value: Rc<T>,

View File

@ -1,7 +1,9 @@
#[macro_export] #[macro_export]
#[cfg(not(feature = "mock_data"))]
macro_rules! println { ($($args:tt)*) => { crate::utils::print_raw(alloc::format!($($args)*).as_bytes()); } } macro_rules! println { ($($args:tt)*) => { crate::utils::print_raw(alloc::format!($($args)*).as_bytes()); } }
#[macro_export] #[macro_export]
#[cfg(not(feature = "mock_data"))]
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
macro_rules! dbg { ($($args:tt)*) => { crate::utils::print_raw(alloc::format!($($args)*).as_bytes()); } } 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"))] #[cfg(not(feature = "mock_data"))]
pub use implementation::*; 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::*;