diff --git a/Cargo.toml b/Cargo.toml index 3e41385..22c8dac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +edition = "2021" members = [ "pkmn_lib_interface", @@ -9,4 +10,5 @@ members = [ # Tell `rustc` to optimize for small code size. opt-level = "s" lto = false -debug-assertions = true \ No newline at end of file +debug-assertions = true + diff --git a/gen_7_scripts/Cargo.toml b/gen_7_scripts/Cargo.toml index 63902a8..b6544d6 100644 --- a/gen_7_scripts/Cargo.toml +++ b/gen_7_scripts/Cargo.toml @@ -2,10 +2,13 @@ name = "gen7_scripts" version = "0.1.0" authors = ["Deukhoofd "] -edition = "2018" +edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] -pkmn_lib_interface = { path = "../pkmn_lib_interface" } \ No newline at end of file +pkmn_lib_interface = { path = "../pkmn_lib_interface" } + +[dev-dependencies] +pkmn_lib_interface = { path = "../pkmn_lib_interface", features = ["mock_data"] } diff --git a/gen_7_scripts/src/lib.rs b/gen_7_scripts/src/lib.rs index 9d17fdd..10d6dc3 100644 --- a/gen_7_scripts/src/lib.rs +++ b/gen_7_scripts/src/lib.rs @@ -1,7 +1,7 @@ #![feature(inline_const)] #![feature(inline_const_pat)] #![feature(wasm_abi)] -#![no_std] +#![cfg_attr(not(test), no_std)] #![allow(incomplete_features)] extern crate alloc; @@ -15,6 +15,7 @@ pub mod registered_scripts; pub mod test_script; #[no_mangle] +#[cfg(not(test))] extern "wasm" fn _init() { set_load_script_fn(Box::new(registered_scripts::get_script)); } diff --git a/gen_7_scripts/src/registered_scripts.rs b/gen_7_scripts/src/registered_scripts.rs index 9b01fa7..1f17759 100644 --- a/gen_7_scripts/src/registered_scripts.rs +++ b/gen_7_scripts/src/registered_scripts.rs @@ -1,6 +1,6 @@ use crate::test_script::TestScript; use alloc::boxed::Box; -use pkmn_lib_interface::app_interface::{get_hash, StringKey}; +use pkmn_lib_interface::app_interface::{get_hash_const, StringKey}; use pkmn_lib_interface::handling::{Script, ScriptCategory}; macro_rules! resolve_match { @@ -12,7 +12,7 @@ macro_rules! resolve_match { ) => ( match $mid { $( - const { get_hash($key) } => { + const { get_hash_const($key) } => { return Some(Box::new($script {})) } )* diff --git a/gen_7_scripts/src/test_script.rs b/gen_7_scripts/src/test_script.rs index 583e854..61e10f2 100644 --- a/gen_7_scripts/src/test_script.rs +++ b/gen_7_scripts/src/test_script.rs @@ -1,6 +1,6 @@ use pkmn_lib_interface::app_interface::list::ImmutableList; use pkmn_lib_interface::app_interface::{ - get_hash, DamageSource, DataLibrary, DynamicLibrary, EffectParameter, TurnChoice, + get_hash_const, DamageSource, DataLibrary, DynamicLibrary, EffectParameter, TurnChoice, }; use pkmn_lib_interface::dbg; use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; @@ -31,14 +31,13 @@ impl Script for TestScript { ) { let l = library.data_library(); let ml = l.move_library(); - let m = ml.get_by_hash(const { get_hash(b"tackle") }).unwrap(); + let m = ml.get_by_hash(const { get_hash_const(b"tackle") }).unwrap(); dbg!("found move!"); dbg!("{:?} has {} base power", m.name().str(), m.base_power()); dbg!( "Found a parameter with value: {}", parameters.unwrap().get(0).unwrap() ); - if m.has_flag(b"foo") {} } fn on_before_turn(&self, choice: TurnChoice) { @@ -46,7 +45,7 @@ impl Script for TestScript { "On before turn for user: {}", choice.user().species().name() ); - choice.user().damage(50, DamageSource::Misc); + // choice.user().damage(50, DamageSource::Misc); if let TurnChoice::Move(d) = choice { dbg!( "On before turn for move choice: {}", @@ -55,3 +54,49 @@ impl Script for TestScript { } } } + +#[cfg(test)] +mod test { + use super::*; + use pkmn_lib_interface::app_interface::move_library::MoveLibrary; + use pkmn_lib_interface::app_interface::species_library::SpeciesLibrary; + use pkmn_lib_interface::app_interface::type_library::TypeLibrary; + use pkmn_lib_interface::app_interface::{ + Item, ItemLibrary, LibrarySettings, MoveCategory, MoveData, MoveTarget, StaticData, + }; + use pkmn_lib_interface::handling::Script; + + #[test] + fn test_foo() { + let item = Item::mock(); + assert_eq!(item.name().str().to_str().unwrap(), "test"); + + let script = TestScript::new(); + assert_eq!(script.get_name(), "TestScript"); + + let lib = DynamicLibrary::new(StaticData::mock( + MoveLibrary::mock(), + ItemLibrary::mock(), + SpeciesLibrary::mock(), + TypeLibrary::mock(), + LibrarySettings::mock(100), + )); + lib.data_library().move_library().insert( + const { get_hash_const(b"tackle") }, + MoveData::mock( + "tackle", + 0, + MoveCategory::Physical, + 60, + 100, + 10, + MoveTarget::Adjacent, + 0, + ), + ); + script.on_initialize( + &lib, + Some(ImmutableList::mock((&[EffectParameter::Int(100)]).to_vec())), + ); + } +} diff --git a/pkmn_lib_interface/Cargo.toml b/pkmn_lib_interface/Cargo.toml index 70c62e2..d6e1cde 100644 --- a/pkmn_lib_interface/Cargo.toml +++ b/pkmn_lib_interface/Cargo.toml @@ -2,7 +2,10 @@ name = "pkmn_lib_interface" version = "0.1.0" authors = ["Deukhoofd "] -edition = "2018" +edition = "2021" + +[features] +mock_data = [] [dependencies] wee_alloc = "0.4.5" diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs index 256daa3..08c4047 100644 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs @@ -21,6 +21,7 @@ pub struct Battle { } impl Battle { + #[cfg(not(feature = "mock_data"))] pub fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(BattleInner { @@ -39,6 +40,7 @@ impl Battle { pub fn sides(&self) -> ImmutableList; } + #[cfg(not(feature = "mock_data"))] pub fn get_pokemon(&self, side: u8, index: u8) -> Option { unsafe { battle_get_pokemon(self.inner.reference, side, index).get_value() } } @@ -57,12 +59,14 @@ wasm_value_getters! { crate::handling::cacheable::cacheable!(Battle); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for Battle { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn battle_get_library(r: ExternRef) -> ExternRef; fn battle_get_parties(r: ExternRef) -> VecExternRef; diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/battle_party.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/battle_party.rs index 57eec8d..7ef96e0 100644 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/battle_party.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/battle_party.rs @@ -15,6 +15,7 @@ pub struct BattleParty { } impl BattleParty { + #[cfg(not(feature = "mock_data"))] pub fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(BattlePartyInner { @@ -31,12 +32,15 @@ impl BattleParty { crate::handling::cacheable::cacheable!(BattleParty); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for BattleParty { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } + +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn battle_party_get_party(r: ExternRef) -> ExternRef; } diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/battle_random.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/battle_random.rs index 5ad8636..9de7142 100644 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/battle_random.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/battle_random.rs @@ -6,12 +6,15 @@ pub struct BattleRandom { } impl BattleRandom { + #[cfg(not(feature = "mock_data"))] pub fn get(&self) -> i32 { unsafe { battle_random_get(self.reference) } } + #[cfg(not(feature = "mock_data"))] pub fn get_max(&self, max: i32) -> i32 { unsafe { battle_random_get_max(self.reference, max) } } + #[cfg(not(feature = "mock_data"))] pub fn get_between(&self, min: i32, max: i32) -> i32 { unsafe { battle_random_get_between(self.reference, min, max) } } @@ -24,6 +27,7 @@ impl ExternalReferenceType for BattleRandom { } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn battle_random_get(r: ExternRef) -> i32; fn battle_random_get_max(r: ExternRef, max: i32) -> i32; diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/battle_side.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/battle_side.rs index 1176e57..f6175e1 100644 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/battle_side.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/battle_side.rs @@ -19,6 +19,7 @@ pub struct BattleSide { } impl BattleSide { + #[cfg(not(feature = "mock_data"))] pub fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(BattleSideInner { @@ -36,6 +37,7 @@ impl BattleSide { pub fn battle(&self) -> Battle; } + #[cfg(not(feature = "mock_data"))] pub fn get_pokemon(&self, index: usize) -> Option { unsafe { battleside_get_pokemon(self.inner.reference, index).get_value() } } @@ -49,12 +51,14 @@ wasm_value_getters! { crate::handling::cacheable::cacheable!(BattleSide); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for BattleSide { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn battleside_get_side_index(r: ExternRef) -> u8; fn battleside_get_pokemon_per_side(r: ExternRef) -> u8; diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/dynamic_library.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/dynamic_library.rs index 9a0ae01..1f1fbb5 100644 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/dynamic_library.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/dynamic_library.rs @@ -17,6 +17,7 @@ pub struct DynamicLibrary { crate::handling::cacheable::cacheable!(DynamicLibrary); impl DynamicLibrary { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(ptr: ExternRef) -> Self { Self::from_ref(ptr, &|ptr| Self { inner: Rc::new(DynamicLibraryInner { @@ -28,17 +29,29 @@ impl DynamicLibrary { }) } + #[cfg(feature = "mock_data")] + pub fn new(data: StaticData) -> Self { + Self { + inner: Rc::new(DynamicLibraryInner { + ptr: ExternRef::mock(), + static_data: data.into(), + }), + } + } + pub fn data_library(&self) -> StaticData { self.inner.static_data.value() } } +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for DynamicLibrary { fn from_extern_value(reference: ExternRef) -> Self { DynamicLibrary::new(reference) } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn dynamic_library_get_static_data(ptr: ExternRef) -> ExternRef; } diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/learned_move.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/learned_move.rs index ad50597..5d32b49 100644 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/learned_move.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/learned_move.rs @@ -30,6 +30,7 @@ pub struct LearnedMove { crate::handling::cacheable::cacheable!(LearnedMove); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for LearnedMove { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) @@ -37,6 +38,7 @@ impl ExternalReferenceType for LearnedMove { } impl LearnedMove { + #[cfg(not(feature = "mock_data"))] pub fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(LearnedMoveInner { @@ -54,12 +56,14 @@ impl LearnedMove { pub fn learn_method(&self) -> MoveLearnMethod; } + #[cfg(not(feature = "mock_data"))] pub fn restore_all_uses(&self) { unsafe { learned_move_restore_all_uses(self.inner.reference); } } + #[cfg(not(feature = "mock_data"))] pub fn restore_uses(&self, uses: u8) { unsafe { learned_move_restore_uses(self.inner.reference, uses); @@ -73,6 +77,7 @@ wasm_value_getters! { pub fn remaining_pp(&self) -> u8; } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn learned_move_get_move_data(r: ExternRef) -> ExternRef; fn learned_move_get_learn_method(r: ExternRef) -> MoveLearnMethod; diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/party.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/party.rs index 5ac5b12..abd50ea 100644 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/party.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/party.rs @@ -11,6 +11,7 @@ impl Party { Self { reference } } + #[cfg(not(feature = "mock_data"))] pub fn get_pokemon(&self, index: usize) -> Option { unsafe { party_get_pokemon(self.reference, index).get_value() } } @@ -22,6 +23,7 @@ impl ExternalReferenceType for Party { } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn party_get_pokemon(r: ExternRef, index: usize) -> ExternRef; } diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs index 0b7b536..615c25e 100644 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs @@ -34,6 +34,7 @@ pub struct Pokemon { } impl Pokemon { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(PokemonInner { @@ -69,33 +70,41 @@ impl Pokemon { pub fn effort_values(&self) -> ClampedStatisticSet; } + #[cfg(not(feature = "mock_data"))] pub fn has_held_item(&self, name: &str) -> bool { let cstr = CString::new(name).unwrap(); unsafe { pokemon_has_held_item(self.inner.reference, cstr.as_ptr()) } } + #[cfg(not(feature = "mock_data"))] pub fn set_held_item(&self, item: &Item) -> Option { unsafe { pokemon_set_held_item(self.inner.reference, item.reference()).get_value() } } + #[cfg(not(feature = "mock_data"))] pub fn remove_held_item(&self) -> Option { unsafe { pokemon_remove_held_item(self.inner.reference).get_value() } } + #[cfg(not(feature = "mock_data"))] pub fn consume_held_item(&self) -> bool { unsafe { pokemon_consume_held_item(self.inner.reference) } } + #[cfg(not(feature = "mock_data"))] pub fn max_health(&self) -> u32 { self.boosted_stats().hp() } + #[cfg(not(feature = "mock_data"))] pub fn get_type(&self, index: usize) -> u8 { unsafe { pokemon_get_type(self.inner.reference, index) } } + #[cfg(not(feature = "mock_data"))] pub fn has_type(&self, type_identifier: u8) -> bool { unsafe { pokemon_has_type(self.inner.reference, type_identifier) } } + #[cfg(not(feature = "mock_data"))] pub fn has_type_by_name(&self, type_name: &str) -> bool { let type_identifier = self .library() @@ -107,9 +116,12 @@ impl Pokemon { } false } + + #[cfg(not(feature = "mock_data"))] pub fn get_learned_move(&self, index: usize) -> Option { unsafe { pokemon_get_learned_move(self.inner.reference, index).get_value() } } + #[cfg(not(feature = "mock_data"))] pub fn change_stat_boost( &self, stat: Statistic, @@ -121,16 +133,19 @@ impl Pokemon { } } + #[cfg(not(feature = "mock_data"))] pub fn ability_script(&self) -> Option<&Box> { unsafe { pokemon_get_ability_script(self.inner.reference).as_ref() } } + #[cfg(not(feature = "mock_data"))] pub fn change_species(&self, species: Species, form: Form) { unsafe { pokemon_change_species(self.inner.reference, species.reference(), form.reference()); } } + #[cfg(not(feature = "mock_data"))] pub fn change_form(&self, form: Form) { unsafe { pokemon_change_form(self.inner.reference, form.reference()); @@ -141,15 +156,18 @@ impl Pokemon { self.current_health() == 0 } + #[cfg(not(feature = "mock_data"))] pub fn damage(&self, damage: u32, source: DamageSource) { unsafe { pokemon_damage(self.inner.reference, damage, source) } } + #[cfg(not(feature = "mock_data"))] pub fn heal(&self, amount: u32, allow_revive: bool) -> bool { unsafe { pokemon_heal(self.inner.reference, amount, allow_revive) } } } +#[cfg(not(feature = "mock_data"))] wasm_reference_getters! { Pokemon, pub fn species(&self) -> Species; @@ -158,6 +176,7 @@ wasm_reference_getters! { pub fn nature(&self) -> Nature; } +#[cfg(not(feature = "mock_data"))] wasm_optional_reference_getters! { Pokemon, pub fn display_species(&self) -> Option; @@ -166,6 +185,7 @@ wasm_optional_reference_getters! { pub fn battle(&self) -> Option; } +#[cfg(not(feature = "mock_data"))] wasm_value_getters! { Pokemon, pub fn level(&self) -> LevelInt; @@ -198,12 +218,14 @@ pub enum DamageSource { crate::handling::cacheable::cacheable!(Pokemon); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for Pokemon { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn pokemon_get_library(r: ExternRef) -> ExternRef; fn pokemon_get_flat_stats(r: ExternRef) -> ExternRef>; @@ -234,3 +256,13 @@ extern "wasm" { fn pokemon_damage(r: ExternRef, damage: u32, source: DamageSource); fn pokemon_heal(r: ExternRef, amount: u32, allow_revive: bool) -> bool; } + +#[cfg(feature = "mock_data")] +impl Pokemon { + pub fn current_health(&self) -> u32 { + unimplemented!() + } + pub fn species(&self) -> Species { + unimplemented!() + } +} diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/statistic_set.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/statistic_set.rs index cba199d..f745fd3 100644 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/statistic_set.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/statistic_set.rs @@ -28,25 +28,32 @@ where } } + #[cfg(not(feature = "mock_data"))] pub fn hp(&self) -> T { self.get_stat(Statistic::HP) } + #[cfg(not(feature = "mock_data"))] pub fn attack(&self) -> T { self.get_stat(Statistic::Attack) } + #[cfg(not(feature = "mock_data"))] pub fn defense(&self) -> T { self.get_stat(Statistic::Defense) } + #[cfg(not(feature = "mock_data"))] pub fn special_attack(&self) -> T { self.get_stat(Statistic::SpecialAttack) } + #[cfg(not(feature = "mock_data"))] pub fn special_defense(&self) -> T { self.get_stat(Statistic::SpecialDefense) } + #[cfg(not(feature = "mock_data"))] pub fn speed(&self) -> T { self.get_stat(Statistic::Speed) } + #[cfg(not(feature = "mock_data"))] pub fn get_stat(&self, stat: Statistic) -> T { unsafe { statistic_set_get(self.reference.cast(), stat) @@ -55,15 +62,18 @@ where } } + #[cfg(not(feature = "mock_data"))] pub fn set_stat(&self, stat: Statistic, value: T) { unsafe { statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()) } } + #[cfg(not(feature = "mock_data"))] pub fn increase_stat(&self, stat: Statistic, value: T) { unsafe { statistic_set_increase_stat(self.reference.cast(), stat, value.try_into().unwrap()) } } + #[cfg(not(feature = "mock_data"))] pub fn decrease_stat(&self, stat: Statistic, value: T) { unsafe { statistic_set_decrease_stat(self.reference.cast(), stat, value.try_into().unwrap()) @@ -106,25 +116,33 @@ where _p: Default::default(), } } + + #[cfg(not(feature = "mock_data"))] pub fn hp(&self) -> T { self.get_stat(Statistic::HP) } + #[cfg(not(feature = "mock_data"))] pub fn attack(&self) -> T { self.get_stat(Statistic::Attack) } + #[cfg(not(feature = "mock_data"))] pub fn defense(&self) -> T { self.get_stat(Statistic::Defense) } + #[cfg(not(feature = "mock_data"))] pub fn special_attack(&self) -> T { self.get_stat(Statistic::SpecialAttack) } + #[cfg(not(feature = "mock_data"))] pub fn special_defense(&self) -> T { self.get_stat(Statistic::SpecialDefense) } + #[cfg(not(feature = "mock_data"))] pub fn speed(&self) -> T { self.get_stat(Statistic::Speed) } + #[cfg(not(feature = "mock_data"))] pub fn get_stat(&self, stat: Statistic) -> T { unsafe { clamped_statistic_set_get(self.reference.cast(), stat) @@ -133,10 +151,12 @@ where } } + #[cfg(not(feature = "mock_data"))] pub fn set_stat(&self, stat: Statistic, value: T) { unsafe { clamped_statistic_set_set(self.reference.cast(), stat, value.try_into().unwrap()) } } + #[cfg(not(feature = "mock_data"))] pub fn increase_stat(&self, stat: Statistic, value: T) -> bool { unsafe { clamped_statistic_set_increase_stat( @@ -146,6 +166,7 @@ where ) } } + #[cfg(not(feature = "mock_data"))] pub fn decrease_stat(&self, stat: Statistic, value: T) -> bool { unsafe { clamped_statistic_set_decrease_stat( @@ -169,6 +190,7 @@ where } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn statistic_set_get(r: ExternRef>, stat: Statistic) -> i64; fn statistic_set_set(r: ExternRef>, stat: Statistic, value: i64); diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/turn_choices.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/turn_choices.rs index 522f8b7..f5a1e3c 100644 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/turn_choices.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/turn_choices.rs @@ -1,7 +1,10 @@ use crate::app_interface::{LearnedMove, Pokemon}; use crate::handling::cached_value::CachedValue; use crate::handling::temporary::Temporary; -use crate::{cached_value, wasm_value_getters, ExternRef, ExternalReferenceType, Script}; +use crate::ExternRef; +#[cfg(not(feature = "mock_data"))] +use crate::{cached_value, wasm_value_getters, ExternalReferenceType, Script}; +#[cfg(not(feature = "mock_data"))] use alloc::boxed::Box; use alloc::rc::Rc; @@ -47,14 +50,17 @@ impl TurnChoice { self.base().user.value() } + #[cfg(not(feature = "mock_data"))] pub fn speed(&self) -> u32 { unsafe { turn_choice_get_speed(self.base().reference) } } + #[cfg(not(feature = "mock_data"))] pub fn has_failed(&self) -> bool { unsafe { turn_choice_has_failed(self.base().reference) } } + #[cfg(not(feature = "mock_data"))] pub fn fail(&self) { unsafe { turn_choice_fail(self.base().reference) } } @@ -70,15 +76,18 @@ impl MoveTurnChoiceData { pub fn target_index(&self) -> u8 { self.temp.value().inner.target_index.value() } + #[cfg(not(feature = "mock_data"))] pub fn priority(&self) -> i8 { unsafe { turn_choice_move_priority(self.temp.value().inner.base.reference.cast()) } } + #[cfg(not(feature = "mock_data"))] pub fn move_script(&self) -> Option<&Box> { unsafe { turn_choice_move_script(self.temp.value().inner.base.reference.cast()).as_ref() } } } +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for TurnChoice { fn from_extern_value(reference: ExternRef) -> Self { let kind = unsafe { turn_choice_get_kind(reference) }; @@ -91,6 +100,7 @@ impl ExternalReferenceType for TurnChoice { } } +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for MoveTurnChoiceDataTemporary { fn from_extern_value(reference: ExternRef) -> Self { Self { @@ -113,6 +123,7 @@ impl ExternalReferenceType for MoveTurnChoiceDataTemporary { } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn turn_choice_get_kind(r: ExternRef) -> u8; fn turn_choice_get_user(r: ExternRef) -> ExternRef; @@ -128,6 +139,7 @@ extern "wasm" { } #[no_mangle] +#[cfg(not(feature = "mock_data"))] unsafe extern "wasm" fn turn_choice_mark_deleted(r: ExternRef, kind: u8) { match kind { 0 => Temporary::::mark_as_deleted(r.cast()), diff --git a/pkmn_lib_interface/src/app_interface/list.rs b/pkmn_lib_interface/src/app_interface/list.rs index 54fd971..3bd6e87 100644 --- a/pkmn_lib_interface/src/app_interface/list.rs +++ b/pkmn_lib_interface/src/app_interface/list.rs @@ -1,9 +1,11 @@ use crate::{ExternalReferenceType, VecExternRef}; use alloc::boxed::Box; use alloc::collections::BTreeMap; +use alloc::rc::Rc; use alloc::vec::Vec; use core::marker::PhantomData; +#[cfg(not(feature = "mock_data"))] struct ImmutableListInner { extern_ref: VecExternRef, resource_type: PhantomData, @@ -11,6 +13,7 @@ struct ImmutableListInner { } #[derive(Clone)] +#[cfg(not(feature = "mock_data"))] pub struct ImmutableList where T: Clone, @@ -19,6 +22,7 @@ where inner: *const ImmutableListInner, } +#[cfg(not(feature = "mock_data"))] impl ImmutableList where T: Clone, @@ -71,4 +75,31 @@ where } } +#[cfg(feature = "mock_data")] +pub struct ImmutableListInner { + values: Vec, +} + +#[cfg(feature = "mock_data")] +#[derive(Clone)] +pub struct ImmutableList { + inner: Rc>, +} + +#[cfg(feature = "mock_data")] +impl ImmutableList +where + T: Clone, +{ + pub fn mock(values: Vec) -> Self { + Self { + inner: Rc::new(ImmutableListInner { values }), + } + } + + pub fn get(&self, index: u32) -> Option { + self.inner.values.get(index as usize).cloned() + } +} + static mut CACHE: BTreeMap = BTreeMap::new(); diff --git a/pkmn_lib_interface/src/app_interface/mod.rs b/pkmn_lib_interface/src/app_interface/mod.rs index 9f386cd..9106659 100644 --- a/pkmn_lib_interface/src/app_interface/mod.rs +++ b/pkmn_lib_interface/src/app_interface/mod.rs @@ -5,5 +5,5 @@ pub mod string_key; pub use dynamic_data::*; pub use static_data::*; -pub use string_key::get_hash; +pub use string_key::get_hash_const; pub use string_key::StringKey; diff --git a/pkmn_lib_interface/src/app_interface/static_data/ability.rs b/pkmn_lib_interface/src/app_interface/static_data/ability.rs index 85db3ce..3b6baa2 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/ability.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/ability.rs @@ -19,6 +19,7 @@ pub struct Ability { } impl Ability { + #[cfg(not(feature = "mock_data"))] pub fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(AbilityInner { @@ -38,6 +39,7 @@ impl Ability { } } +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for Ability { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) @@ -53,6 +55,7 @@ pub struct AbilityIndex { pub index: u8, } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn ability_get_name(r: ExternRef) -> ExternRef; fn ability_get_effect(r: ExternRef) -> ExternRef; diff --git a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/item_library.rs b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/item_library.rs index 3566e33..da4eb91 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/item_library.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/item_library.rs @@ -15,6 +15,7 @@ pub struct ItemLibrary { } impl ItemLibrary { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(ptr: ExternRef) -> Self { Self { inner: Rc::new(ItemLibraryInner { @@ -34,10 +35,12 @@ impl DataLibrary for ItemLibrary { self.inner.ptr } + #[cfg(not(feature = "mock_data"))] fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> ExternRef { unsafe { move_library_get_move(ptr, name) } } + #[cfg(not(feature = "mock_data"))] fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> ExternRef { unsafe { move_library_get_move_by_hash(ptr, hash) } } @@ -45,12 +48,14 @@ impl DataLibrary for ItemLibrary { crate::handling::cacheable::cacheable!(ItemLibrary); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for ItemLibrary { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn move_library_get_move( ptr: ExternRef, @@ -58,3 +63,15 @@ extern "wasm" { ) -> ExternRef; fn move_library_get_move_by_hash(ptr: ExternRef, hash: u32) -> ExternRef; } + +#[cfg(feature = "mock_data")] +impl ItemLibrary { + pub fn mock() -> Self { + Self { + inner: Rc::new(ItemLibraryInner { + ptr: ExternRef::mock(), + cache: Default::default(), + }), + } + } +} diff --git a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/mod.rs b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/mod.rs index 6aa6f3f..94c8791 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/mod.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/mod.rs @@ -23,6 +23,7 @@ struct StaticDataInner { item_library: CachedValue, species_library: CachedValue, type_library: CachedValue, + settings: CachedValue, } #[derive(Clone)] @@ -31,6 +32,7 @@ pub struct StaticData { } impl StaticData { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(StaticDataInner { @@ -53,6 +55,26 @@ impl StaticData { }) } + #[cfg(feature = "mock_data")] + pub fn mock( + moves: MoveLibrary, + items: ItemLibrary, + species: SpeciesLibrary, + types: TypeLibrary, + settings: LibrarySettings, + ) -> Self { + Self { + inner: Rc::new(StaticDataInner { + reference: ExternRef::mock(), + move_library: moves.into(), + item_library: items.into(), + species_library: species.into(), + type_library: types.into(), + settings: settings.into(), + }), + } + } + cached_value_getters! { pub fn move_library(&self) -> MoveLibrary; pub fn item_library(&self) -> ItemLibrary; @@ -63,9 +85,10 @@ impl StaticData { crate::handling::cacheable::cacheable!(StaticData); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for StaticData { fn from_extern_value(reference: ExternRef) -> Self { - StaticData::new(reference) + StaticData::mock(reference) } } @@ -79,6 +102,7 @@ pub struct LibrarySettings { } impl LibrarySettings { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(ptr: ExternRef) -> Self { Self { inner: Rc::new(LibrarySettingsInner { @@ -87,11 +111,21 @@ impl LibrarySettings { } } + #[cfg(feature = "mock_data")] + pub fn mock(maximum_level: LevelInt) -> Self { + Self { + inner: Rc::new(LibrarySettingsInner { + maximum_level: maximum_level.into(), + }), + } + } + cached_value_getters! { pub fn maximum_level(&self) -> LevelInt; } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn static_data_get_move_library(ptr: ExternRef) -> ExternRef; fn static_data_get_item_library(ptr: ExternRef) -> ExternRef; @@ -101,6 +135,7 @@ extern "wasm" { fn library_settings_get_maximum_level(ptr: ExternRef) -> LevelInt; } +#[cfg(not(feature = "mock_data"))] pub trait DataLibrary: Cacheable where T: ExternalReferenceType, @@ -147,3 +182,32 @@ where v } } + +#[cfg(feature = "mock_data")] +pub trait DataLibrary: Cacheable +where + T: Clone, +{ + fn get_cache(&self) -> &RwLock>; + fn get_self_ref(&self) -> ExternRef + where + Self: Sized; + + fn get(&self, name: &StringKey) -> Option + where + Self: Sized, + { + self.get_cache().read().get(&name.hash()).cloned() + } + + fn get_by_hash(&self, hash: u32) -> Option + where + Self: Sized, + { + self.get_cache().read().get(&hash).cloned() + } + + fn insert(&self, hash: u32, item: T) { + self.get_cache().write().insert(hash, item); + } +} diff --git a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/move_library.rs b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/move_library.rs index 4f5f159..1b2265d 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/move_library.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/move_library.rs @@ -16,6 +16,7 @@ pub struct MoveLibrary { } impl MoveLibrary { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(ptr: ExternRef) -> Self { Self { inner: Rc::new(MoveLibraryInner { @@ -24,6 +25,16 @@ impl MoveLibrary { }), } } + + #[cfg(feature = "mock_data")] + pub fn mock() -> Self { + Self { + inner: Rc::new(MoveLibraryInner { + ptr: ExternRef::mock(), + cache: Default::default(), + }), + } + } } impl DataLibrary for MoveLibrary { @@ -35,10 +46,12 @@ impl DataLibrary for MoveLibrary { self.inner.ptr } + #[cfg(not(feature = "mock_data"))] fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> ExternRef { unsafe { move_library_get_move(ptr, name) } } + #[cfg(not(feature = "mock_data"))] fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> ExternRef { unsafe { move_library_get_move_by_hash(ptr, hash) } } @@ -46,12 +59,14 @@ impl DataLibrary for MoveLibrary { crate::handling::cacheable::cacheable!(MoveLibrary); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for MoveLibrary { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn move_library_get_move( ptr: ExternRef, diff --git a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/species_library.rs b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/species_library.rs index 4bd9b9f..f347099 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/species_library.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/species_library.rs @@ -15,7 +15,8 @@ pub struct SpeciesLibrary { } impl SpeciesLibrary { - pub(crate) fn new(ptr: ExternRef) -> Self { + #[cfg(not(feature = "mock_data"))] + pub fn new(ptr: ExternRef) -> Self { Self { inner: Rc::new(SpeciesLibraryInner { ptr, @@ -23,6 +24,16 @@ impl SpeciesLibrary { }), } } + + #[cfg(feature = "mock_data")] + pub fn mock() -> Self { + Self { + inner: Rc::new(SpeciesLibraryInner { + ptr: ExternRef::mock(), + cache: Default::default(), + }), + } + } } impl DataLibrary for SpeciesLibrary { @@ -34,10 +45,12 @@ impl DataLibrary for SpeciesLibrary { self.inner.ptr } + #[cfg(not(feature = "mock_data"))] fn _get_ref_by_name(ptr: ExternRef, name: ExternRef) -> ExternRef { unsafe { species_library_get_species(ptr, name) } } + #[cfg(not(feature = "mock_data"))] fn _get_ref_by_hash(ptr: ExternRef, hash: u32) -> ExternRef { unsafe { species_library_get_species_by_hash(ptr, hash) } } @@ -45,12 +58,14 @@ impl DataLibrary for SpeciesLibrary { crate::handling::cacheable::cacheable!(SpeciesLibrary); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for SpeciesLibrary { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn species_library_get_species( ptr: ExternRef, diff --git a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/type_library.rs b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/type_library.rs index fe07f01..807f37d 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/data_libraries/type_library.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/data_libraries/type_library.rs @@ -17,6 +17,7 @@ pub struct TypeLibrary { } impl TypeLibrary { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(reference: ExternRef) -> Self { Self { inner: Rc::new(TypeLibraryInner { @@ -26,7 +27,18 @@ impl TypeLibrary { }), } } + #[cfg(feature = "mock_data")] + pub fn mock() -> Self { + Self { + inner: Rc::new(TypeLibraryInner { + reference: ExternRef::mock(), + name_to_type_cache: Default::default(), + effectiveness_cache: Default::default(), + }), + } + } + #[cfg(not(feature = "mock_data"))] pub fn get_type_from_name(&self, name: &str) -> Option { if let Some(cached) = self.inner.name_to_type_cache.read().get(name) { return Some(*cached); @@ -43,6 +55,7 @@ impl TypeLibrary { Some(v) } + #[cfg(not(feature = "mock_data"))] pub fn get_single_effectiveness(&self, attacking_type: u8, defending_type: u8) -> f32 { if let Some(cached) = self .inner @@ -66,6 +79,7 @@ impl TypeLibrary { effectiveness } + #[cfg(not(feature = "mock_data"))] pub fn get_effectiveness(&self, attacking_type: u8, defending_types: &[u8]) -> f32 { let mut f = 1.0; for defending_type in defending_types { @@ -77,12 +91,14 @@ impl TypeLibrary { crate::handling::cacheable::cacheable!(TypeLibrary); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for TypeLibrary { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn type_library_get_single_effectiveness( r: ExternRef, diff --git a/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs b/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs index 56aa841..6e1b65d 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs @@ -21,7 +21,8 @@ pub enum EffectParameter { } impl EffectParameter { - pub(crate) fn create(ptr: ExternRef) -> Self { + #[cfg(not(feature = "mock_data"))] + pub(crate) fn new(ptr: ExternRef) -> Self { unsafe { match effect_parameter_get_type(ptr) { EffectParameterType::None => Self::None, @@ -36,12 +37,13 @@ impl EffectParameter { } } +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for EffectParameter { fn from_extern_value(reference: ExternRef) -> Self where Self: Sized, { - EffectParameter::create(reference) + EffectParameter::new(reference) } } @@ -59,6 +61,7 @@ impl Display for EffectParameter { } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn effect_parameter_get_type(ptr: ExternRef) -> EffectParameterType; fn effect_parameter_as_bool(ptr: ExternRef) -> bool; diff --git a/pkmn_lib_interface/src/app_interface/static_data/item.rs b/pkmn_lib_interface/src/app_interface/static_data/item.rs index 2d782a4..d76c904 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/item.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/item.rs @@ -56,6 +56,7 @@ pub struct Item { } impl Item { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(ItemInner { @@ -68,6 +69,7 @@ impl Item { }) } + #[cfg(not(feature = "mock_data"))] pub(crate) fn reference(&self) -> ExternRef { self.inner.reference } @@ -83,6 +85,7 @@ impl Item { pub fn price(&self) -> i32; } + #[cfg(not(feature = "mock_data"))] pub fn has_flag(&self, flag: &StringKey) -> bool { unsafe { item_has_flag(self.inner.reference, flag.ptr()) } } @@ -90,12 +93,14 @@ impl Item { crate::handling::cacheable::cacheable!(Item); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for Item { fn from_extern_value(reference: ExternRef) -> Self { - Item::new(reference) + Item::mock(reference) } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn item_get_name(ptr: ExternRef) -> ExternRef; fn item_get_category(ptr: ExternRef) -> ItemCategory; @@ -103,3 +108,30 @@ extern "wasm" { fn item_get_price(ptr: ExternRef) -> i32; fn item_has_flag(ptr: ExternRef, flag: ExternRef) -> bool; } + +#[cfg(feature = "mock_data")] +mod test { + use super::Item; + use super::ItemInner; + use crate::app_interface::{BattleItemCategory, ItemCategory}; + use crate::{cached_value, ExternRef, StringKey}; + use alloc::rc::Rc; + + impl Item { + pub fn mock() -> Self { + Self { + inner: Rc::new(ItemInner { + reference: ExternRef::mock(), + name: StringKey::new("test").into(), + category: ItemCategory::MiscItem.into(), + battle_category: BattleItemCategory::None.into(), + price: 0.into(), + }), + } + } + + pub fn has_flag(&self) -> bool { + unimplemented!() + } + } +} diff --git a/pkmn_lib_interface/src/app_interface/static_data/move_data.rs b/pkmn_lib_interface/src/app_interface/static_data/move_data.rs index 8bd79f6..d153cd8 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/move_data.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/move_data.rs @@ -1,4 +1,4 @@ -use crate::app_interface::{get_hash, StringKey}; +use crate::app_interface::{get_hash_const, StringKey}; use crate::handling::cached_value::CachedValue; use crate::handling::Cacheable; use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType}; @@ -50,6 +50,7 @@ pub struct MoveData { } impl MoveData { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(ptr: ExternRef) -> Self { MoveData::from_ref(ptr, &|ptr| Self { inner: Rc::new(MoveDataInner { @@ -65,6 +66,31 @@ impl MoveData { }), }) } + #[cfg(feature = "mock_data")] + pub fn mock( + name: &str, + move_type: u8, + category: MoveCategory, + base_power: u8, + accuracy: u8, + base_usages: u8, + target: MoveTarget, + priority: i8, + ) -> Self { + Self { + inner: Rc::new(MoveDataInner { + ptr: ExternRef::mock(), + name: StringKey::new(name).into(), + move_type: move_type.into(), + category: category.into(), + base_power: base_power.into(), + accuracy: accuracy.into(), + base_usages: base_usages.into(), + target: target.into(), + priority: priority.into(), + }), + } + } cached_value_getters! { pub fn name(&self) -> StringKey; @@ -76,12 +102,15 @@ impl MoveData { pub fn target(&self) -> MoveTarget; pub fn priority(&self) -> i8; } + + #[cfg(not(feature = "mock_data"))] pub fn has_flag(&self, flag: &[u8; N]) -> bool { - let hash = get_hash(flag); + let hash = get_hash_const(flag); unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash) } } } +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for MoveData { fn from_extern_value(reference: ExternRef) -> Self { MoveData::new(reference) @@ -90,6 +119,7 @@ impl ExternalReferenceType for MoveData { crate::handling::cacheable::cacheable!(MoveData); +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn move_data_get_name(ptr: ExternRef) -> ExternRef; fn move_data_get_type(ptr: ExternRef) -> u8; diff --git a/pkmn_lib_interface/src/app_interface/static_data/nature.rs b/pkmn_lib_interface/src/app_interface/static_data/nature.rs index d1392d1..a2a6449 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/nature.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/nature.rs @@ -23,6 +23,7 @@ pub struct Nature { crate::handling::cacheable::cacheable!(Nature); impl Nature { + #[cfg(not(feature = "mock_data"))] pub fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| unsafe { Self { @@ -38,12 +39,14 @@ impl Nature { } } +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for Nature { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn nature_get_increase_stat(r: ExternRef) -> Statistic; fn nature_get_decrease_stat(r: ExternRef) -> Statistic; diff --git a/pkmn_lib_interface/src/app_interface/static_data/species.rs b/pkmn_lib_interface/src/app_interface/static_data/species.rs index f7168f6..d095c6e 100644 --- a/pkmn_lib_interface/src/app_interface/static_data/species.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/species.rs @@ -1,4 +1,4 @@ -use crate::app_interface::get_hash; +use crate::app_interface::get_hash_const; use crate::handling::cached_value::CachedValue; use crate::handling::Cacheable; use crate::{ @@ -49,6 +49,7 @@ pub struct ImmutableStatisticSet { } impl ImmutableStatisticSet { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(ImmutableStatisticSetInner { @@ -106,6 +107,7 @@ pub struct Form { } impl Form { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(reference: ExternRef) -> Self { Self::from_ref(reference, &|reference| Self { inner: Rc::new(FormInner { @@ -144,8 +146,9 @@ impl Form { self.inner.types.value_ref() } + #[cfg(not(feature = "mock_data"))] pub fn has_flag(&self, flag: &[u8; N]) -> bool { - let hash = get_hash(flag); + let hash = get_hash_const(flag); unsafe { form_has_flag_by_hash(self.inner.reference, hash) } } } @@ -166,6 +169,7 @@ pub struct Species { } impl Species { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(reference: ExternRef) -> Self { Self { inner: Rc::new(SpeciesInner { @@ -200,8 +204,9 @@ impl Species { pub fn capture_rate(&self) -> u8; } + #[cfg(not(feature = "mock_data"))] pub fn get_form(&self, form_name: &[u8; N]) -> Option
{ - let hash = get_hash(form_name); + let hash = get_hash_const(form_name); unsafe { if let Some(v) = self.inner.forms.read().get(&hash) { v.clone() @@ -214,24 +219,28 @@ impl Species { } } + #[cfg(not(feature = "mock_data"))] pub fn has_flag(&self, flag: &[u8; N]) -> bool { - let hash = get_hash(flag); + let hash = get_hash_const(flag); unsafe { species_has_flag_by_hash(self.inner.reference, hash) } } } +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for ImmutableStatisticSet { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for Form { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) } } +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for Species { fn from_extern_value(reference: ExternRef) -> Self { Self::new(reference) @@ -242,6 +251,7 @@ crate::handling::cacheable::cacheable!(ImmutableStatisticSet); crate::handling::cacheable::cacheable!(Form); crate::handling::cacheable::cacheable!(Species); +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn static_statistics_set_get_hp(r: ExternRef) -> u16; fn static_statistics_set_get_attack(r: ExternRef) -> u16; diff --git a/pkmn_lib_interface/src/app_interface/string_key.rs b/pkmn_lib_interface/src/app_interface/string_key.rs index 223a5e4..9cb84a6 100644 --- a/pkmn_lib_interface/src/app_interface/string_key.rs +++ b/pkmn_lib_interface/src/app_interface/string_key.rs @@ -17,6 +17,7 @@ pub struct StringKey { } impl StringKey { + #[cfg(not(feature = "mock_data"))] pub(crate) fn new(ptr: ExternRef) -> Self { StringKey::from_ref(ptr, &|ptr| -> StringKey { StringKey { @@ -29,10 +30,12 @@ impl StringKey { }) } + #[cfg(not(feature = "mock_data"))] pub(super) fn ptr(&self) -> ExternRef { self.data.ptr } + #[cfg(not(feature = "mock_data"))] pub fn str(&self) -> &CString { if self.data.str.borrow().is_none() { unsafe { @@ -43,6 +46,13 @@ impl StringKey { } unsafe { (*self.data.str.as_ptr()).as_ref().unwrap() } } + + #[cfg(feature = "mock_data")] + pub fn str(&self) -> &CString { + unsafe { (*self.data.str.as_ptr()).as_ref().unwrap() } + } + + #[cfg(not(feature = "mock_data"))] pub fn hash(&self) -> u32 { if self.data.hash.borrow().is_none() { unsafe { @@ -53,10 +63,16 @@ impl StringKey { } self.data.hash.borrow().unwrap() } + + #[cfg(feature = "mock_data")] + pub fn hash(&self) -> u32 { + self.data.hash.borrow().unwrap() + } } crate::handling::cacheable::cacheable!(StringKey); +#[cfg(not(feature = "mock_data"))] impl ExternalReferenceType for StringKey { fn from_extern_value(reference: ExternRef) -> Self { StringKey::new(reference) @@ -70,6 +86,7 @@ impl Display for StringKey { } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn string_key_get_str(ptr: ExternRef) -> *mut c_char; fn string_key_get_hash(ptr: ExternRef) -> u32; @@ -117,7 +134,7 @@ const fn to_lower(c: u8) -> u8 { c } -pub const fn get_hash(s: &[u8; N]) -> u32 { +pub const fn get_hash_const(s: &[u8; N]) -> u32 { let mut crc: u32 = 0xffffffff; let mut i: usize = 0; @@ -127,3 +144,37 @@ pub const fn get_hash(s: &[u8; N]) -> u32 { } crc ^ 0xffffffff } + +pub const fn get_hash(s: &[u8]) -> u32 { + let mut crc: u32 = 0xffffffff; + + let mut i: usize = 0; + while i < s.len() { + crc = (crc >> 8) ^ CRC_TABLE[((crc ^ (to_lower(s[i]) as u32)) & 0xff) as usize]; + i += 1; + } + crc ^ 0xffffffff +} + +#[cfg(feature = "mock_data")] +mod test { + use super::get_hash; + use super::StringKeyInner; + use crate::{ExternRef, StringKey}; + use alloc::rc::Rc; + use core::cell::RefCell; + use cstr_core::CString; + + impl StringKey { + pub fn new(s: &str) -> Self { + let hash = get_hash(s.as_bytes()); + Self { + data: Rc::new(StringKeyInner { + ptr: ExternRef::mock(), + str: RefCell::new(Some(CString::new(s).unwrap())), + hash: RefCell::new(Some(hash)), + }), + } + } + } +} diff --git a/pkmn_lib_interface/src/handling/cacheable.rs b/pkmn_lib_interface/src/handling/cacheable.rs index 8edd186..3ac0b23 100644 --- a/pkmn_lib_interface/src/handling/cacheable.rs +++ b/pkmn_lib_interface/src/handling/cacheable.rs @@ -1,11 +1,15 @@ +#[cfg(not(feature = "mock_data"))] use crate::ExternRef; +#[cfg(not(feature = "mock_data"))] use alloc::collections::BTreeMap; pub trait Cacheable { + #[cfg(not(feature = "mock_data"))] fn get_cache<'a>() -> &'a mut BTreeMap, Self> where Self: Sized; + #[cfg(not(feature = "mock_data"))] fn from_ref(ptr: ExternRef, ctor: &dyn Fn(ExternRef) -> Self) -> Self where Self: Sized, @@ -23,9 +27,11 @@ pub trait Cacheable { macro_rules! cacheable { ($type: ty) => { paste::paste!{ + #[cfg(not(feature = "mock_data"))] static mut [<$type:upper _CACHE>]: alloc::collections::BTreeMap, $type> = alloc::collections::BTreeMap::new(); impl crate::handling::Cacheable for $type { + #[cfg(not(feature = "mock_data"))] fn get_cache<'a>() -> &'a mut alloc::collections::BTreeMap, $type> { unsafe { &mut [<$type:upper _CACHE>] } } diff --git a/pkmn_lib_interface/src/handling/cached_value.rs b/pkmn_lib_interface/src/handling/cached_value.rs index 8af5823..9a6f52e 100644 --- a/pkmn_lib_interface/src/handling/cached_value.rs +++ b/pkmn_lib_interface/src/handling/cached_value.rs @@ -1,10 +1,12 @@ use alloc::boxed::Box; +#[cfg(not(feature = "mock_data"))] pub struct CachedValue { init_fn: Box T>, value: Option, } +#[cfg(not(feature = "mock_data"))] impl CachedValue { pub fn new(init_fn: Box T>) -> Self { Self { @@ -39,6 +41,37 @@ impl CachedValue { } } +#[cfg(feature = "mock_data")] +pub struct CachedValue { + value: T, +} +#[cfg(feature = "mock_data")] +impl CachedValue { + pub fn new(value: T) -> Self { + Self { value } + } + + #[inline] + pub fn value(&self) -> T + where + T: Clone, + { + self.value.clone() + } + + #[inline] + pub fn value_ref(&self) -> &T { + &self.value + } +} + +#[cfg(feature = "mock_data")] +impl From for CachedValue { + fn from(value: T) -> Self { + Self::new(value) + } +} + #[macro_export] macro_rules! cached_value { ($init: block) => { diff --git a/pkmn_lib_interface/src/handling/extern_ref.rs b/pkmn_lib_interface/src/handling/extern_ref.rs index 213bece..43d5aae 100644 --- a/pkmn_lib_interface/src/handling/extern_ref.rs +++ b/pkmn_lib_interface/src/handling/extern_ref.rs @@ -35,6 +35,14 @@ impl ExternRef { resource_type: Default::default(), } } + + #[cfg(feature = "mock_data")] + pub(crate) fn mock() -> Self { + Self { + p: 0, + resource_type: Default::default(), + } + } } impl Clone for ExternRef { @@ -89,6 +97,7 @@ impl VecExternRef { v.1 } + #[cfg(not(feature = "mock_data"))] pub(crate) fn at(&self, index: u32) -> ExternRef { let p = unsafe { _vec_extern_ref_get_value(self.get_internal_index(), index) }; ExternRef { @@ -97,6 +106,7 @@ impl VecExternRef { } } + #[cfg(not(feature = "mock_data"))] pub(crate) fn get_immutable_list(&self) -> ImmutableList where T: Clone, @@ -168,6 +178,7 @@ macro_rules! impl_extern_ctor { }; } +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn _vec_extern_ref_get_value(extern_ref: u32, index: u32) -> u32; } diff --git a/pkmn_lib_interface/src/handling/ffi_array.rs b/pkmn_lib_interface/src/handling/ffi_array.rs index 5d487e0..fe069d7 100644 --- a/pkmn_lib_interface/src/handling/ffi_array.rs +++ b/pkmn_lib_interface/src/handling/ffi_array.rs @@ -34,6 +34,7 @@ impl FFIArray { } #[no_mangle] +#[cfg(not(feature = "mock_data"))] extern "wasm" fn delete_ffi_array(a: FFIArray) { a.delete() } diff --git a/pkmn_lib_interface/src/handling/mod.rs b/pkmn_lib_interface/src/handling/mod.rs index d82784b..b22b94f 100644 --- a/pkmn_lib_interface/src/handling/mod.rs +++ b/pkmn_lib_interface/src/handling/mod.rs @@ -45,7 +45,8 @@ macro_rules! wasm_reference_getters { } - extern "wasm" { + #[cfg(not(feature = "mock_data"))] +extern "wasm" { $( paste::paste!{ fn [<$base_type:snake _get_ $name>](r: ExternRef<$base_type>) -> ExternRef<$type>; @@ -78,7 +79,8 @@ macro_rules! wasm_optional_reference_getters { } - extern "wasm" { + #[cfg(not(feature = "mock_data"))] +extern "wasm" { $( paste::paste!{ fn [<$base_type:snake get_ $name>](r: ExternRef<$base_type>) -> ExternRef<$type>; @@ -97,13 +99,14 @@ macro_rules! wasm_value_getters { $v:vis fn $name:ident(&self) -> $type:ty; )* ) => { + #[cfg(not(feature = "mock_data"))] impl $base_type { $( $(#[$attr])* $v fn $name(&self) -> $type { paste::paste!{ unsafe{ - [<$base_type:snake get_ $name>](self.inner.reference) + [<$base_type:snake _get_ $name>](self.inner.reference) } } } @@ -111,10 +114,11 @@ macro_rules! wasm_value_getters { } - extern "wasm" { +#[cfg(not(feature = "mock_data"))] +extern "wasm" { $( paste::paste!{ - fn [<$base_type:snake get_ $name>](r: ExternRef<$base_type>) -> $type; + fn [<$base_type:snake _get_ $name>](r: ExternRef<$base_type>) -> $type; } )* } diff --git a/pkmn_lib_interface/src/handling/script.rs b/pkmn_lib_interface/src/handling/script.rs index 5902e3e..ba4319b 100644 --- a/pkmn_lib_interface/src/handling/script.rs +++ b/pkmn_lib_interface/src/handling/script.rs @@ -34,6 +34,7 @@ pub trait OwnerGetter { } } +#[cfg(not(feature = "mock_data"))] extern "wasm" { pub fn get_script_owner(pointer: *const c_void) -> ExternRef; } diff --git a/pkmn_lib_interface/src/handling/temporary.rs b/pkmn_lib_interface/src/handling/temporary.rs index ca7c7c2..71e6f31 100644 --- a/pkmn_lib_interface/src/handling/temporary.rs +++ b/pkmn_lib_interface/src/handling/temporary.rs @@ -9,12 +9,16 @@ struct TemporaryData { value: T, } +#[cfg(not(feature = "mock_data"))] pub struct Temporary { value: *mut TemporaryData, } +#[cfg(not(feature = "mock_data"))] static mut TEMPORARIES: alloc::collections::BTreeMap = alloc::collections::BTreeMap::new(); + +#[cfg(not(feature = "mock_data"))] impl Temporary where T: ExternalReferenceType, @@ -75,6 +79,7 @@ where } } +#[cfg(not(feature = "mock_data"))] impl Clone for Temporary { fn clone(&self) -> Self { *unsafe { self.value.as_mut() }.unwrap().use_count.get_mut() += 1; @@ -82,6 +87,7 @@ impl Clone for Temporary { } } +#[cfg(not(feature = "mock_data"))] impl Drop for Temporary { fn drop(&mut self) { let data = unsafe { self.value.as_mut() }.unwrap(); @@ -92,3 +98,21 @@ impl Drop for Temporary { } } } + +#[cfg(feature = "mock_data")] +pub struct Temporary { + value: T, +} + +#[cfg(feature = "mock_data")] +impl Temporary { + #[inline] + pub fn value(&self) -> T { + self.value.clone() + } + + #[inline] + pub fn value_ref(&self) -> &T { + &self.value + } +} diff --git a/pkmn_lib_interface/src/lib.rs b/pkmn_lib_interface/src/lib.rs index 7b538c1..2e75b7d 100644 --- a/pkmn_lib_interface/src/lib.rs +++ b/pkmn_lib_interface/src/lib.rs @@ -12,7 +12,7 @@ #![feature(wasm_abi)] #![feature(thread_local)] #![feature(build_hasher_simple_hash_one)] -#![no_std] +#![cfg_attr(not(feature = "mock_data"), no_std)] #![allow(incomplete_features)] extern crate alloc; @@ -26,7 +26,9 @@ use crate::app_interface::list::ImmutableList; use crate::app_interface::{DynamicLibrary, EffectParameter, StringKey, TurnChoice}; pub(crate) use crate::handling::extern_ref::*; use crate::handling::ffi_array::FFIArray; -use crate::handling::{Script, ScriptCapabilities, ScriptCategory}; +#[cfg(not(feature = "mock_data"))] +use crate::handling::ScriptCapabilities; +use crate::handling::{Script, ScriptCategory}; use alloc::boxed::Box; #[macro_use] @@ -46,6 +48,7 @@ pub fn set_load_script_fn(f: LoadScriptFnType) { } #[no_mangle] +#[cfg(not(feature = "mock_data"))] extern "wasm" fn load_script(category: ScriptCategory, name: ExternRef) -> u32 { let name_c = StringKey::new(name); let boxed_script = unsafe { &LOAD_SCRIPT_FN }.as_ref().unwrap()(category, &name_c); @@ -57,6 +60,7 @@ extern "wasm" fn load_script(category: ScriptCategory, name: ExternRef) { // By turning it from a raw pointer back into a Box with from_raw, we give ownership back to rust. // This lets Rust do the cleanup. @@ -65,6 +69,7 @@ unsafe extern "wasm" fn destroy_script(script: *mut Box) { } #[no_mangle] +#[cfg(not(feature = "mock_data"))] unsafe extern "wasm" fn get_script_capabilities( script: *const Box, ) -> FFIArray { @@ -73,6 +78,7 @@ unsafe extern "wasm" fn get_script_capabilities( } #[no_mangle] +#[cfg(not(feature = "mock_data"))] unsafe extern "wasm" fn script_on_initialize( script: *const Box, library: ExternRef, @@ -88,6 +94,7 @@ unsafe extern "wasm" fn script_on_initialize( } #[no_mangle] +#[cfg(not(feature = "mock_data"))] unsafe extern "wasm" fn script_on_before_turn( script: *const Box, choice: ExternRef, diff --git a/pkmn_lib_interface/src/utils.rs b/pkmn_lib_interface/src/utils.rs index 9df7d26..66521b1 100644 --- a/pkmn_lib_interface/src/utils.rs +++ b/pkmn_lib_interface/src/utils.rs @@ -1,9 +1,11 @@ use alloc::alloc::alloc; use core::alloc::Layout; -#[cfg(not(test))] +#[cfg(not(feature = "mock_data"))] use core::panic::PanicInfo; -use cstr_core::c_char; +use cstr_core::{c_char, CStr, CString}; +#[cfg(not(feature = "mock_data"))] +#[cfg(not(feature = "mock_data"))] extern "wasm" { fn _print(s: *const u8, len: usize); fn _error( @@ -16,12 +18,20 @@ extern "wasm" { ); } +#[cfg(not(feature = "mock_data"))] pub fn print_raw(s: &[c_char]) { unsafe { _print(s.as_ptr(), s.len()); } } +#[cfg(feature = "mock_data")] +pub fn print_raw(s: &[u8]) { + unsafe { + println!("{}", CString::new(s).unwrap().into_string().unwrap()); + } +} + #[macro_export] macro_rules! println { ($($args:tt)*) => { pkmn_lib_interface::utils::print_raw(alloc::format!($($args)*).as_bytes()); } } @@ -37,6 +47,7 @@ macro_rules! dbg { #[panic_handler] #[no_mangle] +#[cfg(not(feature = "mock_data"))] #[cfg(not(test))] pub fn begin_panic_handler(panic_info: &PanicInfo<'_>) -> ! { let msg = panic_info.message().unwrap().as_str().unwrap(); @@ -64,12 +75,14 @@ pub fn begin_panic_handler(panic_info: &PanicInfo<'_>) -> ! { #[alloc_error_handler] #[no_mangle] +#[cfg(not(feature = "mock_data"))] #[cfg(not(test))] fn allocation_error_handler(layout: core::alloc::Layout) -> ! { panic!("memory allocation of {} bytes failed", layout.size()) } #[no_mangle] +#[cfg(not(feature = "mock_data"))] unsafe extern "wasm" fn allocate_mem(len: u32, align: u32) -> *mut u8 { alloc(Layout::from_size_align(len as usize, align as usize).unwrap()) }