Implements first few actual move effects.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use crate::app_interface::{BattleParty, BattleRandom, BattleSide, Pokemon};
|
||||
use crate::app_interface::{BattleParty, BattleRandom, BattleSide, ChoiceQueue, Pokemon};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{
|
||||
@@ -13,6 +13,7 @@ struct BattleInner {
|
||||
parties: CachedValue<ImmutableList<BattleParty>>,
|
||||
sides: CachedValue<ImmutableList<BattleSide>>,
|
||||
random: CachedValue<BattleRandom>,
|
||||
choice_queue: CachedValue<ChoiceQueue>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -30,6 +31,9 @@ impl Battle {
|
||||
parties: cached_value!({ battle_get_parties(reference).get_immutable_list() }),
|
||||
sides: cached_value!({ battle_get_sides(reference).get_immutable_list() }),
|
||||
random: cached_value!({ battle_get_random(reference).get_value().unwrap() }),
|
||||
choice_queue: cached_value!({
|
||||
battle_get_choice_queue(reference).get_value().unwrap()
|
||||
}),
|
||||
}),
|
||||
})
|
||||
}
|
||||
@@ -38,6 +42,8 @@ impl Battle {
|
||||
pub fn library(&self) -> DynamicLibrary;
|
||||
pub fn parties(&self) -> ImmutableList<BattleParty>;
|
||||
pub fn sides(&self) -> ImmutableList<BattleSide>;
|
||||
pub fn random(&self) -> BattleRandom;
|
||||
pub fn choice_queue(&self) -> ChoiceQueue;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
@@ -72,5 +78,6 @@ extern "wasm" {
|
||||
fn battle_get_parties(r: ExternRef<Battle>) -> VecExternRef<BattleParty>;
|
||||
fn battle_get_sides(r: ExternRef<Battle>) -> VecExternRef<BattleSide>;
|
||||
fn battle_get_random(r: ExternRef<Battle>) -> ExternRef<BattleRandom>;
|
||||
fn battle_get_choice_queue(r: ExternRef<Battle>) -> ExternRef<ChoiceQueue>;
|
||||
fn battle_get_pokemon(r: ExternRef<Battle>, side: u8, index: u8) -> ExternRef<Pokemon>;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ impl ExternalReferenceType for BattleParty {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
extern "wasm" {
|
||||
fn battle_party_get_party(r: ExternRef<BattleParty>) -> ExternRef<Party>;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
use crate::{ExternRef, ExternalReferenceType, Pokemon};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ChoiceQueue {
|
||||
reference: ExternRef<ChoiceQueue>,
|
||||
}
|
||||
|
||||
impl ChoiceQueue {
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn new(reference: ExternRef<ChoiceQueue>) -> Self {
|
||||
Self { reference }
|
||||
}
|
||||
|
||||
pub fn move_pokemon_choice_next(&self, pokemon: &Pokemon) -> bool {
|
||||
unsafe { choice_queue_move_pokemon_choice_next(self.reference, pokemon.reference()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
impl ExternalReferenceType for ChoiceQueue {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Self::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn choice_queue_move_pokemon_choice_next(
|
||||
r: ExternRef<ChoiceQueue>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> bool;
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
use crate::app_interface::{LearnedMove, MoveData, Pokemon};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::temporary::Temporary;
|
||||
use crate::{cached_value, ExternRef, ExternalReferenceType, Script};
|
||||
|
||||
struct ExecutingMoveInner {
|
||||
reference: ExternRef<ExecutingMove>,
|
||||
number_of_hits: CachedValue<u8>,
|
||||
user: CachedValue<Pokemon>,
|
||||
chosen_move: CachedValue<LearnedMove>,
|
||||
use_move: CachedValue<MoveData>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExecutingMove {
|
||||
inner: Temporary<ExecutingMoveInner>,
|
||||
}
|
||||
|
||||
impl ExecutingMove {
|
||||
pub(crate) fn new(reference: ExternRef<ExecutingMove>) -> Self {
|
||||
Self {
|
||||
inner: Temporary::new(
|
||||
reference.get_internal_index(),
|
||||
ExecutingMoveInner {
|
||||
reference,
|
||||
number_of_hits: cached_value!({ executing_move_get_number_of_hits(reference) }),
|
||||
user: cached_value!({
|
||||
executing_move_get_user(reference).get_value().unwrap()
|
||||
}),
|
||||
chosen_move: cached_value!({
|
||||
executing_move_get_chosen_move(reference)
|
||||
.get_value()
|
||||
.unwrap()
|
||||
}),
|
||||
use_move: cached_value!({
|
||||
executing_move_get_use_move(reference).get_value().unwrap()
|
||||
}),
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn number_of_hits(&self) -> u8 {
|
||||
self.inner.value().number_of_hits.value()
|
||||
}
|
||||
pub fn user(&self) -> Pokemon {
|
||||
self.inner.value().user.value()
|
||||
}
|
||||
pub fn chosen_move(&self) -> LearnedMove {
|
||||
self.inner.value().chosen_move.value()
|
||||
}
|
||||
pub fn use_move(&self) -> MoveData {
|
||||
self.inner.value().use_move.value()
|
||||
}
|
||||
pub fn move_script(&self) -> Option<&dyn Script> {
|
||||
unsafe { executing_move_get_script(self.inner.value().reference).as_ref() }
|
||||
}
|
||||
pub fn number_of_targets(&self) -> usize {
|
||||
unsafe { executing_move_get_number_of_targets(self.inner.value().reference) }
|
||||
}
|
||||
pub fn is_pokemon_target(&self, pokemon: &Pokemon) -> bool {
|
||||
unsafe {
|
||||
executing_move_is_pokemon_target(self.inner.value().reference, pokemon.reference())
|
||||
}
|
||||
}
|
||||
pub fn get_hit_data(&self, pokemon: &Pokemon, hit: u8) -> HitData {
|
||||
unsafe {
|
||||
executing_move_get_hit_data(self.inner.value().reference, pokemon.reference(), hit)
|
||||
.get_value()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HitData {
|
||||
reference: ExternRef<HitData>,
|
||||
}
|
||||
|
||||
impl HitData {
|
||||
pub fn is_critical(&self) -> bool {
|
||||
unsafe { hit_data_is_critical(self.reference) }
|
||||
}
|
||||
pub fn base_power(&self) -> u8 {
|
||||
unsafe { hit_data_get_base_power(self.reference) }
|
||||
}
|
||||
pub fn effectiveness(&self) -> f32 {
|
||||
unsafe { hit_data_get_effectiveness(self.reference) }
|
||||
}
|
||||
pub fn damage(&self) -> u32 {
|
||||
unsafe { hit_data_get_damage(self.reference) }
|
||||
}
|
||||
pub fn move_type(&self) -> u8 {
|
||||
unsafe { hit_data_get_move_type(self.reference) }
|
||||
}
|
||||
pub fn has_failed(&self) -> bool {
|
||||
unsafe { hit_data_is_critical(self.reference) }
|
||||
}
|
||||
|
||||
pub fn set_critical(&self, critical: bool) {
|
||||
unsafe { hit_data_set_critical(self.reference, critical) }
|
||||
}
|
||||
pub fn set_effectiveness(&self, effectiveness: f32) {
|
||||
unsafe { hit_data_set_effectiveness(self.reference, effectiveness) }
|
||||
}
|
||||
pub fn set_damage(&self, damage: u32) {
|
||||
unsafe { hit_data_set_damage(self.reference, damage) }
|
||||
}
|
||||
pub fn set_move_type(&self, move_type: u8) {
|
||||
unsafe { hit_data_set_move_type(self.reference, move_type) }
|
||||
}
|
||||
pub fn fail(&self) {
|
||||
unsafe { hit_data_fail(self.reference) }
|
||||
}
|
||||
}
|
||||
|
||||
impl ExternalReferenceType for ExecutingMove {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Self::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
impl ExternalReferenceType for HitData {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Self { reference }
|
||||
}
|
||||
}
|
||||
|
||||
extern "wasm" {
|
||||
fn executing_move_get_number_of_targets(r: ExternRef<ExecutingMove>) -> usize;
|
||||
fn executing_move_get_number_of_hits(r: ExternRef<ExecutingMove>) -> u8;
|
||||
fn executing_move_get_user(r: ExternRef<ExecutingMove>) -> ExternRef<Pokemon>;
|
||||
fn executing_move_get_chosen_move(r: ExternRef<ExecutingMove>) -> ExternRef<LearnedMove>;
|
||||
fn executing_move_get_use_move(r: ExternRef<ExecutingMove>) -> ExternRef<MoveData>;
|
||||
#[allow(improper_ctypes)]
|
||||
fn executing_move_get_script(r: ExternRef<ExecutingMove>) -> *const dyn Script;
|
||||
|
||||
fn executing_move_is_pokemon_target(
|
||||
r: ExternRef<ExecutingMove>,
|
||||
pokemon: ExternRef<Pokemon>,
|
||||
) -> bool;
|
||||
fn executing_move_get_hit_data(
|
||||
r: ExternRef<ExecutingMove>,
|
||||
target: ExternRef<Pokemon>,
|
||||
hit: u8,
|
||||
) -> ExternRef<HitData>;
|
||||
|
||||
fn hit_data_is_critical(r: ExternRef<HitData>) -> bool;
|
||||
fn hit_data_get_base_power(r: ExternRef<HitData>) -> u8;
|
||||
fn hit_data_get_effectiveness(r: ExternRef<HitData>) -> f32;
|
||||
fn hit_data_get_damage(r: ExternRef<HitData>) -> u32;
|
||||
fn hit_data_get_move_type(r: ExternRef<HitData>) -> u8;
|
||||
fn hit_data_has_failed(r: ExternRef<HitData>) -> bool;
|
||||
|
||||
fn hit_data_set_critical(r: ExternRef<HitData>, critical: bool);
|
||||
fn hit_data_set_base_power(r: ExternRef<HitData>, power: u8);
|
||||
fn hit_data_set_effectiveness(r: ExternRef<HitData>, effectiveness: f32);
|
||||
fn hit_data_set_damage(r: ExternRef<HitData>, damage: u32);
|
||||
fn hit_data_set_move_type(r: ExternRef<HitData>, move_type: u8);
|
||||
fn hit_data_fail(r: ExternRef<HitData>);
|
||||
}
|
||||
@@ -2,7 +2,9 @@ mod battle;
|
||||
mod battle_party;
|
||||
mod battle_random;
|
||||
mod battle_side;
|
||||
mod choice_queue;
|
||||
mod dynamic_library;
|
||||
mod executing_move;
|
||||
mod learned_move;
|
||||
mod party;
|
||||
mod pokemon;
|
||||
@@ -13,7 +15,9 @@ pub use battle::*;
|
||||
pub use battle_party::*;
|
||||
pub use battle_random::*;
|
||||
pub use battle_side::*;
|
||||
pub use choice_queue::*;
|
||||
pub use dynamic_library::DynamicLibrary;
|
||||
pub use executing_move::*;
|
||||
pub use learned_move::*;
|
||||
pub use party::*;
|
||||
pub use pokemon::*;
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{
|
||||
cached_value, cached_value_getters, wasm_optional_reference_getters, wasm_reference_getters,
|
||||
wasm_value_getters, DynamicLibrary, ExternRef, ExternalReferenceType, Script,
|
||||
wasm_value_getters, DynamicLibrary, ExternRef, ExternalReferenceType, Script, TypeIdentifier,
|
||||
};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::rc::Rc;
|
||||
@@ -61,6 +61,10 @@ impl Pokemon {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn reference(&self) -> ExternRef<Self> {
|
||||
self.inner.reference
|
||||
}
|
||||
|
||||
cached_value_getters! {
|
||||
pub fn library(&self) -> DynamicLibrary;
|
||||
pub fn flat_stats(&self) -> StatisticSet<u32>;
|
||||
@@ -101,8 +105,8 @@ impl Pokemon {
|
||||
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) }
|
||||
pub fn has_type(&self, type_identifier: TypeIdentifier) -> bool {
|
||||
unsafe { pokemon_has_type(self.inner.reference, type_identifier.into()) }
|
||||
}
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn has_type_by_name(&self, type_name: &str) -> bool {
|
||||
@@ -206,6 +210,12 @@ wasm_value_getters! {
|
||||
pub fn is_usable(&self) -> bool;
|
||||
}
|
||||
|
||||
impl PartialEq for Pokemon {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.inner.reference == other.inner.reference
|
||||
}
|
||||
}
|
||||
|
||||
/// A source of damage. This should be as unique as possible.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
@@ -246,6 +256,7 @@ extern "wasm" {
|
||||
diff_amount: i8,
|
||||
self_inflicted: bool,
|
||||
) -> bool;
|
||||
#[allow(improper_ctypes)]
|
||||
fn pokemon_get_ability_script(r: ExternRef<Pokemon>) -> *const Box<dyn Script>;
|
||||
fn pokemon_change_species(
|
||||
r: ExternRef<Pokemon>,
|
||||
|
||||
@@ -3,10 +3,9 @@ use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::temporary::Temporary;
|
||||
use crate::ExternRef;
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
use crate::{cached_value, wasm_value_getters, ExternalReferenceType, Script};
|
||||
use crate::{cached_value, ExternalReferenceType, Script};
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
use alloc::boxed::Box;
|
||||
use alloc::rc::Rc;
|
||||
|
||||
struct BaseTurnChoiceData {
|
||||
reference: ExternRef<TurnChoice>,
|
||||
@@ -19,12 +18,10 @@ struct MoveTurnChoiceDataInner {
|
||||
target_side: CachedValue<u8>,
|
||||
target_index: CachedValue<u8>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct MoveTurnChoiceDataTemporary {
|
||||
inner: Rc<MoveTurnChoiceDataInner>,
|
||||
}
|
||||
pub struct MoveTurnChoiceData {
|
||||
temp: Temporary<MoveTurnChoiceDataTemporary>,
|
||||
inner: Temporary<MoveTurnChoiceDataInner>,
|
||||
}
|
||||
|
||||
pub enum TurnChoice {
|
||||
@@ -38,7 +35,7 @@ pub enum TurnChoice {
|
||||
impl TurnChoice {
|
||||
fn base(&self) -> &BaseTurnChoiceData {
|
||||
match self {
|
||||
TurnChoice::Move(d) => &d.temp.value_ref().inner.base,
|
||||
TurnChoice::Move(d) => &d.inner.value_ref().base,
|
||||
TurnChoice::Item() => unimplemented!(),
|
||||
TurnChoice::Switch() => unimplemented!(),
|
||||
TurnChoice::Flee => unimplemented!(),
|
||||
@@ -68,22 +65,22 @@ impl TurnChoice {
|
||||
|
||||
impl MoveTurnChoiceData {
|
||||
pub fn used_move(&self) -> LearnedMove {
|
||||
self.temp.value().inner.used_move.value()
|
||||
self.inner.value().used_move.value()
|
||||
}
|
||||
pub fn target_side(&self) -> u8 {
|
||||
self.temp.value().inner.target_side.value()
|
||||
self.inner.value().target_side.value()
|
||||
}
|
||||
pub fn target_index(&self) -> u8 {
|
||||
self.temp.value().inner.target_index.value()
|
||||
self.inner.value().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()) }
|
||||
unsafe { turn_choice_move_priority(self.inner.value().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() }
|
||||
unsafe { turn_choice_move_script(self.inner.value().base.reference.cast()).as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +90,10 @@ impl ExternalReferenceType for TurnChoice {
|
||||
let kind = unsafe { turn_choice_get_kind(reference) };
|
||||
match kind {
|
||||
0 => TurnChoice::Move(MoveTurnChoiceData {
|
||||
temp: Temporary::from_reference(reference.cast()),
|
||||
inner: Temporary::new(
|
||||
reference.get_internal_index(),
|
||||
MoveTurnChoiceDataInner::from_reference(reference.cast()),
|
||||
),
|
||||
}),
|
||||
_ => panic!("Unknown turn choice type"),
|
||||
}
|
||||
@@ -101,24 +101,22 @@ impl ExternalReferenceType for TurnChoice {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
impl ExternalReferenceType for MoveTurnChoiceDataTemporary {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
impl MoveTurnChoiceDataInner {
|
||||
fn from_reference(reference: ExternRef<MoveTurnChoiceData>) -> Self {
|
||||
Self {
|
||||
inner: Rc::new(MoveTurnChoiceDataInner {
|
||||
base: BaseTurnChoiceData {
|
||||
reference: reference.cast(),
|
||||
user: cached_value!({
|
||||
turn_choice_get_user(reference.cast()).get_value().unwrap()
|
||||
}),
|
||||
},
|
||||
used_move: cached_value!({
|
||||
turn_choice_move_used_move(reference.cast())
|
||||
.get_value()
|
||||
.unwrap()
|
||||
base: BaseTurnChoiceData {
|
||||
reference: reference.cast(),
|
||||
user: cached_value!({
|
||||
turn_choice_get_user(reference.cast()).get_value().unwrap()
|
||||
}),
|
||||
target_side: cached_value!({ turn_choice_move_target_side(reference.cast()) }),
|
||||
target_index: cached_value!({ turn_choice_move_target_index(reference.cast()) }),
|
||||
},
|
||||
used_move: cached_value!({
|
||||
turn_choice_move_used_move(reference.cast())
|
||||
.get_value()
|
||||
.unwrap()
|
||||
}),
|
||||
target_side: cached_value!({ turn_choice_move_target_side(reference.cast()) }),
|
||||
target_index: cached_value!({ turn_choice_move_target_index(reference.cast()) }),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,14 +133,6 @@ extern "wasm" {
|
||||
fn turn_choice_move_target_side(r: ExternRef<MoveTurnChoiceData>) -> u8;
|
||||
fn turn_choice_move_target_index(r: ExternRef<MoveTurnChoiceData>) -> u8;
|
||||
fn turn_choice_move_priority(r: ExternRef<MoveTurnChoiceData>) -> i8;
|
||||
#[allow(improper_ctypes)]
|
||||
fn turn_choice_move_script(r: ExternRef<MoveTurnChoiceData>) -> *const Box<dyn Script>;
|
||||
}
|
||||
|
||||
#[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()),
|
||||
_ => panic!("Unknown turn choice type"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{ExternalReferenceType, VecExternRef};
|
||||
use alloc::boxed::Box;
|
||||
use alloc::collections::BTreeMap;
|
||||
#[cfg(feature = "mock_data")]
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
use core::marker::PhantomData;
|
||||
@@ -44,13 +44,22 @@ where
|
||||
|
||||
pub(crate) fn from_ref(extern_ref: VecExternRef<T>) -> Self {
|
||||
unsafe {
|
||||
let existing = CACHE.get(&extern_ref.get_internal_index());
|
||||
if let None = CACHE {
|
||||
CACHE = Some(hashbrown::HashMap::new());
|
||||
}
|
||||
let existing = CACHE
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get(&extern_ref.get_internal_index());
|
||||
if let Some(v) = existing {
|
||||
let inner = *v as *const ImmutableListInner<T>;
|
||||
ImmutableList { inner }
|
||||
} else {
|
||||
let v = Self::new(extern_ref);
|
||||
CACHE.insert(extern_ref.get_internal_index(), v.inner as *const u8);
|
||||
CACHE
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.insert(extern_ref.get_internal_index(), v.inner as *const u8);
|
||||
v
|
||||
}
|
||||
}
|
||||
@@ -102,4 +111,4 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
static mut CACHE: BTreeMap<u32, *const u8> = BTreeMap::new();
|
||||
static mut CACHE: Option<hashbrown::HashMap<u32, *const u8>> = None;
|
||||
|
||||
@@ -5,5 +5,4 @@ pub mod string_key;
|
||||
|
||||
pub use dynamic_data::*;
|
||||
pub use static_data::*;
|
||||
pub use string_key::get_hash_const;
|
||||
pub use string_key::StringKey;
|
||||
pub use string_key::*;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
use crate::app_interface::{DataLibrary, Item};
|
||||
use crate::{ExternRef, ExternalReferenceType, StringKey};
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::rc::Rc;
|
||||
use spin::rwlock::RwLock;
|
||||
|
||||
struct ItemLibraryInner {
|
||||
ptr: ExternRef<ItemLibrary>,
|
||||
cache: RwLock<BTreeMap<u32, Item>>,
|
||||
cache: RwLock<hashbrown::HashMap<u32, Item>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -27,7 +26,7 @@ impl ItemLibrary {
|
||||
}
|
||||
|
||||
impl DataLibrary<Item> for ItemLibrary {
|
||||
fn get_cache(&self) -> &spin::rwlock::RwLock<BTreeMap<u32, Item>> {
|
||||
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, Item>> {
|
||||
&self.inner.cache
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType, StringKey};
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::rc::Rc;
|
||||
use move_library::MoveLibrary;
|
||||
use spin::rwlock::RwLock;
|
||||
@@ -51,6 +50,11 @@ impl StaticData {
|
||||
type_library: cached_value!({
|
||||
static_data_get_type_library(reference).get_value().unwrap()
|
||||
}),
|
||||
settings: cached_value!({
|
||||
static_data_get_library_settings(reference)
|
||||
.get_value()
|
||||
.unwrap()
|
||||
}),
|
||||
}),
|
||||
})
|
||||
}
|
||||
@@ -88,7 +92,7 @@ crate::handling::cacheable::cacheable!(StaticData);
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
impl ExternalReferenceType for StaticData {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
StaticData::mock(reference)
|
||||
StaticData::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,12 +129,20 @@ impl LibrarySettings {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
impl ExternalReferenceType for LibrarySettings {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
LibrarySettings::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
#[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>;
|
||||
fn static_data_get_species_library(ptr: ExternRef<StaticData>) -> ExternRef<SpeciesLibrary>;
|
||||
fn static_data_get_type_library(ptr: ExternRef<StaticData>) -> ExternRef<TypeLibrary>;
|
||||
fn static_data_get_library_settings(ptr: ExternRef<StaticData>) -> ExternRef<LibrarySettings>;
|
||||
|
||||
fn library_settings_get_maximum_level(ptr: ExternRef<LibrarySettings>) -> LevelInt;
|
||||
}
|
||||
@@ -141,7 +153,7 @@ where
|
||||
T: ExternalReferenceType,
|
||||
T: Clone,
|
||||
{
|
||||
fn get_cache(&self) -> &RwLock<BTreeMap<u32, T>>;
|
||||
fn get_cache(&self) -> &RwLock<hashbrown::HashMap<u32, T>>;
|
||||
fn get_self_ref(&self) -> ExternRef<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
@@ -188,7 +200,7 @@ pub trait DataLibrary<T>: Cacheable
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
fn get_cache(&self) -> &RwLock<BTreeMap<u32, T>>;
|
||||
fn get_cache(&self) -> &RwLock<hashbrown::HashMap<u32, T>>;
|
||||
fn get_self_ref(&self) -> ExternRef<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
use crate::app_interface::data_libraries::DataLibrary;
|
||||
use crate::app_interface::{MoveData, StringKey};
|
||||
use crate::{ExternRef, ExternalReferenceType};
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::rc::Rc;
|
||||
use spin::RwLock;
|
||||
|
||||
struct MoveLibraryInner {
|
||||
ptr: ExternRef<MoveLibrary>,
|
||||
cache: RwLock<BTreeMap<u32, MoveData>>,
|
||||
cache: RwLock<hashbrown::HashMap<u32, MoveData>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -38,7 +37,7 @@ impl MoveLibrary {
|
||||
}
|
||||
|
||||
impl DataLibrary<MoveData> for MoveLibrary {
|
||||
fn get_cache(&self) -> &spin::rwlock::RwLock<BTreeMap<u32, MoveData>> {
|
||||
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, MoveData>> {
|
||||
&self.inner.cache
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
use crate::app_interface::{DataLibrary, Species};
|
||||
use crate::{ExternRef, ExternalReferenceType, StringKey};
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::rc::Rc;
|
||||
use spin::RwLock;
|
||||
|
||||
struct SpeciesLibraryInner {
|
||||
ptr: ExternRef<SpeciesLibrary>,
|
||||
cache: RwLock<BTreeMap<u32, Species>>,
|
||||
cache: RwLock<hashbrown::HashMap<u32, Species>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -37,7 +36,7 @@ impl SpeciesLibrary {
|
||||
}
|
||||
|
||||
impl DataLibrary<Species> for SpeciesLibrary {
|
||||
fn get_cache(&self) -> &spin::rwlock::RwLock<BTreeMap<u32, Species>> {
|
||||
fn get_cache(&self) -> &spin::rwlock::RwLock<hashbrown::HashMap<u32, Species>> {
|
||||
&self.inner.cache
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::{ExternRef, ExternalReferenceType};
|
||||
use alloc::collections::BTreeMap;
|
||||
use crate::{ExternRef, ExternalReferenceType, TypeIdentifier};
|
||||
use alloc::rc::Rc;
|
||||
use alloc::string::{String, ToString};
|
||||
use cstr_core::{c_char, CString};
|
||||
@@ -7,8 +6,8 @@ use spin::RwLock;
|
||||
|
||||
struct TypeLibraryInner {
|
||||
reference: ExternRef<TypeLibrary>,
|
||||
name_to_type_cache: RwLock<BTreeMap<String, u8>>,
|
||||
effectiveness_cache: RwLock<BTreeMap<(u8, u8), f32>>,
|
||||
name_to_type_cache: RwLock<hashbrown::HashMap<String, TypeIdentifier>>,
|
||||
effectiveness_cache: RwLock<hashbrown::HashMap<(TypeIdentifier, TypeIdentifier), f32>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -39,7 +38,7 @@ impl TypeLibrary {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn get_type_from_name(&self, name: &str) -> Option<u8> {
|
||||
pub fn get_type_from_name(&self, name: &str) -> Option<TypeIdentifier> {
|
||||
if let Some(cached) = self.inner.name_to_type_cache.read().get(name) {
|
||||
return Some(*cached);
|
||||
}
|
||||
@@ -48,6 +47,7 @@ impl TypeLibrary {
|
||||
if v == 255 {
|
||||
return None;
|
||||
}
|
||||
let v = v.into();
|
||||
self.inner
|
||||
.name_to_type_cache
|
||||
.write()
|
||||
@@ -56,7 +56,11 @@ impl TypeLibrary {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn get_single_effectiveness(&self, attacking_type: u8, defending_type: u8) -> f32 {
|
||||
pub fn get_single_effectiveness(
|
||||
&self,
|
||||
attacking_type: TypeIdentifier,
|
||||
defending_type: TypeIdentifier,
|
||||
) -> f32 {
|
||||
if let Some(cached) = self
|
||||
.inner
|
||||
.effectiveness_cache
|
||||
@@ -68,8 +72,8 @@ impl TypeLibrary {
|
||||
let effectiveness = unsafe {
|
||||
type_library_get_single_effectiveness(
|
||||
self.inner.reference,
|
||||
attacking_type,
|
||||
defending_type,
|
||||
attacking_type.into(),
|
||||
defending_type.into(),
|
||||
)
|
||||
};
|
||||
self.inner
|
||||
@@ -80,7 +84,11 @@ impl TypeLibrary {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn get_effectiveness(&self, attacking_type: u8, defending_types: &[u8]) -> f32 {
|
||||
pub fn get_effectiveness(
|
||||
&self,
|
||||
attacking_type: TypeIdentifier,
|
||||
defending_types: &[TypeIdentifier],
|
||||
) -> f32 {
|
||||
let mut f = 1.0;
|
||||
for defending_type in defending_types {
|
||||
f *= self.get_single_effectiveness(attacking_type, *defending_type);
|
||||
|
||||
@@ -96,7 +96,7 @@ crate::handling::cacheable::cacheable!(Item);
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
impl ExternalReferenceType for Item {
|
||||
fn from_extern_value(reference: ExternRef<Self>) -> Self {
|
||||
Item::mock(reference)
|
||||
Item::new(reference)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,3 +14,23 @@ pub use nature::*;
|
||||
pub use species::*;
|
||||
|
||||
pub type LevelInt = u8;
|
||||
|
||||
/// A unique key that can be used to store a reference to a type. Opaque reference to a byte
|
||||
/// internally.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default, Hash)]
|
||||
pub struct TypeIdentifier {
|
||||
/// The unique internal value.
|
||||
val: u8,
|
||||
}
|
||||
|
||||
impl From<u8> for TypeIdentifier {
|
||||
fn from(val: u8) -> Self {
|
||||
Self { val }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TypeIdentifier> for u8 {
|
||||
fn from(id: TypeIdentifier) -> Self {
|
||||
id.val
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::app_interface::{get_hash_const, StringKey};
|
||||
use crate::app_interface::{get_hash, StringKey};
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType};
|
||||
@@ -104,8 +104,8 @@ impl MoveData {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn has_flag<const N: usize>(&self, flag: &[u8; N]) -> bool {
|
||||
let hash = get_hash_const(flag);
|
||||
pub fn has_flag(&self, flag: &str) -> bool {
|
||||
let hash = get_hash(flag);
|
||||
unsafe { move_data_has_flag_by_hash(self.inner.ptr, hash) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use crate::app_interface::get_hash_const;
|
||||
use crate::app_interface::get_hash;
|
||||
use crate::handling::cached_value::CachedValue;
|
||||
use crate::handling::Cacheable;
|
||||
use crate::{
|
||||
cached_value, cached_value_getters, ExternRef, ExternalReferenceType, FFIArray, ImmutableList,
|
||||
StringKey, VecExternRef,
|
||||
};
|
||||
use alloc::collections::BTreeMap;
|
||||
use alloc::rc::Rc;
|
||||
use alloc::vec::Vec;
|
||||
use spin::RwLock;
|
||||
@@ -147,8 +146,8 @@ impl Form {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn has_flag<const N: usize>(&self, flag: &[u8; N]) -> bool {
|
||||
let hash = get_hash_const(flag);
|
||||
pub fn has_flag(&self, flag: &str) -> bool {
|
||||
let hash = get_hash(flag);
|
||||
unsafe { form_has_flag_by_hash(self.inner.reference, hash) }
|
||||
}
|
||||
}
|
||||
@@ -160,7 +159,7 @@ pub struct SpeciesInner {
|
||||
gender_rate: CachedValue<f32>,
|
||||
growth_rate: CachedValue<StringKey>,
|
||||
capture_rate: CachedValue<u8>,
|
||||
forms: RwLock<BTreeMap<u32, Option<Form>>>,
|
||||
forms: RwLock<hashbrown::HashMap<u32, Option<Form>>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -205,8 +204,8 @@ impl Species {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn get_form<const N: usize>(&self, form_name: &[u8; N]) -> Option<Form> {
|
||||
let hash = get_hash_const(form_name);
|
||||
pub fn get_form(&self, form_name: &str) -> Option<Form> {
|
||||
let hash = get_hash(form_name);
|
||||
unsafe {
|
||||
if let Some(v) = self.inner.forms.read().get(&hash) {
|
||||
v.clone()
|
||||
@@ -220,8 +219,8 @@ impl Species {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub fn has_flag<const N: usize>(&self, flag: &[u8; N]) -> bool {
|
||||
let hash = get_hash_const(flag);
|
||||
pub fn has_flag(&self, flag: &str) -> bool {
|
||||
let hash = get_hash(flag);
|
||||
unsafe { species_has_flag_by_hash(self.inner.reference, hash) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ impl StringKey {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
pub(super) fn ptr(&self) -> ExternRef<Self> {
|
||||
pub(crate) fn ptr(&self) -> ExternRef<Self> {
|
||||
self.data.ptr
|
||||
}
|
||||
|
||||
@@ -70,6 +70,12 @@ impl StringKey {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for StringKey {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.data.ptr == other.data.ptr
|
||||
}
|
||||
}
|
||||
|
||||
crate::handling::cacheable::cacheable!(StringKey);
|
||||
|
||||
#[cfg(not(feature = "mock_data"))]
|
||||
@@ -134,23 +140,12 @@ const fn to_lower(c: u8) -> u8 {
|
||||
c
|
||||
}
|
||||
|
||||
pub const fn get_hash_const<const N: usize>(s: &[u8; N]) -> u32 {
|
||||
let mut crc: u32 = 0xffffffff;
|
||||
|
||||
let mut i: usize = 0;
|
||||
while i < N {
|
||||
crc = (crc >> 8) ^ CRC_TABLE[((crc ^ (to_lower(s[i]) as u32)) & 0xff) as usize];
|
||||
i += 1;
|
||||
}
|
||||
crc ^ 0xffffffff
|
||||
}
|
||||
|
||||
pub const fn get_hash(s: &[u8]) -> u32 {
|
||||
pub const fn get_hash(s: &str) -> 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];
|
||||
crc = (crc >> 8) ^ CRC_TABLE[((crc ^ (to_lower(s.as_bytes()[i]) as u32)) & 0xff) as usize];
|
||||
i += 1;
|
||||
}
|
||||
crc ^ 0xffffffff
|
||||
|
||||
Reference in New Issue
Block a user