Initial work on mocking so we can unit test.

This commit is contained in:
2022-08-17 18:05:38 +02:00
parent 45b16f415f
commit 98130706fb
39 changed files with 580 additions and 34 deletions

View File

@@ -21,6 +21,7 @@ pub struct Battle {
}
impl Battle {
#[cfg(not(feature = "mock_data"))]
pub fn new(reference: ExternRef<Battle>) -> Self {
Self::from_ref(reference, &|reference| Self {
inner: Rc::new(BattleInner {
@@ -39,6 +40,7 @@ impl Battle {
pub fn sides(&self) -> ImmutableList<BattleSide>;
}
#[cfg(not(feature = "mock_data"))]
pub fn get_pokemon(&self, side: u8, index: u8) -> Option<Pokemon> {
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 {
Self::new(reference)
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn battle_get_library(r: ExternRef<Battle>) -> ExternRef<DynamicLibrary>;
fn battle_get_parties(r: ExternRef<Battle>) -> VecExternRef<BattleParty>;

View File

@@ -15,6 +15,7 @@ pub struct BattleParty {
}
impl BattleParty {
#[cfg(not(feature = "mock_data"))]
pub fn new(reference: ExternRef<BattleParty>) -> 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 {
Self::new(reference)
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn battle_party_get_party(r: ExternRef<BattleParty>) -> ExternRef<Party>;
}

View File

@@ -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<BattleRandom>) -> i32;
fn battle_random_get_max(r: ExternRef<BattleRandom>, max: i32) -> i32;

View File

@@ -19,6 +19,7 @@ pub struct BattleSide {
}
impl BattleSide {
#[cfg(not(feature = "mock_data"))]
pub fn new(reference: ExternRef<Self>) -> 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<Pokemon> {
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 {
Self::new(reference)
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn battleside_get_side_index(r: ExternRef<BattleSide>) -> u8;
fn battleside_get_pokemon_per_side(r: ExternRef<BattleSide>) -> u8;

View File

@@ -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 {
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>) -> Self {
DynamicLibrary::new(reference)
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn dynamic_library_get_static_data(ptr: ExternRef<DynamicLibrary>) -> ExternRef<StaticData>;
}

View File

@@ -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 {
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 {
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<LearnedMove>) -> ExternRef<MoveData>;
fn learned_move_get_learn_method(r: ExternRef<LearnedMove>) -> MoveLearnMethod;

View File

@@ -11,6 +11,7 @@ impl Party {
Self { reference }
}
#[cfg(not(feature = "mock_data"))]
pub fn get_pokemon(&self, index: usize) -> Option<Pokemon> {
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<Party>, index: usize) -> ExternRef<Pokemon>;
}

View File

@@ -34,6 +34,7 @@ pub struct Pokemon {
}
impl Pokemon {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(reference: ExternRef<Self>) -> Self {
Self::from_ref(reference, &|reference| Self {
inner: Rc::new(PokemonInner {
@@ -69,33 +70,41 @@ impl Pokemon {
pub fn effort_values(&self) -> ClampedStatisticSet<u8>;
}
#[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<Item> {
unsafe { pokemon_set_held_item(self.inner.reference, item.reference()).get_value() }
}
#[cfg(not(feature = "mock_data"))]
pub fn remove_held_item(&self) -> Option<Item> {
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<LearnedMove> {
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<dyn Script>> {
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<Species>;
@@ -166,6 +185,7 @@ wasm_optional_reference_getters! {
pub fn battle(&self) -> Option<Battle>;
}
#[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 {
Self::new(reference)
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn pokemon_get_library(r: ExternRef<Pokemon>) -> ExternRef<DynamicLibrary>;
fn pokemon_get_flat_stats(r: ExternRef<Pokemon>) -> ExternRef<StatisticSet<u32>>;
@@ -234,3 +256,13 @@ extern "wasm" {
fn pokemon_damage(r: ExternRef<Pokemon>, damage: u32, source: DamageSource);
fn pokemon_heal(r: ExternRef<Pokemon>, 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!()
}
}

View File

@@ -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<StatisticSet<i64>>, stat: Statistic) -> i64;
fn statistic_set_set(r: ExternRef<StatisticSet<i64>>, stat: Statistic, value: i64);

View File

@@ -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<dyn Script>> {
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>) -> 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 {
Self {
@@ -113,6 +123,7 @@ impl ExternalReferenceType for MoveTurnChoiceDataTemporary {
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn turn_choice_get_kind(r: ExternRef<TurnChoice>) -> u8;
fn turn_choice_get_user(r: ExternRef<TurnChoice>) -> ExternRef<Pokemon>;
@@ -128,6 +139,7 @@ extern "wasm" {
}
#[no_mangle]
#[cfg(not(feature = "mock_data"))]
unsafe extern "wasm" fn turn_choice_mark_deleted(r: ExternRef<TurnChoice>, kind: u8) {
match kind {
0 => Temporary::<MoveTurnChoiceDataTemporary>::mark_as_deleted(r.cast()),

View File

@@ -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<T: Clone> {
extern_ref: VecExternRef<T>,
resource_type: PhantomData<T>,
@@ -11,6 +13,7 @@ struct ImmutableListInner<T: Clone> {
}
#[derive(Clone)]
#[cfg(not(feature = "mock_data"))]
pub struct ImmutableList<T>
where
T: Clone,
@@ -19,6 +22,7 @@ where
inner: *const ImmutableListInner<T>,
}
#[cfg(not(feature = "mock_data"))]
impl<T> ImmutableList<T>
where
T: Clone,
@@ -71,4 +75,31 @@ where
}
}
#[cfg(feature = "mock_data")]
pub struct ImmutableListInner<T> {
values: Vec<T>,
}
#[cfg(feature = "mock_data")]
#[derive(Clone)]
pub struct ImmutableList<T> {
inner: Rc<ImmutableListInner<T>>,
}
#[cfg(feature = "mock_data")]
impl<T> ImmutableList<T>
where
T: Clone,
{
pub fn mock(values: Vec<T>) -> Self {
Self {
inner: Rc::new(ImmutableListInner { values }),
}
}
pub fn get(&self, index: u32) -> Option<T> {
self.inner.values.get(index as usize).cloned()
}
}
static mut CACHE: BTreeMap<u32, *const u8> = BTreeMap::new();

View File

@@ -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;

View File

@@ -19,6 +19,7 @@ pub struct Ability {
}
impl Ability {
#[cfg(not(feature = "mock_data"))]
pub fn new(reference: ExternRef<Self>) -> 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 {
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<Ability>) -> ExternRef<StringKey>;
fn ability_get_effect(r: ExternRef<Ability>) -> ExternRef<StringKey>;

View File

@@ -15,6 +15,7 @@ pub struct ItemLibrary {
}
impl ItemLibrary {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(ptr: ExternRef<Self>) -> Self {
Self {
inner: Rc::new(ItemLibraryInner {
@@ -34,10 +35,12 @@ impl DataLibrary<Item> for ItemLibrary {
self.inner.ptr
}
#[cfg(not(feature = "mock_data"))]
fn _get_ref_by_name(ptr: ExternRef<Self>, name: ExternRef<StringKey>) -> ExternRef<Item> {
unsafe { move_library_get_move(ptr, name) }
}
#[cfg(not(feature = "mock_data"))]
fn _get_ref_by_hash(ptr: ExternRef<Self>, hash: u32) -> ExternRef<Item> {
unsafe { move_library_get_move_by_hash(ptr, hash) }
}
@@ -45,12 +48,14 @@ impl DataLibrary<Item> for ItemLibrary {
crate::handling::cacheable::cacheable!(ItemLibrary);
#[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for ItemLibrary {
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<ItemLibrary>,
@@ -58,3 +63,15 @@ extern "wasm" {
) -> ExternRef<Item>;
fn move_library_get_move_by_hash(ptr: ExternRef<ItemLibrary>, hash: u32) -> ExternRef<Item>;
}
#[cfg(feature = "mock_data")]
impl ItemLibrary {
pub fn mock() -> Self {
Self {
inner: Rc::new(ItemLibraryInner {
ptr: ExternRef::mock(),
cache: Default::default(),
}),
}
}
}

View File

@@ -23,6 +23,7 @@ struct StaticDataInner {
item_library: CachedValue<ItemLibrary>,
species_library: CachedValue<SpeciesLibrary>,
type_library: CachedValue<TypeLibrary>,
settings: CachedValue<LibrarySettings>,
}
#[derive(Clone)]
@@ -31,6 +32,7 @@ pub struct StaticData {
}
impl StaticData {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(reference: ExternRef<StaticData>) -> 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>) -> 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<LibrarySettings>) -> 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<StaticData>) -> ExternRef<MoveLibrary>;
fn static_data_get_item_library(ptr: ExternRef<StaticData>) -> ExternRef<ItemLibrary>;
@@ -101,6 +135,7 @@ extern "wasm" {
fn library_settings_get_maximum_level(ptr: ExternRef<LibrarySettings>) -> LevelInt;
}
#[cfg(not(feature = "mock_data"))]
pub trait DataLibrary<T>: Cacheable
where
T: ExternalReferenceType,
@@ -147,3 +182,32 @@ where
v
}
}
#[cfg(feature = "mock_data")]
pub trait DataLibrary<T>: Cacheable
where
T: Clone,
{
fn get_cache(&self) -> &RwLock<BTreeMap<u32, T>>;
fn get_self_ref(&self) -> ExternRef<Self>
where
Self: Sized;
fn get(&self, name: &StringKey) -> Option<T>
where
Self: Sized,
{
self.get_cache().read().get(&name.hash()).cloned()
}
fn get_by_hash(&self, hash: u32) -> Option<T>
where
Self: Sized,
{
self.get_cache().read().get(&hash).cloned()
}
fn insert(&self, hash: u32, item: T) {
self.get_cache().write().insert(hash, item);
}
}

View File

@@ -16,6 +16,7 @@ pub struct MoveLibrary {
}
impl MoveLibrary {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(ptr: ExternRef<Self>) -> 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<MoveData> for MoveLibrary {
@@ -35,10 +46,12 @@ impl DataLibrary<MoveData> for MoveLibrary {
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) }
}
@@ -46,12 +59,14 @@ impl DataLibrary<MoveData> for MoveLibrary {
crate::handling::cacheable::cacheable!(MoveLibrary);
#[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for MoveLibrary {
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<MoveLibrary>,

View File

@@ -15,7 +15,8 @@ pub struct SpeciesLibrary {
}
impl SpeciesLibrary {
pub(crate) fn new(ptr: ExternRef<SpeciesLibrary>) -> Self {
#[cfg(not(feature = "mock_data"))]
pub fn new(ptr: ExternRef<SpeciesLibrary>) -> 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<Species> for SpeciesLibrary {
@@ -34,10 +45,12 @@ impl DataLibrary<Species> for SpeciesLibrary {
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) }
}
@@ -45,12 +58,14 @@ impl DataLibrary<Species> for SpeciesLibrary {
crate::handling::cacheable::cacheable!(SpeciesLibrary);
#[cfg(not(feature = "mock_data"))]
impl ExternalReferenceType for SpeciesLibrary {
fn from_extern_value(reference: ExternRef<Self>) -> Self {
Self::new(reference)
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn species_library_get_species(
ptr: ExternRef<SpeciesLibrary>,

View File

@@ -17,6 +17,7 @@ pub struct TypeLibrary {
}
impl TypeLibrary {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(reference: ExternRef<Self>) -> 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<u8> {
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 {
Self::new(reference)
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn type_library_get_single_effectiveness(
r: ExternRef<TypeLibrary>,

View File

@@ -21,7 +21,8 @@ pub enum EffectParameter {
}
impl EffectParameter {
pub(crate) fn create(ptr: ExternRef<Self>) -> Self {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(ptr: ExternRef<Self>) -> 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>) -> 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<EffectParameter>) -> EffectParameterType;
fn effect_parameter_as_bool(ptr: ExternRef<EffectParameter>) -> bool;

View File

@@ -56,6 +56,7 @@ pub struct Item {
}
impl Item {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(reference: ExternRef<Self>) -> 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> {
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>) -> Self {
Item::new(reference)
Item::mock(reference)
}
}
#[cfg(not(feature = "mock_data"))]
extern "wasm" {
fn item_get_name(ptr: ExternRef<Item>) -> ExternRef<StringKey>;
fn item_get_category(ptr: ExternRef<Item>) -> ItemCategory;
@@ -103,3 +108,30 @@ extern "wasm" {
fn item_get_price(ptr: ExternRef<Item>) -> i32;
fn item_has_flag(ptr: ExternRef<Item>, flag: ExternRef<StringKey>) -> 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!()
}
}
}

View File

@@ -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>) -> 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<const N: usize>(&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>) -> 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<MoveData>) -> ExternRef<StringKey>;
fn move_data_get_type(ptr: ExternRef<MoveData>) -> u8;

View File

@@ -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 {
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 {
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;

View File

@@ -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 {
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 {
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<const N: usize>(&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<Species>) -> 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<const N: usize>(&self, form_name: &[u8; N]) -> Option<Form> {
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<const N: usize>(&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 {
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)
@@ -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<ImmutableStatisticSet>) -> u16;
fn static_statistics_set_get_attack(r: ExternRef<ImmutableStatisticSet>) -> u16;

View File

@@ -17,6 +17,7 @@ pub struct StringKey {
}
impl StringKey {
#[cfg(not(feature = "mock_data"))]
pub(crate) fn new(ptr: ExternRef<Self>) -> 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> {
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>) -> 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<StringKey>) -> *mut c_char;
fn string_key_get_hash(ptr: ExternRef<StringKey>) -> u32;
@@ -117,7 +134,7 @@ const fn to_lower(c: u8) -> u8 {
c
}
pub const fn get_hash<const N: usize>(s: &[u8; N]) -> u32 {
pub const fn get_hash_const<const N: usize>(s: &[u8; N]) -> u32 {
let mut crc: u32 = 0xffffffff;
let mut i: usize = 0;
@@ -127,3 +144,37 @@ pub const fn get_hash<const N: usize>(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)),
}),
}
}
}
}