PkmnLib_rs/src/script_implementations/wasm/export_registry/wasm_object.rs

461 lines
18 KiB
Rust

use crate::dynamic_data::{Battle, Pokemon, WeakBattleReference, WeakBattleSideReference, WeakPokemonReference};
use anyhow::anyhow;
use anyhow_ext::Result;
use std::hash::{Hash, Hasher};
use std::sync::{Arc, Weak};
#[derive(Clone)]
#[allow(clippy::missing_docs_in_private_items)]
pub(crate) enum WasmObject {
// Static data
StringKey(crate::StringKey),
EffectParameter(Weak<crate::static_data::Parameter>),
MoveData(Weak<dyn crate::static_data::MoveData>),
Species(Weak<dyn crate::static_data::Species>),
Form(Weak<dyn crate::static_data::Form>),
Item(Weak<dyn crate::static_data::Item>),
Ability(Weak<dyn crate::static_data::Ability>),
Nature(Weak<dyn crate::static_data::Nature>),
StaticStatisticSetU16(Weak<crate::static_data::StaticStatisticSet<u16>>),
StatisticSetU32(Weak<crate::static_data::StatisticSet<u32>>),
StatChangeStatisticSet(Weak<crate::static_data::ClampedStatisticSet<i8, -6, 6>>),
EVStatisticSet(Weak<crate::static_data::ClampedStatisticSet<u8, 0, 252>>),
IVStatisticSet(Weak<crate::static_data::ClampedStatisticSet<u8, 0, 31>>),
// Static data libraries
MoveLibrary(Weak<dyn crate::static_data::MoveLibrary>),
SpeciesLibrary(Weak<dyn crate::static_data::SpeciesLibrary>),
ItemLibrary(Weak<dyn crate::static_data::ItemLibrary>),
TypeLibrary(Weak<dyn crate::static_data::TypeLibrary>),
LibrarySettings(Weak<dyn crate::static_data::LibrarySettings>),
AbilityLibrary(Weak<dyn crate::static_data::AbilityLibrary>),
StaticData(Weak<dyn crate::static_data::StaticData>),
// Dynamic data
Pokemon(WeakPokemonReference),
PokemonParty(Weak<crate::dynamic_data::PokemonParty>),
LearnedMove(Weak<crate::dynamic_data::LearnedMove>),
// Dynamic data libraries
DynamicLibrary(Weak<dyn crate::dynamic_data::DynamicLibrary>),
MiscLibrary(Weak<dyn crate::dynamic_data::MiscLibrary>),
// Battle data
Battle(WeakBattleReference),
ChoiceQueue(Weak<crate::dynamic_data::ChoiceQueue>),
BattleRandom(Weak<crate::dynamic_data::BattleRandom>),
BattleSide(WeakBattleSideReference),
BattleParty(Weak<crate::dynamic_data::BattleParty>),
TurnChoice(Weak<crate::dynamic_data::TurnChoice>),
ExecutingMove(Weak<crate::dynamic_data::ExecutingMove>),
HitData(Weak<crate::dynamic_data::HitData>),
}
/// Trait for converting from a [`WasmObject`] to a Rust object.
pub(crate) trait FromWasmObj
where
Self: Sized,
{
/// Converts from a [`WasmObject`] to a Rust object.
fn from_wasm_obj(obj: WasmObject) -> Result<Self>;
}
impl PartialEq for WasmObject {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(WasmObject::StringKey(s1), WasmObject::StringKey(s2)) => s1 == s2,
(WasmObject::EffectParameter(s1), WasmObject::EffectParameter(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::MoveData(s1), WasmObject::MoveData(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::Species(s1), WasmObject::Species(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::Form(s1), WasmObject::Form(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::Item(s1), WasmObject::Item(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::Ability(s1), WasmObject::Ability(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::Nature(s1), WasmObject::Nature(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::StaticStatisticSetU16(s1), WasmObject::StaticStatisticSetU16(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::StatisticSetU32(s1), WasmObject::StatisticSetU32(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::StatChangeStatisticSet(s1), WasmObject::StatChangeStatisticSet(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::EVStatisticSet(s1), WasmObject::EVStatisticSet(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::IVStatisticSet(s1), WasmObject::IVStatisticSet(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::MoveLibrary(s1), WasmObject::MoveLibrary(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::SpeciesLibrary(s1), WasmObject::SpeciesLibrary(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::ItemLibrary(s1), WasmObject::ItemLibrary(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::TypeLibrary(s1), WasmObject::TypeLibrary(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::LibrarySettings(s1), WasmObject::LibrarySettings(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::AbilityLibrary(s1), WasmObject::AbilityLibrary(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::StaticData(s1), WasmObject::StaticData(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::Pokemon(s1), WasmObject::Pokemon(s2)) => WeakPokemonReference::eq(s1, s2),
(WasmObject::PokemonParty(s1), WasmObject::PokemonParty(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::LearnedMove(s1), WasmObject::LearnedMove(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::DynamicLibrary(s1), WasmObject::DynamicLibrary(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::MiscLibrary(s1), WasmObject::MiscLibrary(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::Battle(s1), WasmObject::Battle(s2)) => WeakBattleReference::eq(s1, s2),
(WasmObject::ChoiceQueue(s1), WasmObject::ChoiceQueue(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::BattleRandom(s1), WasmObject::BattleRandom(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::BattleSide(s1), WasmObject::BattleSide(s2)) => WeakBattleSideReference::eq(s1, s2),
(WasmObject::BattleParty(s1), WasmObject::BattleParty(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::TurnChoice(s1), WasmObject::TurnChoice(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::ExecutingMove(s1), WasmObject::ExecutingMove(s2)) => Weak::ptr_eq(s1, s2),
(WasmObject::HitData(s1), WasmObject::HitData(s2)) => Weak::ptr_eq(s1, s2),
_ => false,
}
}
}
impl Eq for WasmObject {}
impl Hash for WasmObject {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
WasmObject::StringKey(s) => state.write_u32(s.hash()),
WasmObject::EffectParameter(m) => m.as_ptr().hash(state),
WasmObject::MoveData(m) => m.as_ptr().hash(state),
WasmObject::Species(m) => m.as_ptr().hash(state),
WasmObject::Form(m) => m.as_ptr().hash(state),
WasmObject::Item(m) => m.as_ptr().hash(state),
WasmObject::Ability(m) => m.as_ptr().hash(state),
WasmObject::Nature(m) => m.as_ptr().hash(state),
WasmObject::StaticStatisticSetU16(m) => m.as_ptr().hash(state),
WasmObject::StatisticSetU32(m) => m.as_ptr().hash(state),
WasmObject::StatChangeStatisticSet(m) => m.as_ptr().hash(state),
WasmObject::EVStatisticSet(m) => m.as_ptr().hash(state),
WasmObject::IVStatisticSet(m) => m.as_ptr().hash(state),
WasmObject::MoveLibrary(m) => m.as_ptr().hash(state),
WasmObject::SpeciesLibrary(m) => m.as_ptr().hash(state),
WasmObject::ItemLibrary(m) => m.as_ptr().hash(state),
WasmObject::TypeLibrary(m) => m.as_ptr().hash(state),
WasmObject::LibrarySettings(m) => m.as_ptr().hash(state),
WasmObject::AbilityLibrary(m) => m.as_ptr().hash(state),
WasmObject::StaticData(m) => m.as_ptr().hash(state),
WasmObject::Pokemon(m) => m.as_ptr().hash(state),
WasmObject::PokemonParty(m) => m.as_ptr().hash(state),
WasmObject::LearnedMove(m) => m.as_ptr().hash(state),
WasmObject::DynamicLibrary(m) => m.as_ptr().hash(state),
WasmObject::MiscLibrary(m) => m.as_ptr().hash(state),
WasmObject::Battle(m) => m.as_ptr().hash(state),
WasmObject::ChoiceQueue(m) => m.as_ptr().hash(state),
WasmObject::BattleRandom(m) => m.as_ptr().hash(state),
WasmObject::BattleSide(m) => m.as_ptr().hash(state),
WasmObject::BattleParty(m) => m.as_ptr().hash(state),
WasmObject::TurnChoice(m) => m.as_ptr().hash(state),
WasmObject::ExecutingMove(m) => m.as_ptr().hash(state),
WasmObject::HitData(m) => m.as_ptr().hash(state),
};
}
}
/// Macro to convert a `WasmObject` into a `Result` of the specified type.
macro_rules! get_from_wasm_obj {
($variant:ident, $obj:expr) => {
match $obj {
WasmObject::$variant(b) => b.upgrade().ok_or(anyhow!("$variant was dropped")),
_ => Err(anyhow!("Expected $variant")),
}
};
}
/// Macro to implement `FromWasmObj` for a type.
macro_rules! impl_from_wasm_obj {
($variant:ident, $ty:ty) => {
impl FromWasmObj for $ty {
fn from_wasm_obj(obj: WasmObject) -> Result<Self> {
get_from_wasm_obj!($variant, obj)
}
}
};
}
impl From<crate::StringKey> for WasmObject {
fn from(value: crate::StringKey) -> Self {
Self::StringKey(value)
}
}
impl FromWasmObj for crate::StringKey {
fn from_wasm_obj(obj: WasmObject) -> Result<Self> {
match obj {
WasmObject::StringKey(b) => Ok(b),
_ => Err(anyhow!("Expected StringKey")),
}
}
}
impl From<&Arc<crate::static_data::Parameter>> for WasmObject {
fn from(value: &Arc<crate::static_data::Parameter>) -> Self {
Self::EffectParameter(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(EffectParameter, Arc<crate::static_data::Parameter>);
impl From<&Arc<dyn crate::static_data::MoveData>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::MoveData>) -> Self {
Self::MoveData(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(MoveData, Arc<dyn crate::static_data::MoveData>);
impl From<&Arc<dyn crate::static_data::Species>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::Species>) -> Self {
Self::Species(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(Species, Arc<dyn crate::static_data::Species>);
impl From<&Arc<dyn crate::static_data::Form>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::Form>) -> Self {
Self::Form(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(Form, Arc<dyn crate::static_data::Form>);
impl From<&Arc<dyn crate::static_data::Item>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::Item>) -> Self {
Self::Item(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(Item, Arc<dyn crate::static_data::Item>);
impl From<&Arc<dyn crate::static_data::Ability>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::Ability>) -> Self {
Self::Ability(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(Ability, Arc<dyn crate::static_data::Ability>);
impl From<&Arc<dyn crate::static_data::Nature>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::Nature>) -> Self {
Self::Nature(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(Nature, Arc<dyn crate::static_data::Nature>);
impl From<&Arc<crate::static_data::StaticStatisticSet<u16>>> for WasmObject {
fn from(value: &Arc<crate::static_data::StaticStatisticSet<u16>>) -> Self {
Self::StaticStatisticSetU16(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(StaticStatisticSetU16, Arc<crate::static_data::StaticStatisticSet<u16>>);
impl From<&Arc<crate::static_data::StatisticSet<u32>>> for WasmObject {
fn from(value: &Arc<crate::static_data::StatisticSet<u32>>) -> Self {
Self::StatisticSetU32(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(StatisticSetU32, Arc<crate::static_data::StatisticSet<u32>>);
impl From<&Arc<crate::static_data::ClampedStatisticSet<i8, -6, 6>>> for WasmObject {
fn from(value: &Arc<crate::static_data::ClampedStatisticSet<i8, -6, 6>>) -> Self {
Self::StatChangeStatisticSet(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(
StatChangeStatisticSet,
Arc<crate::static_data::ClampedStatisticSet<i8, -6, 6>>
);
impl From<&Arc<crate::static_data::ClampedStatisticSet<u8, 0, 252>>> for WasmObject {
fn from(value: &Arc<crate::static_data::ClampedStatisticSet<u8, 0, 252>>) -> Self {
Self::EVStatisticSet(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(EVStatisticSet, Arc<crate::static_data::ClampedStatisticSet<u8, 0, 252>>);
impl From<&Arc<crate::static_data::ClampedStatisticSet<u8, 0, 31>>> for WasmObject {
fn from(value: &Arc<crate::static_data::ClampedStatisticSet<u8, 0, 31>>) -> Self {
Self::IVStatisticSet(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(IVStatisticSet, Arc<crate::static_data::ClampedStatisticSet<u8, 0, 31>>);
impl From<&Arc<dyn crate::static_data::MoveLibrary>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::MoveLibrary>) -> Self {
Self::MoveLibrary(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(MoveLibrary, Arc<dyn crate::static_data::MoveLibrary>);
impl From<&Arc<dyn crate::static_data::SpeciesLibrary>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::SpeciesLibrary>) -> Self {
Self::SpeciesLibrary(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(SpeciesLibrary, Arc<dyn crate::static_data::SpeciesLibrary>);
impl From<&Arc<dyn crate::static_data::ItemLibrary>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::ItemLibrary>) -> Self {
Self::ItemLibrary(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(ItemLibrary, Arc<dyn crate::static_data::ItemLibrary>);
impl From<&Arc<dyn crate::static_data::TypeLibrary>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::TypeLibrary>) -> Self {
Self::TypeLibrary(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(TypeLibrary, Arc<dyn crate::static_data::TypeLibrary>);
impl From<&Arc<dyn crate::static_data::LibrarySettings>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::LibrarySettings>) -> Self {
Self::LibrarySettings(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(LibrarySettings, Arc<dyn crate::static_data::LibrarySettings>);
impl From<&Arc<dyn crate::static_data::AbilityLibrary>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::AbilityLibrary>) -> Self {
Self::AbilityLibrary(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(AbilityLibrary, Arc<dyn crate::static_data::AbilityLibrary>);
impl From<&Arc<dyn crate::static_data::StaticData>> for WasmObject {
fn from(value: &Arc<dyn crate::static_data::StaticData>) -> Self {
Self::StaticData(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(StaticData, Arc<dyn crate::static_data::StaticData>);
impl From<&Pokemon> for WasmObject {
fn from(value: &Pokemon) -> Self {
Self::Pokemon(value.weak())
}
}
impl From<&WeakPokemonReference> for WasmObject {
fn from(value: &WeakPokemonReference) -> Self {
Self::Pokemon(value.clone())
}
}
impl_from_wasm_obj!(Pokemon, Pokemon);
impl From<&Arc<crate::dynamic_data::PokemonParty>> for WasmObject {
fn from(value: &Arc<crate::dynamic_data::PokemonParty>) -> Self {
Self::PokemonParty(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(PokemonParty, Arc<crate::dynamic_data::PokemonParty>);
impl From<&Arc<crate::dynamic_data::LearnedMove>> for WasmObject {
fn from(value: &Arc<crate::dynamic_data::LearnedMove>) -> Self {
Self::LearnedMove(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(LearnedMove, Arc<crate::dynamic_data::LearnedMove>);
impl From<&Battle> for WasmObject {
fn from(value: &Battle) -> Self {
Self::Battle(value.weak())
}
}
impl From<&WeakBattleReference> for WasmObject {
fn from(value: &WeakBattleReference) -> Self {
Self::Battle(value.clone())
}
}
impl_from_wasm_obj!(Battle, crate::dynamic_data::Battle);
impl From<&Arc<crate::dynamic_data::ChoiceQueue>> for WasmObject {
fn from(value: &Arc<crate::dynamic_data::ChoiceQueue>) -> Self {
Self::ChoiceQueue(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(ChoiceQueue, Arc<crate::dynamic_data::ChoiceQueue>);
impl From<&Arc<dyn crate::dynamic_data::DynamicLibrary>> for WasmObject {
fn from(value: &Arc<dyn crate::dynamic_data::DynamicLibrary>) -> Self {
Self::DynamicLibrary(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(DynamicLibrary, Arc<dyn crate::dynamic_data::DynamicLibrary>);
impl From<&Arc<dyn crate::dynamic_data::MiscLibrary>> for WasmObject {
fn from(value: &Arc<dyn crate::dynamic_data::MiscLibrary>) -> Self {
Self::MiscLibrary(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(MiscLibrary, Arc<dyn crate::dynamic_data::MiscLibrary>);
impl From<&Arc<crate::dynamic_data::BattleRandom>> for WasmObject {
fn from(value: &Arc<crate::dynamic_data::BattleRandom>) -> Self {
Self::BattleRandom(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(BattleRandom, Arc<crate::dynamic_data::BattleRandom>);
impl From<&crate::dynamic_data::BattleSide> for WasmObject {
fn from(value: &crate::dynamic_data::BattleSide) -> Self {
Self::BattleSide(value.weak())
}
}
impl From<&WeakBattleSideReference> for WasmObject {
fn from(value: &WeakBattleSideReference) -> Self {
Self::BattleSide(value.clone())
}
}
impl_from_wasm_obj!(BattleSide, crate::dynamic_data::BattleSide);
impl From<&Arc<crate::dynamic_data::BattleParty>> for WasmObject {
fn from(value: &Arc<crate::dynamic_data::BattleParty>) -> Self {
Self::BattleParty(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(BattleParty, Arc<crate::dynamic_data::BattleParty>);
impl From<&Arc<crate::dynamic_data::TurnChoice>> for WasmObject {
fn from(value: &Arc<crate::dynamic_data::TurnChoice>) -> Self {
Self::TurnChoice(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(TurnChoice, Arc<crate::dynamic_data::TurnChoice>);
impl From<&Arc<crate::dynamic_data::ExecutingMove>> for WasmObject {
fn from(value: &Arc<crate::dynamic_data::ExecutingMove>) -> Self {
Self::ExecutingMove(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(ExecutingMove, Arc<crate::dynamic_data::ExecutingMove>);
impl From<&Arc<crate::dynamic_data::HitData>> for WasmObject {
fn from(value: &Arc<crate::dynamic_data::HitData>) -> Self {
Self::HitData(Arc::downgrade(value))
}
}
impl_from_wasm_obj!(HitData, Arc<crate::dynamic_data::HitData>);