Cleanup to resolve all warnings when unit testing.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
258c497982
commit
1d66e08d48
|
@ -1,5 +1,4 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
edition = "2021"
|
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
members = [
|
members = [
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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>);
|
||||||
|
|
|
@ -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!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +1,86 @@
|
||||||
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;
|
|
||||||
|
|
||||||
struct ItemLibraryInner {
|
pub trait ItemLibraryTrait: DataLibrary<Item> {}
|
||||||
ptr: ExternRef<ItemLibrary>,
|
|
||||||
cache: RwLock<hashbrown::HashMap<u32, ItemImpl>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub type ItemLibrary = Rc<dyn ItemLibraryTrait>;
|
||||||
pub struct ItemLibrary {
|
|
||||||
inner: Rc<ItemLibraryInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ItemLibrary {
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
|
|
||||||
Self {
|
|
||||||
inner: Rc::new(ItemLibraryInner {
|
|
||||||
ptr,
|
|
||||||
cache: Default::default(),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DataLibrary<ItemImpl> for ItemLibrary {
|
|
||||||
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, ItemImpl>> {
|
|
||||||
&self.inner.cache
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_self_ref(&self) -> ExternRef<Self> {
|
|
||||||
self.inner.ptr
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<ItemImpl> {
|
|
||||||
unsafe { item_library_get_item(ptr, name) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<ItemImpl> {
|
|
||||||
unsafe { item_library_get_item_by_hash(ptr, hash) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(ItemLibrary);
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for ItemLibrary {
|
mod implementation {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
use super::*;
|
||||||
Self::new(reference)
|
use crate::app_interface::{ItemImpl, StringKey};
|
||||||
|
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||||
|
use spin::RwLock;
|
||||||
|
|
||||||
|
struct ItemLibraryInner {
|
||||||
|
ptr: ExternRef<ItemLibraryImpl>,
|
||||||
|
cache: RwLock<hashbrown::HashMap<u32, Item>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ItemLibraryImpl {
|
||||||
|
inner: Rc<ItemLibraryInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ItemLibraryImpl {
|
||||||
|
pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Rc::new(ItemLibraryInner {
|
||||||
|
ptr,
|
||||||
|
cache: Default::default(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ItemLibraryTrait for ItemLibraryImpl {}
|
||||||
|
|
||||||
|
impl DataLibrary<Item> for ItemLibraryImpl {
|
||||||
|
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, Item>> {
|
||||||
|
&self.inner.cache
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_self_ref(&self) -> ExternRef<Self> {
|
||||||
|
self.inner.ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> u32 {
|
||||||
|
unsafe { item_library_get_item(ptr, name).get_internal_index() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> u32 {
|
||||||
|
unsafe { item_library_get_item_by_hash(ptr, hash).get_internal_index() }
|
||||||
|
}
|
||||||
|
|
||||||
|
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!(ItemLibraryImpl);
|
||||||
|
|
||||||
|
impl ExternalReferenceType for ItemLibraryImpl {
|
||||||
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
|
Self::new(reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "wasm" {
|
||||||
|
fn item_library_get_item(
|
||||||
|
ptr: ExternRef<ItemLibraryImpl>,
|
||||||
|
name: ExternRef<StringKey>,
|
||||||
|
) -> ExternRef<ItemImpl>;
|
||||||
|
fn item_library_get_item_by_hash(
|
||||||
|
ptr: ExternRef<ItemLibraryImpl>,
|
||||||
|
hash: u32,
|
||||||
|
) -> ExternRef<ItemImpl>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
pub use implementation::*;
|
||||||
fn item_library_get_item(
|
|
||||||
ptr: ExternRef<ItemLibrary>,
|
|
||||||
name: ExternRef<StringKey>,
|
|
||||||
) -> ExternRef<ItemImpl>;
|
|
||||||
fn item_library_get_item_by_hash(ptr: ExternRef<ItemLibrary>, hash: u32)
|
|
||||||
-> ExternRef<ItemImpl>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "mock_data")]
|
|
||||||
impl ItemLibrary {
|
|
||||||
pub fn mock() -> Self {
|
|
||||||
Self {
|
|
||||||
inner: Rc::new(ItemLibraryInner {
|
|
||||||
ptr: ExternRef::mock(),
|
|
||||||
cache: Default::default(),
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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!({
|
||||||
static_data_get_species_library(reference)
|
Rc::new(
|
||||||
.get_value()
|
static_data_get_species_library(reference)
|
||||||
.unwrap()
|
.get_value()
|
||||||
|
.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,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,76 +1,101 @@
|
||||||
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;
|
||||||
use spin::RwLock;
|
|
||||||
|
|
||||||
struct MoveLibraryInner {
|
pub trait MoveLibraryTrait: DataLibrary<MoveData> {}
|
||||||
ptr: ExternRef<MoveLibrary>,
|
|
||||||
cache: RwLock<hashbrown::HashMap<u32, MoveData>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub type MoveLibrary = Rc<dyn MoveLibraryTrait>;
|
||||||
pub struct MoveLibrary {
|
|
||||||
inner: Rc<MoveLibraryInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MoveLibrary {
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub(crate) fn new(ptr: ExternRef<Self>) -> 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<MoveData> for MoveLibrary {
|
|
||||||
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, MoveData>> {
|
|
||||||
&self.inner.cache
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_self_ref(&self) -> ExternRef<Self> {
|
|
||||||
self.inner.ptr
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<MoveData> {
|
|
||||||
unsafe { move_library_get_move(ptr, name) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<MoveData> {
|
|
||||||
unsafe { move_library_get_move_by_hash(ptr, hash) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(MoveLibrary);
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for MoveLibrary {
|
mod implementation {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
use super::*;
|
||||||
Self::new(reference)
|
use crate::app_interface::{MoveDataImpl, StringKey};
|
||||||
|
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||||
|
use spin::RwLock;
|
||||||
|
|
||||||
|
struct MoveLibraryInner {
|
||||||
|
ptr: ExternRef<MoveLibraryImpl>,
|
||||||
|
cache: RwLock<hashbrown::HashMap<u32, MoveData>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct MoveLibraryImpl {
|
||||||
|
inner: Rc<MoveLibraryInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MoveLibraryImpl {
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
pub(crate) fn new(ptr: ExternRef<Self>) -> 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<MoveData> for MoveLibraryImpl {
|
||||||
|
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, MoveData>> {
|
||||||
|
&self.inner.cache
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_self_ref(&self) -> ExternRef<Self> {
|
||||||
|
self.inner.ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> u32 {
|
||||||
|
unsafe { move_library_get_move(ptr, name).get_internal_index() }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> u32 {
|
||||||
|
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!(MoveLibraryImpl);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl ExternalReferenceType for MoveLibraryImpl {
|
||||||
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
|
Self::new(reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
extern "wasm" {
|
||||||
|
fn move_library_get_move(
|
||||||
|
ptr: ExternRef<MoveLibraryImpl>,
|
||||||
|
name: ExternRef<StringKey>,
|
||||||
|
) -> ExternRef<MoveDataImpl>;
|
||||||
|
fn move_library_get_move_by_hash(
|
||||||
|
ptr: ExternRef<MoveLibraryImpl>,
|
||||||
|
hash: u32,
|
||||||
|
) -> ExternRef<MoveDataImpl>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
pub use implementation::*;
|
||||||
fn move_library_get_move(
|
|
||||||
ptr: ExternRef<MoveLibrary>,
|
|
||||||
name: ExternRef<StringKey>,
|
|
||||||
) -> ExternRef<MoveData>;
|
|
||||||
fn move_library_get_move_by_hash(ptr: ExternRef<MoveLibrary>, hash: u32)
|
|
||||||
-> ExternRef<MoveData>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,77 +1,88 @@
|
||||||
use crate::app_interface::{DataLibrary, Species};
|
use crate::app_interface::{DataLibrary, Species};
|
||||||
use crate::{ExternRef, ExternalReferenceType, StringKey};
|
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use spin::RwLock;
|
|
||||||
|
|
||||||
struct SpeciesLibraryInner {
|
pub trait SpeciesLibraryTrait: DataLibrary<Species> {}
|
||||||
ptr: ExternRef<SpeciesLibrary>,
|
|
||||||
cache: RwLock<hashbrown::HashMap<u32, Species>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub type SpeciesLibrary = Rc<dyn SpeciesLibraryTrait>;
|
||||||
pub struct SpeciesLibrary {
|
|
||||||
inner: Rc<SpeciesLibraryInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SpeciesLibrary {
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub fn new(ptr: ExternRef<SpeciesLibrary>) -> 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<Species> for SpeciesLibrary {
|
|
||||||
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, Species>> {
|
|
||||||
&self.inner.cache
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_self_ref(&self) -> ExternRef<Self> {
|
|
||||||
self.inner.ptr
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<Species> {
|
|
||||||
unsafe { species_library_get_species(ptr, name) }
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<Species> {
|
|
||||||
unsafe { species_library_get_species_by_hash(ptr, hash) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(SpeciesLibrary);
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for SpeciesLibrary {
|
mod implementation {
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
use crate::app_interface::species_library::SpeciesLibraryTrait;
|
||||||
Self::new(reference)
|
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<SpeciesLibraryImpl>,
|
||||||
|
cache: RwLock<hashbrown::HashMap<u32, Species>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct SpeciesLibraryImpl {
|
||||||
|
inner: Rc<SpeciesLibraryInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpeciesLibraryImpl {
|
||||||
|
pub fn new(ptr: ExternRef<SpeciesLibraryImpl>) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Rc::new(SpeciesLibraryInner {
|
||||||
|
ptr,
|
||||||
|
cache: Default::default(),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpeciesLibraryTrait for SpeciesLibraryImpl {}
|
||||||
|
|
||||||
|
impl DataLibrary<Species> for SpeciesLibraryImpl {
|
||||||
|
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, Species>> {
|
||||||
|
&self.inner.cache
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_self_ref(&self) -> ExternRef<Self> {
|
||||||
|
self.inner.ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> u32 {
|
||||||
|
unsafe { species_library_get_species(ptr, name).get_internal_index() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> u32 {
|
||||||
|
unsafe { species_library_get_species_by_hash(ptr, hash).get_internal_index() }
|
||||||
|
}
|
||||||
|
|
||||||
|
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!(SpeciesLibraryImpl);
|
||||||
|
|
||||||
|
impl ExternalReferenceType for SpeciesLibraryImpl {
|
||||||
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
|
Self::new(reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "wasm" {
|
||||||
|
fn species_library_get_species(
|
||||||
|
ptr: ExternRef<SpeciesLibraryImpl>,
|
||||||
|
name: ExternRef<StringKey>,
|
||||||
|
) -> ExternRef<SpeciesImpl>;
|
||||||
|
fn species_library_get_species_by_hash(
|
||||||
|
ptr: ExternRef<SpeciesLibraryImpl>,
|
||||||
|
hash: u32,
|
||||||
|
) -> ExternRef<SpeciesImpl>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
extern "wasm" {
|
pub use implementation::*;
|
||||||
fn species_library_get_species(
|
|
||||||
ptr: ExternRef<SpeciesLibrary>,
|
|
||||||
name: ExternRef<StringKey>,
|
|
||||||
) -> ExternRef<Species>;
|
|
||||||
fn species_library_get_species_by_hash(
|
|
||||||
ptr: ExternRef<SpeciesLibrary>,
|
|
||||||
hash: u32,
|
|
||||||
) -> ExternRef<Species>;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,118 +1,132 @@
|
||||||
use crate::app_interface::TypeIdentifier;
|
use crate::app_interface::TypeIdentifier;
|
||||||
use crate::{ExternRef, ExternalReferenceType};
|
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use alloc::string::{String, ToString};
|
|
||||||
use cstr_core::{c_char, CString};
|
|
||||||
use spin::RwLock;
|
|
||||||
|
|
||||||
struct TypeLibraryInner {
|
pub trait TypeLibraryTrait {
|
||||||
reference: ExternRef<TypeLibrary>,
|
fn get_type_from_name(&self, name: &str) -> Option<TypeIdentifier>;
|
||||||
name_to_type_cache: RwLock<hashbrown::HashMap<String, TypeIdentifier>>,
|
fn get_single_effectiveness(
|
||||||
effectiveness_cache: RwLock<hashbrown::HashMap<(TypeIdentifier, TypeIdentifier), f32>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct TypeLibrary {
|
|
||||||
inner: Rc<TypeLibraryInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TypeLibrary {
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub(crate) fn new(reference: ExternRef<Self>) -> 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<TypeIdentifier> {
|
|
||||||
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(
|
|
||||||
&self,
|
&self,
|
||||||
attacking_type: TypeIdentifier,
|
attacking_type: TypeIdentifier,
|
||||||
defending_type: TypeIdentifier,
|
defending_type: TypeIdentifier,
|
||||||
) -> f32 {
|
) -> f32;
|
||||||
if let Some(cached) = self
|
fn get_effectiveness(
|
||||||
.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(
|
|
||||||
&self,
|
&self,
|
||||||
attacking_type: TypeIdentifier,
|
attacking_type: TypeIdentifier,
|
||||||
defending_types: &[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 {
|
|
||||||
Self::new(reference)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
extern "wasm" {
|
|
||||||
fn type_library_get_single_effectiveness(
|
|
||||||
r: ExternRef<TypeLibrary>,
|
|
||||||
attacking_type: u8,
|
|
||||||
defending_type: u8,
|
|
||||||
) -> f32;
|
) -> f32;
|
||||||
fn type_library_get_type_by_name(r: ExternRef<TypeLibrary>, name: *const c_char) -> u8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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::string::{String, ToString};
|
||||||
|
use cstr_core::{c_char, CString};
|
||||||
|
use spin::RwLock;
|
||||||
|
|
||||||
|
struct TypeLibraryInner {
|
||||||
|
reference: ExternRef<TypeLibraryImpl>,
|
||||||
|
name_to_type_cache: RwLock<hashbrown::HashMap<String, TypeIdentifier>>,
|
||||||
|
effectiveness_cache: RwLock<hashbrown::HashMap<(TypeIdentifier, TypeIdentifier), f32>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct TypeLibraryImpl {
|
||||||
|
inner: Rc<TypeLibraryInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeLibraryImpl {
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
pub(crate) fn new(reference: ExternRef<Self>) -> 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<TypeIdentifier> {
|
||||||
|
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 {
|
||||||
|
Self::new(reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
extern "wasm" {
|
||||||
|
fn type_library_get_single_effectiveness(
|
||||||
|
r: ExternRef<TypeLibraryImpl>,
|
||||||
|
attacking_type: u8,
|
||||||
|
defending_type: u8,
|
||||||
|
) -> f32;
|
||||||
|
fn type_library_get_type_by_name(r: ExternRef<TypeLibraryImpl>, name: *const c_char) -> u8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
pub use implementation::*;
|
||||||
|
|
|
@ -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}\")"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,75 +57,87 @@ pub type Item = Rc<dyn ItemTrait>;
|
||||||
#[cfg(feature = "mock_data")]
|
#[cfg(feature = "mock_data")]
|
||||||
pub type MockItem = MockItemTrait;
|
pub type MockItem = MockItemTrait;
|
||||||
|
|
||||||
struct ItemInner {
|
|
||||||
reference: ExternRef<ItemImpl>,
|
|
||||||
name: CachedValue<StringKey>,
|
|
||||||
category: CachedValue<ItemCategory>,
|
|
||||||
battle_category: CachedValue<BattleItemCategory>,
|
|
||||||
price: CachedValue<i32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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<ItemInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ItemImpl {
|
mod implementation {
|
||||||
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
|
use crate::app_interface::{BattleItemCategory, ItemCategory, ItemTrait, StringKey};
|
||||||
Self::from_ref(reference, &|reference| Self {
|
use crate::handling::cached_value::CachedValue;
|
||||||
inner: Rc::new(ItemInner {
|
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||||
reference,
|
use crate::handling::Cacheable;
|
||||||
name: cached_value!({ StringKey::new(item_get_name(reference)) }),
|
use crate::{cached_value, cached_value_getters};
|
||||||
category: cached_value!({ item_get_category(reference) }),
|
use alloc::rc::Rc;
|
||||||
battle_category: cached_value!({ item_get_battle_category(reference) }),
|
|
||||||
price: cached_value!({ item_get_price(reference) }),
|
struct ItemInner {
|
||||||
}),
|
reference: ExternRef<ItemImpl>,
|
||||||
})
|
name: CachedValue<StringKey>,
|
||||||
|
category: CachedValue<ItemCategory>,
|
||||||
|
battle_category: CachedValue<BattleItemCategory>,
|
||||||
|
price: CachedValue<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn reference(&self) -> ExternRef<Self> {
|
/// An item is an object which the player can pick up, keep in their Bag, and use in some manner
|
||||||
self.inner.reference
|
#[derive(Clone)]
|
||||||
|
pub struct ItemImpl {
|
||||||
|
inner: Rc<ItemInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_data"))]
|
||||||
|
impl ItemImpl {
|
||||||
|
pub(crate) fn new(reference: ExternRef<Self>) -> 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> {
|
||||||
|
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>) -> Self {
|
||||||
|
ItemImpl::new(reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "wasm" {
|
||||||
|
fn item_get_name(ptr: ExternRef<ItemImpl>) -> ExternRef<StringKey>;
|
||||||
|
fn item_get_category(ptr: ExternRef<ItemImpl>) -> ItemCategory;
|
||||||
|
fn item_get_battle_category(ptr: ExternRef<ItemImpl>) -> BattleItemCategory;
|
||||||
|
fn item_get_price(ptr: ExternRef<ItemImpl>) -> i32;
|
||||||
|
fn item_has_flag(ptr: ExternRef<ItemImpl>, flag: ExternRef<StringKey>) -> bool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ItemTrait for ItemImpl {
|
pub use implementation::*;
|
||||||
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>) -> Self {
|
|
||||||
ItemImpl::new(reference)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
extern "wasm" {
|
|
||||||
fn item_get_name(ptr: ExternRef<ItemImpl>) -> ExternRef<StringKey>;
|
|
||||||
fn item_get_category(ptr: ExternRef<ItemImpl>) -> ItemCategory;
|
|
||||||
fn item_get_battle_category(ptr: ExternRef<ItemImpl>) -> BattleItemCategory;
|
|
||||||
fn item_get_price(ptr: ExternRef<ItemImpl>) -> i32;
|
|
||||||
fn item_has_flag(ptr: ExternRef<ItemImpl>, flag: ExternRef<StringKey>) -> bool;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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,102 +29,102 @@ pub enum MoveTarget {
|
||||||
OnSelf,
|
OnSelf,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MoveDataInner {
|
pub trait MoveDataTrait {
|
||||||
ptr: ExternRef<MoveData>,
|
fn name(&self) -> StringKey;
|
||||||
name: CachedValue<StringKey>,
|
fn move_type(&self) -> u8;
|
||||||
move_type: CachedValue<u8>,
|
fn category(&self) -> MoveCategory;
|
||||||
category: CachedValue<MoveCategory>,
|
fn base_power(&self) -> u8;
|
||||||
base_power: CachedValue<u8>,
|
fn accuracy(&self) -> u8;
|
||||||
accuracy: CachedValue<u8>,
|
fn base_usages(&self) -> u8;
|
||||||
base_usages: CachedValue<u8>,
|
fn target(&self) -> MoveTarget;
|
||||||
target: CachedValue<MoveTarget>,
|
fn priority(&self) -> i8;
|
||||||
priority: CachedValue<i8>,
|
fn has_flag(&self, flag: &str) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub type MoveData = Rc<dyn MoveDataTrait>;
|
||||||
pub struct MoveData {
|
|
||||||
inner: Rc<MoveDataInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MoveData {
|
#[cfg(not(feature = "mock_data"))]
|
||||||
#[cfg(not(feature = "mock_data"))]
|
mod implementation {
|
||||||
pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
|
use super::*;
|
||||||
MoveData::from_ref(ptr, &|ptr| Self {
|
use crate::app_interface::get_hash;
|
||||||
inner: Rc::new(MoveDataInner {
|
use crate::handling::cached_value::CachedValue;
|
||||||
ptr,
|
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType};
|
||||||
name: cached_value!({ StringKey::new(move_data_get_name(ptr)) }),
|
use crate::handling::Cacheable;
|
||||||
move_type: cached_value!({ move_data_get_type(ptr) }),
|
use crate::{cached_value, cached_value_getters};
|
||||||
category: cached_value!({ move_data_get_category(ptr) }),
|
|
||||||
base_power: cached_value!({ move_data_get_base_power(ptr) }),
|
struct MoveDataInner {
|
||||||
accuracy: cached_value!({ move_data_get_accuracy(ptr) }),
|
ptr: ExternRef<MoveDataImpl>,
|
||||||
base_usages: cached_value!({ move_data_get_base_power(ptr) }),
|
name: CachedValue<StringKey>,
|
||||||
target: cached_value!({ move_data_get_target(ptr) }),
|
move_type: CachedValue<u8>,
|
||||||
priority: cached_value!({ move_data_get_priority(ptr) }),
|
category: CachedValue<MoveCategory>,
|
||||||
}),
|
base_power: CachedValue<u8>,
|
||||||
})
|
accuracy: CachedValue<u8>,
|
||||||
|
base_usages: CachedValue<u8>,
|
||||||
|
target: CachedValue<MoveTarget>,
|
||||||
|
priority: CachedValue<i8>,
|
||||||
}
|
}
|
||||||
#[cfg(feature = "mock_data")]
|
|
||||||
pub fn mock(
|
#[derive(Clone)]
|
||||||
name: &str,
|
pub struct MoveDataImpl {
|
||||||
move_type: u8,
|
inner: Rc<MoveDataInner>,
|
||||||
category: MoveCategory,
|
}
|
||||||
base_power: u8,
|
|
||||||
accuracy: u8,
|
impl MoveDataImpl {
|
||||||
base_usages: u8,
|
pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
|
||||||
target: MoveTarget,
|
MoveDataImpl::from_ref(ptr, &|ptr| Self {
|
||||||
priority: i8,
|
inner: Rc::new(MoveDataInner {
|
||||||
) -> Self {
|
ptr,
|
||||||
Self {
|
name: cached_value!({ StringKey::new(move_data_get_name(ptr)) }),
|
||||||
inner: Rc::new(MoveDataInner {
|
move_type: cached_value!({ move_data_get_type(ptr) }),
|
||||||
ptr: ExternRef::mock(),
|
category: cached_value!({ move_data_get_category(ptr) }),
|
||||||
name: StringKey::new(name).into(),
|
base_power: cached_value!({ move_data_get_base_power(ptr) }),
|
||||||
move_type: move_type.into(),
|
accuracy: cached_value!({ move_data_get_accuracy(ptr) }),
|
||||||
category: category.into(),
|
base_usages: cached_value!({ move_data_get_base_power(ptr) }),
|
||||||
base_power: base_power.into(),
|
target: cached_value!({ move_data_get_target(ptr) }),
|
||||||
accuracy: accuracy.into(),
|
priority: cached_value!({ move_data_get_priority(ptr) }),
|
||||||
base_usages: base_usages.into(),
|
}),
|
||||||
target: target.into(),
|
})
|
||||||
priority: priority.into(),
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cached_value_getters! {
|
impl MoveDataTrait for MoveDataImpl {
|
||||||
pub fn name(&self) -> StringKey;
|
cached_value_getters! {
|
||||||
pub fn move_type(&self) -> u8;
|
fn name(&self) -> StringKey;
|
||||||
pub fn category(&self) -> MoveCategory;
|
fn move_type(&self) -> u8;
|
||||||
pub fn base_power(&self) -> u8;
|
fn category(&self) -> MoveCategory;
|
||||||
pub fn accuracy(&self) -> u8;
|
fn base_power(&self) -> u8;
|
||||||
pub fn base_usages(&self) -> u8;
|
fn accuracy(&self) -> u8;
|
||||||
pub fn target(&self) -> MoveTarget;
|
fn base_usages(&self) -> u8;
|
||||||
pub fn priority(&self) -> i8;
|
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"))]
|
impl ExternalReferenceType for MoveDataImpl {
|
||||||
pub fn has_flag(&self, flag: &str) -> bool {
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
let hash = get_hash(flag);
|
MoveDataImpl::new(reference)
|
||||||
unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash) }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"))]
|
||||||
impl ExternalReferenceType for MoveData {
|
pub use implementation::*;
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
|
||||||
MoveData::new(reference)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate::handling::cacheable::cacheable!(MoveData);
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
extern "wasm" {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,55 +1,87 @@
|
||||||
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;
|
||||||
|
|
||||||
struct NatureInner {
|
pub trait NatureTrait {
|
||||||
reference: ExternRef<Nature>,
|
fn increase_stat(&self) -> Statistic;
|
||||||
/// The stat that should receive the increased modifier.
|
fn decrease_stat(&self) -> Statistic;
|
||||||
increase_stat: Statistic,
|
fn increase_modifier(&self) -> f32;
|
||||||
/// The stat that should receive the decreased modifier.
|
fn decrease_modifier(&self) -> f32;
|
||||||
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 type Nature = Rc<dyn NatureTrait>;
|
||||||
pub struct Nature {
|
|
||||||
inner: Rc<NatureInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
struct NatureInner {
|
||||||
#[cfg(not(feature = "mock_data"))]
|
reference: ExternRef<NatureImpl>,
|
||||||
pub fn new(reference: ExternRef<Self>) -> Self {
|
/// The stat that should receive the increased modifier.
|
||||||
Self::from_ref(reference, &|reference| unsafe {
|
increase_stat: Statistic,
|
||||||
Self {
|
/// The stat that should receive the decreased modifier.
|
||||||
inner: Rc::new(NatureInner {
|
decrease_stat: Statistic,
|
||||||
reference,
|
/// The amount by which the increased stat is multiplied.
|
||||||
increase_stat: nature_get_increase_stat(reference),
|
increase_modifier: f32,
|
||||||
decrease_stat: nature_get_decrease_stat(reference),
|
/// The amount by which the decreased stat is multiplied.
|
||||||
increase_modifier: nature_get_increase_modifier(reference),
|
decrease_modifier: f32,
|
||||||
decrease_modifier: nature_get_decrease_modifier(reference),
|
}
|
||||||
}),
|
|
||||||
}
|
#[derive(Clone)]
|
||||||
})
|
pub struct NatureImpl {
|
||||||
|
inner: Rc<NatureInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::handling::cacheable::cacheable!(NatureImpl);
|
||||||
|
|
||||||
|
impl NatureImpl {
|
||||||
|
pub fn new(reference: ExternRef<Self>) -> 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 {
|
||||||
|
Self::new(reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "wasm" {
|
||||||
|
fn nature_get_increase_stat(r: ExternRef<NatureImpl>) -> Statistic;
|
||||||
|
fn nature_get_decrease_stat(r: ExternRef<NatureImpl>) -> Statistic;
|
||||||
|
fn nature_get_increase_modifier(r: ExternRef<NatureImpl>) -> f32;
|
||||||
|
fn nature_get_decrease_modifier(r: ExternRef<NatureImpl>) -> f32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for Nature {
|
pub use implementation::*;
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
|
||||||
Self::new(reference)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
extern "wasm" {
|
|
||||||
fn nature_get_increase_stat(r: ExternRef<Nature>) -> Statistic;
|
|
||||||
fn nature_get_decrease_stat(r: ExternRef<Nature>) -> Statistic;
|
|
||||||
fn nature_get_increase_modifier(r: ExternRef<Nature>) -> f32;
|
|
||||||
fn nature_get_decrease_modifier(r: ExternRef<Nature>) -> f32;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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,275 +12,250 @@ 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"))]
|
mod implementation {
|
||||||
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
|
use super::*;
|
||||||
Self::from_ref(reference, &|reference| Self {
|
use crate::app_interface::list::ImmutableListWasm;
|
||||||
inner: Rc::new(ImmutableStatisticSetInner {
|
use crate::app_interface::{get_hash, ImmutableStatisticSetImpl};
|
||||||
reference,
|
use crate::handling::cached_value::CachedValue;
|
||||||
hp: cached_value!({ static_statistics_set_get_hp(reference) }),
|
use crate::handling::extern_ref::{ExternRef, ExternalReferenceType, VecExternRef};
|
||||||
attack: cached_value!({ static_statistics_set_get_attack(reference) }),
|
use crate::handling::ffi_array::FFIArray;
|
||||||
defense: cached_value!({ static_statistics_set_get_defense(reference) }),
|
use crate::handling::Cacheable;
|
||||||
special_attack: cached_value!({
|
use crate::{cached_value, cached_value_getters};
|
||||||
static_statistics_set_get_special_attack(reference)
|
use spin::RwLock;
|
||||||
|
|
||||||
|
struct FormInner {
|
||||||
|
reference: ExternRef<FormImpl>,
|
||||||
|
name: CachedValue<StringKey>,
|
||||||
|
height: CachedValue<f32>,
|
||||||
|
weight: CachedValue<f32>,
|
||||||
|
types: CachedValue<Vec<u8>>,
|
||||||
|
base_experience: CachedValue<u32>,
|
||||||
|
base_stats: CachedValue<ImmutableStatisticSet>,
|
||||||
|
abilities: CachedValue<ImmutableList<Rc<StringKey>>>,
|
||||||
|
hidden_abilities: CachedValue<ImmutableList<Rc<StringKey>>>,
|
||||||
|
// moves: CachedValue<LearnableMoves>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct FormImpl {
|
||||||
|
inner: Rc<FormInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FormImpl {
|
||||||
|
pub(crate) fn new(reference: ExternRef<Self>) -> 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 {
|
pub(crate) fn reference(&self) -> ExternRef<Self> {
|
||||||
self.inner.hp.value()
|
self.inner.reference
|
||||||
}
|
|
||||||
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<Form>,
|
|
||||||
name: CachedValue<StringKey>,
|
|
||||||
height: CachedValue<f32>,
|
|
||||||
weight: CachedValue<f32>,
|
|
||||||
types: CachedValue<Vec<u8>>,
|
|
||||||
base_experience: CachedValue<u32>,
|
|
||||||
base_stats: CachedValue<ImmutableStatisticSet>,
|
|
||||||
abilities: CachedValue<ImmutableList<Rc<StringKey>>>,
|
|
||||||
hidden_abilities: CachedValue<ImmutableList<Rc<StringKey>>>,
|
|
||||||
// moves: CachedValue<LearnableMoves>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Form {
|
|
||||||
inner: Rc<FormInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Form {
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub(crate) fn new(reference: ExternRef<Self>) -> 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> {
|
|
||||||
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> {
|
|
||||||
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<Species>,
|
|
||||||
id: CachedValue<u16>,
|
|
||||||
name: CachedValue<StringKey>,
|
|
||||||
gender_rate: CachedValue<f32>,
|
|
||||||
growth_rate: CachedValue<StringKey>,
|
|
||||||
capture_rate: CachedValue<u8>,
|
|
||||||
forms: RwLock<hashbrown::HashMap<u32, Option<Form>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Species {
|
|
||||||
inner: Rc<SpeciesInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Species {
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
pub(crate) fn new(reference: ExternRef<Species>) -> 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> {
|
impl FormTrait for FormImpl {
|
||||||
self.inner.reference
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
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! {
|
pub struct SpeciesInner {
|
||||||
/// The national dex identifier of the Pokemon.
|
reference: ExternRef<SpeciesImpl>,
|
||||||
pub fn id(&self) -> u16;
|
id: CachedValue<u16>,
|
||||||
/// The name of the Pokemon species.
|
name: CachedValue<StringKey>,
|
||||||
pub fn name(&self) -> StringKey;
|
gender_rate: CachedValue<f32>,
|
||||||
/// The chance between 0.0 and 1.0 that a Pokemon is female.
|
growth_rate: CachedValue<StringKey>,
|
||||||
pub fn gender_rate(&self) -> f32;
|
capture_rate: CachedValue<u8>,
|
||||||
/// How much experience is required for a level.
|
forms: RwLock<hashbrown::HashMap<u32, Option<Form>>>,
|
||||||
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"))]
|
#[derive(Clone)]
|
||||||
pub fn get_form(&self, form_name: &str) -> Option<Form> {
|
pub struct SpeciesImpl {
|
||||||
let hash = get_hash(form_name);
|
inner: Rc<SpeciesInner>,
|
||||||
unsafe {
|
}
|
||||||
if let Some(v) = self.inner.forms.read().get(&hash) {
|
|
||||||
v.clone()
|
impl SpeciesImpl {
|
||||||
} else {
|
pub(crate) fn new(reference: ExternRef<SpeciesImpl>) -> Self {
|
||||||
let r = species_get_form_by_hash(self.inner.reference, hash);
|
Self {
|
||||||
let value = r.get_value();
|
inner: Rc::new(SpeciesInner {
|
||||||
self.inner.forms.write().insert(hash, value.clone());
|
reference,
|
||||||
value
|
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> {
|
||||||
|
self.inner.reference
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
impl SpeciesTrait for SpeciesImpl {
|
||||||
pub fn has_flag(&self, flag: &str) -> bool {
|
cached_value_getters! {
|
||||||
let hash = get_hash(flag);
|
/// The national dex identifier of the Pokemon.
|
||||||
unsafe { species_has_flag_by_hash(self.inner.reference, hash) }
|
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);
|
||||||
|
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<Form> = 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 {
|
||||||
|
Self::new(reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExternalReferenceType for SpeciesImpl {
|
||||||
|
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||||
|
Self::new(reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
crate::handling::cacheable::cacheable!(FormImpl);
|
||||||
|
crate::handling::cacheable::cacheable!(SpeciesImpl);
|
||||||
|
|
||||||
|
extern "wasm" {
|
||||||
|
fn form_get_name(r: ExternRef<FormImpl>) -> ExternRef<StringKey>;
|
||||||
|
fn form_get_height(r: ExternRef<FormImpl>) -> f32;
|
||||||
|
fn form_get_weight(r: ExternRef<FormImpl>) -> f32;
|
||||||
|
fn form_get_types(r: ExternRef<FormImpl>) -> FFIArray<u8>;
|
||||||
|
fn form_get_base_experience(r: ExternRef<FormImpl>) -> u32;
|
||||||
|
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 species_get_id(r: ExternRef<SpeciesImpl>) -> u16;
|
||||||
|
fn species_get_name(r: ExternRef<SpeciesImpl>) -> ExternRef<StringKey>;
|
||||||
|
fn species_get_gender_rate(r: ExternRef<SpeciesImpl>) -> f32;
|
||||||
|
fn species_get_growth_rate(r: ExternRef<SpeciesImpl>) -> ExternRef<StringKey>;
|
||||||
|
fn species_get_capture_rate(r: ExternRef<SpeciesImpl>) -> u8;
|
||||||
|
fn species_get_form_by_hash(r: ExternRef<SpeciesImpl>, hash: u32) -> ExternRef<FormImpl>;
|
||||||
|
fn species_has_flag_by_hash(r: ExternRef<SpeciesImpl>, flag_hash: u32) -> bool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
#[cfg(not(feature = "mock_data"))]
|
||||||
impl ExternalReferenceType for ImmutableStatisticSet {
|
pub use implementation::*;
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
|
||||||
Self::new(reference)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
impl ExternalReferenceType for Form {
|
|
||||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
|
||||||
Self::new(reference)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_data"))]
|
|
||||||
impl ExternalReferenceType for Species {
|
|
||||||
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" {
|
|
||||||
fn static_statistics_set_get_hp(r: ExternRef<ImmutableStatisticSet>) -> u16;
|
|
||||||
fn static_statistics_set_get_attack(r: ExternRef<ImmutableStatisticSet>) -> u16;
|
|
||||||
fn static_statistics_set_get_defense(r: ExternRef<ImmutableStatisticSet>) -> u16;
|
|
||||||
fn static_statistics_set_get_special_attack(r: ExternRef<ImmutableStatisticSet>) -> u16;
|
|
||||||
fn static_statistics_set_get_special_defense(r: ExternRef<ImmutableStatisticSet>) -> u16;
|
|
||||||
fn static_statistics_set_get_speed(r: ExternRef<ImmutableStatisticSet>) -> u16;
|
|
||||||
|
|
||||||
fn form_get_name(r: ExternRef<Form>) -> ExternRef<StringKey>;
|
|
||||||
fn form_get_height(r: ExternRef<Form>) -> f32;
|
|
||||||
fn form_get_weight(r: ExternRef<Form>) -> f32;
|
|
||||||
fn form_get_types(r: ExternRef<Form>) -> FFIArray<u8>;
|
|
||||||
fn form_get_base_experience(r: ExternRef<Form>) -> u32;
|
|
||||||
fn form_get_base_stats(r: ExternRef<Form>) -> ExternRef<ImmutableStatisticSet>;
|
|
||||||
fn form_get_abilities(r: ExternRef<Form>) -> VecExternRef<StringKey>;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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::*;
|
|
@ -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)),
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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::*;
|
|
||||||
|
|
Loading…
Reference in New Issue