Major work on WASM results
This commit is contained in:
parent
0d3d5bcbe7
commit
6a2353df4c
|
@ -53,7 +53,7 @@ hashbrown = "0.13.1"
|
||||||
indexmap = "1.8.2"
|
indexmap = "1.8.2"
|
||||||
parking_lot = "0.12.1"
|
parking_lot = "0.12.1"
|
||||||
serde = { version = "1.0.137", optional = true, features = ["derive"] }
|
serde = { version = "1.0.137", optional = true, features = ["derive"] }
|
||||||
wasmer = { version = "3.1.1", optional = true, default-features = false, features = ["sys", "wat", "cranelift"] }
|
wasmer = { version = "3.3.0", optional = true, default-features = false, features = ["sys", "wat", "llvm"] }
|
||||||
uuid = "1.2.2"
|
uuid = "1.2.2"
|
||||||
paste = { version = "1.0.8" }
|
paste = { version = "1.0.8" }
|
||||||
arcstr = { version = "1.1.4", features = ["std"] }
|
arcstr = { version = "1.1.4", features = ["std"] }
|
||||||
|
@ -61,6 +61,7 @@ enum-display-derive = "0.1.1"
|
||||||
anyhow = "1.0.69"
|
anyhow = "1.0.69"
|
||||||
anyhow_ext = "0.2.1"
|
anyhow_ext = "0.2.1"
|
||||||
thiserror = "1.0.39"
|
thiserror = "1.0.39"
|
||||||
|
stdext = "0.3.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
csv = "1.1.6"
|
csv = "1.1.6"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use parking_lot::RwLock;
|
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::sync::RwLock;
|
||||||
|
|
||||||
use crate::dynamic_data::DamageSource;
|
use crate::dynamic_data::DamageSource;
|
||||||
use crate::dynamic_data::ExecutingMove;
|
use crate::dynamic_data::ExecutingMove;
|
||||||
|
@ -29,14 +29,15 @@ impl EventHook {
|
||||||
/// listeners can exist at the same time. Note that for these functions the event will be disposed
|
/// listeners can exist at the same time. Note that for these functions the event will be disposed
|
||||||
/// of after the event is finished being sent.
|
/// of after the event is finished being sent.
|
||||||
pub fn register_listener(&self, func: EvtHookFn) {
|
pub fn register_listener(&self, func: EvtHookFn) {
|
||||||
self.evt_hook_function.write().push(func);
|
self.evt_hook_function.write().unwrap().push(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run a new event. This will send the event to all externally defined event listeners. It will
|
/// Run a new event. This will send the event to all externally defined event listeners. It will
|
||||||
/// dispose of the event afterwards.
|
/// dispose of the event afterwards.
|
||||||
pub fn trigger(&self, evt: Event) {
|
pub fn trigger(&self, evt: Event) {
|
||||||
let b = Box::new(&evt);
|
let b = Box::new(&evt);
|
||||||
for f in self.evt_hook_function.read().iter() {
|
let read_lock = self.evt_hook_function.read().unwrap();
|
||||||
|
for f in read_lock.iter() {
|
||||||
f(&b);
|
f(&b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ impl Battle {
|
||||||
number_of_sides: u8,
|
number_of_sides: u8,
|
||||||
pokemon_per_side: u8,
|
pokemon_per_side: u8,
|
||||||
random_seed: Option<u128>,
|
random_seed: Option<u128>,
|
||||||
) -> Self {
|
) -> Arc<Self> {
|
||||||
// If no seed was passed, we use the current time as seed for the RNG, otherwise we use the
|
// If no seed was passed, we use the current time as seed for the RNG, otherwise we use the
|
||||||
// seed.
|
// seed.
|
||||||
let random = if let Some(seed) = random_seed {
|
let random = if let Some(seed) = random_seed {
|
||||||
|
@ -83,7 +83,7 @@ impl Battle {
|
||||||
sides.push(BattleSide::new(i, pokemon_per_side));
|
sides.push(BattleSide::new(i, pokemon_per_side));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut battle = Self {
|
let battle = Self {
|
||||||
identifier: Default::default(),
|
identifier: Default::default(),
|
||||||
library,
|
library,
|
||||||
parties,
|
parties,
|
||||||
|
@ -103,12 +103,16 @@ impl Battle {
|
||||||
script_source_data: Default::default(),
|
script_source_data: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ptr: *mut Battle = &mut battle;
|
let battle_arc = Arc::new(battle);
|
||||||
for side in &mut battle.sides {
|
|
||||||
side.set_battle(ptr);
|
let battle_ptr = Arc::as_ptr(&battle_arc) as *mut Battle;
|
||||||
|
unsafe {
|
||||||
|
for side in &mut battle_ptr.as_mut().unwrap().sides {
|
||||||
|
side.set_battle(Arc::downgrade(&battle_arc));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
battle
|
battle_arc
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The library the battle uses for handling.
|
/// The library the battle uses for handling.
|
||||||
|
@ -135,10 +139,6 @@ impl Battle {
|
||||||
pub fn sides(&self) -> &Vec<BattleSide> {
|
pub fn sides(&self) -> &Vec<BattleSide> {
|
||||||
&self.sides
|
&self.sides
|
||||||
}
|
}
|
||||||
/// A mutable list of all sides in the battle.
|
|
||||||
pub fn sides_mut(&mut self) -> &mut Vec<BattleSide> {
|
|
||||||
&mut self.sides
|
|
||||||
}
|
|
||||||
/// The RNG used for the battle.
|
/// The RNG used for the battle.
|
||||||
pub fn random(&self) -> &BattleRandom {
|
pub fn random(&self) -> &BattleRandom {
|
||||||
&self.random
|
&self.random
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use parking_lot::lock_api::RwLockReadGuard;
|
use parking_lot::lock_api::RwLockReadGuard;
|
||||||
|
@ -35,7 +35,7 @@ pub struct BattleSide {
|
||||||
/// The number of choices that are set.
|
/// The number of choices that are set.
|
||||||
choices_set: AtomicU8,
|
choices_set: AtomicU8,
|
||||||
/// A reference to the battle we're part of.
|
/// A reference to the battle we're part of.
|
||||||
battle: *mut Battle,
|
battle: Weak<Battle>,
|
||||||
/// Whether or not this side has fled.
|
/// Whether or not this side has fled.
|
||||||
has_fled_battle: bool,
|
has_fled_battle: bool,
|
||||||
/// The volatile scripts that are attached to the side.
|
/// The volatile scripts that are attached to the side.
|
||||||
|
@ -68,7 +68,7 @@ impl BattleSide {
|
||||||
choices,
|
choices,
|
||||||
fillable_slots,
|
fillable_slots,
|
||||||
choices_set: AtomicU8::new(0),
|
choices_set: AtomicU8::new(0),
|
||||||
battle: std::ptr::null_mut::<Battle>(),
|
battle: Weak::new(),
|
||||||
has_fled_battle: false,
|
has_fled_battle: false,
|
||||||
volatile_scripts: Default::default(),
|
volatile_scripts: Default::default(),
|
||||||
script_source_data: Default::default(),
|
script_source_data: Default::default(),
|
||||||
|
@ -76,7 +76,7 @@ impl BattleSide {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the battle this side belongs to.
|
/// Set the battle this side belongs to.
|
||||||
pub(crate) fn set_battle(&mut self, battle: *mut Battle) {
|
pub(crate) fn set_battle(&mut self, battle: Weak<Battle>) {
|
||||||
self.battle = battle;
|
self.battle = battle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +106,10 @@ impl BattleSide {
|
||||||
self.choices_set.load(Ordering::SeqCst)
|
self.choices_set.load(Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
/// A reference to the battle we're part of.
|
/// A reference to the battle we're part of.
|
||||||
pub fn battle(&self) -> Result<&Battle> {
|
pub fn battle(&self) -> Result<Arc<Battle>> {
|
||||||
unsafe { self.battle.as_ref().ok_or(anyhow!("Battle was not set, but requested")) }
|
self.battle
|
||||||
|
.upgrade()
|
||||||
|
.ok_or(anyhow!("Battle was not set, but requested"))
|
||||||
}
|
}
|
||||||
/// Whether or not this side has fled.
|
/// Whether or not this side has fled.
|
||||||
pub fn has_fled_battle(&self) -> bool {
|
pub fn has_fled_battle(&self) -> bool {
|
||||||
|
@ -194,7 +196,7 @@ impl BattleSide {
|
||||||
&read_lock.get_res(index as usize)?.clone()
|
&read_lock.get_res(index as usize)?.clone()
|
||||||
};
|
};
|
||||||
if let Some(pokemon) = pokemon {
|
if let Some(pokemon) = pokemon {
|
||||||
pokemon.set_battle_data(self.battle, self.index);
|
pokemon.set_battle_data(self.battle.clone(), self.index);
|
||||||
pokemon.set_on_battlefield(true)?;
|
pokemon.set_on_battlefield(true)?;
|
||||||
pokemon.set_battle_index(index);
|
pokemon.set_battle_index(index);
|
||||||
|
|
||||||
|
@ -227,7 +229,7 @@ impl BattleSide {
|
||||||
/// Checks whether a Pokemon is on the field in this side.
|
/// Checks whether a Pokemon is on the field in this side.
|
||||||
pub fn is_pokemon_on_side(&self, pokemon: Arc<Pokemon>) -> bool {
|
pub fn is_pokemon_on_side(&self, pokemon: Arc<Pokemon>) -> bool {
|
||||||
for p in self.pokemon.read().iter().flatten() {
|
for p in self.pokemon.read().iter().flatten() {
|
||||||
if std::ptr::eq(p.deref().deref(), pokemon.deref()) {
|
if Arc::ptr_eq(p, &pokemon) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,7 +249,7 @@ impl BattleSide {
|
||||||
pub fn is_slot_unfillable(&self, pokemon: Arc<Pokemon>) -> Result<bool> {
|
pub fn is_slot_unfillable(&self, pokemon: Arc<Pokemon>) -> Result<bool> {
|
||||||
for (i, slot) in self.pokemon.read().iter().enumerate() {
|
for (i, slot) in self.pokemon.read().iter().enumerate() {
|
||||||
if let Some(p) = slot {
|
if let Some(p) = slot {
|
||||||
if std::ptr::eq(p.deref().deref(), pokemon.deref()) {
|
if Arc::ptr_eq(p, &pokemon) {
|
||||||
return Ok(self.fillable_slots.get_res(i)?.load(Ordering::Relaxed));
|
return Ok(self.fillable_slots.get_res(i)?.load(Ordering::Relaxed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,7 +292,8 @@ impl BattleSide {
|
||||||
// Fetch parties for the two indices.
|
// Fetch parties for the two indices.
|
||||||
let mut party_a = None;
|
let mut party_a = None;
|
||||||
let mut party_b = None;
|
let mut party_b = None;
|
||||||
for party in self.battle()?.parties() {
|
let battle = self.battle()?;
|
||||||
|
for party in battle.parties() {
|
||||||
if party.is_responsible_for_index(self.index, a) {
|
if party.is_responsible_for_index(self.index, a) {
|
||||||
party_a = Some(party);
|
party_a = Some(party);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use std::ops::Deref;
|
|
||||||
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU8, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU8, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -166,10 +165,10 @@ impl ExecutingMove {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a hit data for a target, with a specific index.
|
/// Gets a hit data for a target, with a specific index.
|
||||||
pub fn get_hit_data(&self, for_target: &Pokemon, hit: u8) -> Result<&HitData> {
|
pub fn get_hit_data(&self, for_target: &Arc<Pokemon>, hit: u8) -> Result<&HitData> {
|
||||||
for (index, target) in self.targets.iter().enumerate() {
|
for (index, target) in self.targets.iter().enumerate() {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if std::ptr::eq(target.deref().deref(), for_target.deref().deref()) {
|
if Arc::ptr_eq(target, for_target) {
|
||||||
let i = index * self.number_of_hits as usize + hit as usize;
|
let i = index * self.number_of_hits as usize + hit as usize;
|
||||||
return match self.hits.get(i) {
|
return match self.hits.get(i) {
|
||||||
Some(hit) => Ok(hit),
|
Some(hit) => Ok(hit),
|
||||||
|
@ -188,7 +187,7 @@ impl ExecutingMove {
|
||||||
/// Checks whether a Pokemon is a target for this move.
|
/// Checks whether a Pokemon is a target for this move.
|
||||||
pub fn is_pokemon_target(&self, pokemon: &Arc<Pokemon>) -> bool {
|
pub fn is_pokemon_target(&self, pokemon: &Arc<Pokemon>) -> bool {
|
||||||
for target in self.targets.iter().flatten() {
|
for target in self.targets.iter().flatten() {
|
||||||
if std::ptr::eq(target.deref().deref(), pokemon.deref().deref()) {
|
if Arc::ptr_eq(target, pokemon) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +198,7 @@ impl ExecutingMove {
|
||||||
pub(crate) fn get_index_of_target(&self, for_target: &Arc<Pokemon>) -> Result<usize> {
|
pub(crate) fn get_index_of_target(&self, for_target: &Arc<Pokemon>) -> Result<usize> {
|
||||||
for (index, target) in self.targets.iter().enumerate() {
|
for (index, target) in self.targets.iter().enumerate() {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if std::ptr::eq(target.deref().deref(), for_target.deref().deref()) {
|
if Arc::ptr_eq(target, for_target) {
|
||||||
let i = index * self.number_of_hits as usize;
|
let i = index * self.number_of_hits as usize;
|
||||||
return Ok(i);
|
return Ok(i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use anyhow::Result;
|
|
||||||
use std::sync::atomic::{AtomicU8, Ordering};
|
use std::sync::atomic::{AtomicU8, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -81,7 +80,7 @@ impl LearnedMove {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Restore the remaining PP by a certain amount. Will prevent it from going above max PP.
|
/// Restore the remaining PP by a certain amount. Will prevent it from going above max PP.
|
||||||
pub fn restore_uses(&self, mut uses: u8) -> Result<()> {
|
pub fn restore_uses(&self, mut uses: u8) {
|
||||||
self.remaining_pp
|
self.remaining_pp
|
||||||
.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
|
.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
|
||||||
if x + uses > self.max_pp {
|
if x + uses > self.max_pp {
|
||||||
|
@ -90,7 +89,6 @@ impl LearnedMove {
|
||||||
Some(x + uses)
|
Some(x + uses)
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +111,7 @@ mod tests {
|
||||||
let data: Arc<dyn MoveData> = Arc::new(mock);
|
let data: Arc<dyn MoveData> = Arc::new(mock);
|
||||||
let learned_move = LearnedMove::new(data, MoveLearnMethod::Level);
|
let learned_move = LearnedMove::new(data, MoveLearnMethod::Level);
|
||||||
assert!(learned_move.try_use(15));
|
assert!(learned_move.try_use(15));
|
||||||
learned_move.restore_uses(5).unwrap();
|
learned_move.restore_uses(5);
|
||||||
assert_eq!(20, learned_move.remaining_pp());
|
assert_eq!(20, learned_move.remaining_pp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU8, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU8, Ordering};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
@ -26,7 +27,6 @@ use crate::{script_hook, PkmnError, StringKey, ValueIdentifiable, ValueIdentifie
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
|
|
||||||
/// An individual Pokemon as we know and love them.
|
/// An individual Pokemon as we know and love them.
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Pokemon {
|
pub struct Pokemon {
|
||||||
/// A unique identifier so we know what value this is.
|
/// A unique identifier so we know what value this is.
|
||||||
identifier: ValueIdentifier,
|
identifier: ValueIdentifier,
|
||||||
|
@ -392,10 +392,10 @@ impl Pokemon {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the battle the battle is currently in.
|
/// Gets the battle the battle is currently in.
|
||||||
pub fn get_battle(&self) -> Option<&Battle> {
|
pub fn get_battle(&self) -> Option<Arc<Battle>> {
|
||||||
let r = self.battle_data.read();
|
let r = self.battle_data.read();
|
||||||
if let Some(data) = &r.deref() {
|
if let Some(data) = &r.deref() {
|
||||||
unsafe { data.battle.as_ref() }
|
data.battle.upgrade()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -480,13 +480,8 @@ impl Pokemon {
|
||||||
// If we're in battle, use the battle random for predictability
|
// If we're in battle, use the battle random for predictability
|
||||||
let r = self.battle_data.read();
|
let r = self.battle_data.read();
|
||||||
if let Some(data) = r.deref() {
|
if let Some(data) = r.deref() {
|
||||||
let mut random = match data
|
let battle = data.battle().ok_or(anyhow!("Battle not set"))?;
|
||||||
.battle()
|
let mut random = match battle.random().get_rng().lock() {
|
||||||
.ok_or(anyhow!("Battle not set"))?
|
|
||||||
.random()
|
|
||||||
.get_rng()
|
|
||||||
.lock()
|
|
||||||
{
|
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(_) => return Err(PkmnError::UnableToAcquireLock.into()),
|
Err(_) => return Err(PkmnError::UnableToAcquireLock.into()),
|
||||||
};
|
};
|
||||||
|
@ -585,7 +580,7 @@ impl Pokemon {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the current battle the Pokemon is in.
|
/// Sets the current battle the Pokemon is in.
|
||||||
pub fn set_battle_data(&self, battle: *mut Battle, battle_side_index: u8) {
|
pub fn set_battle_data(&self, battle: Weak<Battle>, battle_side_index: u8) {
|
||||||
let mut w = self.battle_data.write();
|
let mut w = self.battle_data.write();
|
||||||
if let Some(battle_data) = w.deref_mut() {
|
if let Some(battle_data) = w.deref_mut() {
|
||||||
battle_data.battle = battle;
|
battle_data.battle = battle;
|
||||||
|
@ -770,7 +765,7 @@ impl Pokemon {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PokemonBattleData {
|
pub struct PokemonBattleData {
|
||||||
/// The battle data of the Pokemon
|
/// The battle data of the Pokemon
|
||||||
battle: *mut Battle,
|
battle: Weak<Battle>,
|
||||||
/// The index of the side of the Pokemon
|
/// The index of the side of the Pokemon
|
||||||
battle_side_index: AtomicU8,
|
battle_side_index: AtomicU8,
|
||||||
/// The index of the slot on the side of the Pokemon.
|
/// The index of the slot on the side of the Pokemon.
|
||||||
|
@ -783,12 +778,12 @@ pub struct PokemonBattleData {
|
||||||
|
|
||||||
impl PokemonBattleData {
|
impl PokemonBattleData {
|
||||||
/// The battle data of the Pokemon
|
/// The battle data of the Pokemon
|
||||||
pub fn battle_mut(&mut self) -> Option<&mut Battle> {
|
pub fn battle_mut(&mut self) -> Option<Arc<Battle>> {
|
||||||
unsafe { self.battle.as_mut() }
|
self.battle.upgrade()
|
||||||
}
|
}
|
||||||
/// The battle data of the Pokemon
|
/// The battle data of the Pokemon
|
||||||
pub fn battle(&self) -> Option<&Battle> {
|
pub fn battle(&self) -> Option<Arc<Battle>> {
|
||||||
unsafe { self.battle.as_ref() }
|
self.battle.upgrade()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The index of the side of the Pokemon
|
/// The index of the side of the Pokemon
|
||||||
|
@ -876,6 +871,18 @@ pub enum DamageSource {
|
||||||
Struggle = 2,
|
Struggle = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for Pokemon {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_str("Pokemon(")?;
|
||||||
|
write!(f, "Species: {}, ", self.species().name())?;
|
||||||
|
write!(f, "Form: {}, ", self.form().name())?;
|
||||||
|
write!(f, "Level: {}, ", self.level())?;
|
||||||
|
|
||||||
|
f.write_str(")")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::unwrap_used)]
|
||||||
pub mod test {
|
pub mod test {
|
||||||
|
|
|
@ -19,7 +19,7 @@ extern "C" fn battle_new(
|
||||||
// NOTE: Split into two due to u128 not being ABI safe: https://github.com/rust-lang/rust/issues/54341
|
// NOTE: Split into two due to u128 not being ABI safe: https://github.com/rust-lang/rust/issues/54341
|
||||||
random_seed_1: u64,
|
random_seed_1: u64,
|
||||||
random_seed_2: u64,
|
random_seed_2: u64,
|
||||||
) -> IdentifiablePointer<Battle> {
|
) -> IdentifiablePointer<Arc<Battle>> {
|
||||||
let parties = unsafe {
|
let parties = unsafe {
|
||||||
std::slice::from_raw_parts(parties, parties_length)
|
std::slice::from_raw_parts(parties, parties_length)
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -34,14 +34,14 @@ extern "C" fn battle_new(
|
||||||
};
|
};
|
||||||
let random_seed = if random_seed == 0 { None } else { Some(random_seed) };
|
let random_seed = if random_seed == 0 { None } else { Some(random_seed) };
|
||||||
|
|
||||||
Box::new(Battle::new(
|
Battle::new(
|
||||||
library.as_ref().clone(),
|
library.as_ref().clone(),
|
||||||
parties,
|
parties,
|
||||||
can_flee == 1,
|
can_flee == 1,
|
||||||
number_of_sides,
|
number_of_sides,
|
||||||
pokemon_per_side,
|
pokemon_per_side,
|
||||||
random_seed,
|
random_seed,
|
||||||
))
|
)
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -251,9 +251,9 @@ extern "C" fn pokemon_set_effort_value(
|
||||||
/// Gets the data for the battle the Pokemon is currently in. If the Pokemon is not in a battle, this
|
/// Gets the data for the battle the Pokemon is currently in. If the Pokemon is not in a battle, this
|
||||||
/// returns null.
|
/// returns null.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_get_battle(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Battle> {
|
extern "C" fn pokemon_get_battle(ptr: ExternPointer<Arc<Pokemon>>) -> IdentifiablePointer<Arc<Battle>> {
|
||||||
if let Some(v) = ptr.as_ref().get_battle() {
|
if let Some(v) = ptr.as_ref().get_battle() {
|
||||||
(v as *const Battle).into()
|
v.into()
|
||||||
} else {
|
} else {
|
||||||
IdentifiablePointer::none()
|
IdentifiablePointer::none()
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#![allow(clippy::borrowed_box)]
|
#![allow(clippy::borrowed_box)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
#![allow(ambiguous_glob_reexports)]
|
#![allow(ambiguous_glob_reexports)]
|
||||||
|
#![allow(hidden_glob_reexports)]
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
#![deny(clippy::missing_docs_in_private_items)]
|
#![deny(clippy::missing_docs_in_private_items)]
|
||||||
// Linter rules to prevent panics
|
// Linter rules to prevent panics
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
use crate::dynamic_data::{
|
use crate::dynamic_data::{
|
||||||
Battle, BattleParty, BattleRandom, BattleResult, BattleSide, ChoiceQueue, DynamicLibrary, Pokemon, PokemonParty,
|
Battle, BattleParty, BattleRandom, BattleResult, BattleSide, ChoiceQueue, DynamicLibrary, Pokemon, PokemonParty,
|
||||||
};
|
};
|
||||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||||
|
get_value, get_value_arc, get_value_call_getter, try_wasm,
|
||||||
|
};
|
||||||
|
use crate::script_implementations::wasm::export_registry::{register, wasm_ok, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
|
use anyhow_ext::Context;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
|
@ -12,59 +16,66 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(battle.value_func(&env)?.pokemon_per_side()).into()
|
let value = get_value_call_getter!(battle.pokemon_per_side(), env);
|
||||||
|
wasm_ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_parties(
|
fn battle_get_parties(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<VecExternRef<BattleParty>> {
|
) -> WasmResult<VecExternRef<BattleParty>> {
|
||||||
Ok(VecExternRef::new(env.data().data().as_ref(), battle.value_func(&env)?.parties())).into()
|
let parties = get_value_call_getter!(battle.parties(), env);
|
||||||
|
wasm_ok(VecExternRef::new(env.data().data().as_ref(), parties))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_choice_queue(
|
fn battle_get_choice_queue(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<ExternRef<ChoiceQueue>> {
|
) -> WasmResult<ExternRef<ChoiceQueue>> {
|
||||||
let queue = battle.value_func(&env)?.current_turn_queue().read();
|
let value = get_value_call_getter!(battle.current_turn_queue(), env);
|
||||||
Ok(if let Some(queue) = queue.as_ref() {
|
let queue = value.read();
|
||||||
ExternRef::func_new(&env, queue)
|
wasm_ok(if let Some(queue) = queue.as_ref() {
|
||||||
|
ExternRef::<ChoiceQueue>::func_new(&env, queue)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_library(
|
fn battle_get_library(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<ExternRef<dyn DynamicLibrary>> {
|
) -> WasmResult<ExternRef<dyn DynamicLibrary>> {
|
||||||
Ok(ExternRef::func_new(&env, &battle.value_func(&env)?.library().clone())).into()
|
let value = get_value_call_getter!(battle.library(), env);
|
||||||
|
wasm_ok(ExternRef::<dyn DynamicLibrary>::func_new(&env, &value.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_sides(
|
fn battle_get_sides(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<VecExternRef<BattleSide>> {
|
) -> WasmResult<VecExternRef<BattleSide>> {
|
||||||
Ok(VecExternRef::new(env.data().data().as_ref(), battle.value_func(&env)?.sides())).into()
|
let value = get_value_arc!(battle, env);
|
||||||
|
wasm_ok(VecExternRef::new(env.data().data().as_ref(), value.sides()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_random(
|
fn battle_get_random(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<ExternRef<BattleRandom>> {
|
) -> WasmResult<ExternRef<BattleRandom>> {
|
||||||
Ok(ExternRef::func_new(&env, battle.value_func(&env)?.random())).into()
|
let random = get_value_call_getter!(battle.random(), env);
|
||||||
|
wasm_ok(ExternRef::<BattleRandom>::func_new(&env, random))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_weather_name(
|
fn battle_get_weather_name(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<ExternRef<StringKey>> {
|
) -> WasmResult<ExternRef<StringKey>> {
|
||||||
let weather = battle.value_func(&env)?.weather_name()?;
|
let weather = get_value_call_getter!(battle.weather_name(), env);
|
||||||
Ok(if let Some(weather) = weather {
|
let weather = try_wasm!(weather, env);
|
||||||
ExternRef::func_new(&env, &weather)
|
wasm_ok(if let Some(weather) = weather {
|
||||||
|
ExternRef::<StringKey>::func_new(&env, &weather)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_find_party_for_pokemon(
|
fn battle_find_party_for_pokemon(
|
||||||
|
@ -72,14 +83,14 @@ register! {
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
pokemon: ExternRef<Pokemon>
|
pokemon: ExternRef<Pokemon>
|
||||||
) -> WasmResult<ExternRef<BattleParty>> {
|
) -> WasmResult<ExternRef<BattleParty>> {
|
||||||
let battle = battle.value_func(&env)?;
|
let battle = get_value!(battle, env);
|
||||||
let pokemon = pokemon.value_func(&env)?;
|
let pokemon = get_value!(pokemon, env);
|
||||||
for party in battle.parties() {
|
for party in battle.parties() {
|
||||||
if party.party().has_pokemon(pokemon) {
|
if party.party().has_pokemon(pokemon) {
|
||||||
return Ok(ExternRef::func_new(&env, party)).into();
|
return wasm_ok(ExternRef::<BattleParty>::func_new(&env, party));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(ExternRef::null()).into()
|
wasm_ok(ExternRef::<BattleParty>::null())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_pokemon(
|
fn battle_get_pokemon(
|
||||||
|
@ -87,65 +98,68 @@ register! {
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
side: u8, index: u8
|
side: u8, index: u8
|
||||||
) -> WasmResult<ExternRef<Pokemon>> {
|
) -> WasmResult<ExternRef<Pokemon>> {
|
||||||
let battle = battle.value_func(&env)?;
|
let battle = get_value!(battle, env);
|
||||||
let pokemon = battle.get_pokemon(side, index);
|
let pokemon = battle.get_pokemon(side, index);
|
||||||
Ok(if let Some(pokemon) = pokemon {
|
wasm_ok(if let Some(pokemon) = pokemon {
|
||||||
ExternRef::func_new(&env, &pokemon)
|
ExternRef::<Pokemon>::func_new(&env, &pokemon)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_can_flee(
|
fn battle_get_can_flee(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if battle.value_func(&env)?.can_flee() { 1 } else { 0 }).into()
|
wasm_ok(if get_value_call_getter!(battle.can_flee(), env) { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_number_of_sides(
|
fn battle_get_number_of_sides(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(battle.value_func(&env)?.number_of_sides()).into()
|
wasm_ok(get_value_call_getter!(battle.number_of_sides(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_has_ended(
|
fn battle_get_has_ended(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if battle.value_func(&env)?.has_ended() { 1 } else { 0 }).into()
|
wasm_ok(if get_value_call_getter!(battle.has_ended(), env) { 1u8 } else { 0u8 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_has_ended_conclusively(
|
fn battle_get_has_ended_conclusively(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if battle.value_func(&env)?.result().is_conclusive() { 1 } else { 0 }).into()
|
let value = get_value_call_getter!(battle.result(), env);
|
||||||
|
wasm_ok(if value.is_conclusive() { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_winning_side(
|
fn battle_get_winning_side(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if let BattleResult::Conclusive(result) = battle.value_func(&env)?.result() {
|
let value = get_value_call_getter!(battle.result(), env);
|
||||||
|
wasm_ok(if let BattleResult::Conclusive(result) = value {
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_get_current_turn(
|
fn battle_get_current_turn(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle: ExternRef<Battle>,
|
battle: ExternRef<Battle>,
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
Ok(battle.value_func(&env)?.current_turn()).into()
|
wasm_ok(get_value_call_getter!(battle.current_turn(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_party_get_party(
|
fn battle_party_get_party(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle_party: ExternRef<BattleParty>,
|
battle_party: ExternRef<BattleParty>,
|
||||||
) -> WasmResult<ExternRef<PokemonParty>> {
|
) -> WasmResult<ExternRef<PokemonParty>> {
|
||||||
Ok(ExternRef::func_new(&env, battle_party.value_func(&env)?.party().as_ref())).into()
|
let value = get_value_call_getter!(battle_party.party(), env);
|
||||||
|
wasm_ok(ExternRef::<PokemonParty>::func_new(&env, value.as_ref()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,31 @@
|
||||||
use crate::dynamic_data::BattleRandom;
|
use crate::dynamic_data::BattleRandom;
|
||||||
|
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||||
|
get_value, get_value_call_getter, try_wasm, wasm_ok,
|
||||||
|
};
|
||||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
use anyhow_ext::Context;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
fn battle_random_get(
|
fn battle_random_get(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle_random: ExternRef<BattleRandom>,
|
battle_random: ExternRef<BattleRandom>,
|
||||||
) -> WasmResult<i32> {
|
) -> WasmResult<i32> {
|
||||||
battle_random.value_func(&env)?.get().into()
|
let v = get_value_call_getter!(battle_random.get(), env);
|
||||||
|
let v = try_wasm!(v, env);
|
||||||
|
wasm_ok(v)
|
||||||
}
|
}
|
||||||
fn battle_random_get_max(
|
fn battle_random_get_max(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
battle_random: ExternRef<BattleRandom>,
|
battle_random: ExternRef<BattleRandom>,
|
||||||
max: i32
|
max: i32
|
||||||
) -> WasmResult<i32> {
|
) -> WasmResult<i32> {
|
||||||
battle_random.value_func(&env)?.get_max(max).into()
|
let battle_random = get_value!(battle_random, env);
|
||||||
|
let v = try_wasm!(battle_random.get_max(max), env);
|
||||||
|
wasm_ok(v)
|
||||||
}
|
}
|
||||||
fn battle_random_get_between(
|
fn battle_random_get_between(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
|
@ -25,6 +33,8 @@ register! {
|
||||||
min: i32,
|
min: i32,
|
||||||
max: i32
|
max: i32
|
||||||
) -> WasmResult<i32> {
|
) -> WasmResult<i32> {
|
||||||
battle_random.value_func(&env)?.get_between(min, max).into()
|
let battle_random = get_value!(battle_random, env);
|
||||||
|
let v = try_wasm!(battle_random.get_between(min, max), env);
|
||||||
|
wasm_ok(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
use crate::dynamic_data::{Battle, BattleSide, Pokemon, VolatileScriptsOwner};
|
use crate::dynamic_data::{Battle, BattleSide, Pokemon, ScriptCategory, VolatileScriptsOwner};
|
||||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||||
|
get_value, get_value_call_getter, try_wasm, wasm_ok, WasmVoidResultExtension,
|
||||||
|
};
|
||||||
|
use crate::script_implementations::wasm::export_registry::{register, wasm_err, WasmResult, WasmVoidResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::ScriptCategory;
|
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
use anyhow_ext::Context;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
|
@ -13,35 +16,37 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(u8::from(side.value_func(&env)?.has_fled_battle())).into()
|
wasm_ok(u8::from(get_value_call_getter!(side.has_fled_battle(), env)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_is_defeated(
|
fn battleside_is_defeated(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(u8::from(side.value_func(&env)?.is_defeated())).into()
|
wasm_ok(u8::from(get_value_call_getter!(side.is_defeated(), env)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_get_side_index(
|
fn battleside_get_side_index(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(side.value_func(&env)?.index()).into()
|
wasm_ok(get_value_call_getter!(side.index(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_get_pokemon_per_side(
|
fn battleside_get_pokemon_per_side(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(side.value_func(&env)?.pokemon_per_side()).into()
|
wasm_ok(get_value_call_getter!(side.pokemon_per_side(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_get_battle(
|
fn battleside_get_battle(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> WasmResult<ExternRef<Battle>> {
|
) -> WasmResult<ExternRef<Battle>> {
|
||||||
Ok(ExternRef::func_new(&env, side.value_func(&env)?.battle()?)).into()
|
let value = get_value_call_getter!(side.battle(), env);
|
||||||
|
let value = try_wasm!(value, env);
|
||||||
|
wasm_ok(ExternRef::func_new(&env, &value))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_get_pokemon(
|
fn battleside_get_pokemon(
|
||||||
|
@ -49,25 +54,26 @@ register! {
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
index: u32
|
index: u32
|
||||||
) -> WasmResult<ExternRef<Pokemon>> {
|
) -> WasmResult<ExternRef<Pokemon>> {
|
||||||
Ok(if let Some(Some(p)) = side.value_func(&env)?.pokemon().get(index as usize) {
|
let side = get_value!(side, env);
|
||||||
ExternRef::func_new(&env, p.as_ref())
|
wasm_ok(if let Some(Some(p)) = side.pokemon().get(index as usize) {
|
||||||
|
ExternRef::<Pokemon>::func_new(&env, p.as_ref())
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_side_get_has_fled_battle(
|
fn battle_side_get_has_fled_battle(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if side.value_func(&env)?.has_fled_battle() { 1 } else { 0 }).into()
|
wasm_ok(if get_value_call_getter!(side.has_fled_battle(), env) { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battle_side_get_is_defeated(
|
fn battle_side_get_is_defeated(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if side.value_func(&env)?.is_defeated() { 1 } else { 0 }).into()
|
wasm_ok(if get_value_call_getter!(side.is_defeated(), env) { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn battleside_add_volatile_by_name(
|
fn battleside_add_volatile_by_name(
|
||||||
|
@ -76,14 +82,15 @@ register! {
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let side = get_value!(side, env);
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
let script = side.value_func(&env)?.add_volatile_script(&c_name.as_ref().into())?;
|
let script = try_wasm!(side.add_volatile_script(&c_name.as_ref().into()), env);
|
||||||
Ok(if let Some(script) = script {
|
wasm_ok(if let Some(script) = script {
|
||||||
let script = script.get_as::<WebAssemblyScript>()?;
|
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
||||||
script.get_wasm_pointer()
|
script.get_wasm_pointer()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,27 +99,28 @@ register! {
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
script_ptr: u32
|
script_ptr: u32
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
let side : &BattleSide = side.value_func(&env)?;
|
let side : &BattleSide = get_value!(side, env);
|
||||||
unsafe {
|
unsafe {
|
||||||
let env = env.data().data();
|
let e = env.data().data();
|
||||||
let name_ptr = match env
|
let name_func = try_wasm!(e.script_function_cache().script_get_name(&e), env);
|
||||||
.script_function_cache()
|
let name_ptr = try_wasm!(name_func.call(&mut e.store_mut(), script_ptr), env);
|
||||||
.script_get_name(&env)?
|
let c_name: &CStr = CStr::from_ptr(e.get_raw_pointer(name_ptr));
|
||||||
.call(&mut env.store_mut(), script_ptr) {
|
let script = try_wasm!(e.setup_script(script_ptr, ScriptCategory::Side, &c_name.as_ref().into(), side.into()), env);
|
||||||
Ok(name_ptr) => Ok(name_ptr),
|
try_wasm!(e.script_function_cache().dealloc_cstring(&e, name_ptr), env);
|
||||||
Err(e) => Err(e.into())
|
|
||||||
}?;
|
|
||||||
let c_name: &CStr = CStr::from_ptr(env.get_raw_pointer(name_ptr));
|
|
||||||
let script = env.setup_script(script_ptr, ScriptCategory::Side, &c_name.as_ref().into(), side.into())?;
|
|
||||||
env.script_function_cache().dealloc_cstring(&env, name_ptr)?;
|
|
||||||
|
|
||||||
Ok(if let Some(script) = script {
|
if let Some(script) = script {
|
||||||
let script = side.add_volatile_script_with_script(script)?;
|
let script = try_wasm!(side.add_volatile_script_with_script(script), env);
|
||||||
let s = script.as_ref().ok_or(anyhow!("Couldn't get script"))?.get_as::<WebAssemblyScript>()?;
|
let script = script.as_ref();
|
||||||
s.get_wasm_pointer()
|
match script {
|
||||||
|
Some(script) => {
|
||||||
|
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
||||||
|
wasm_ok(script.get_wasm_pointer())
|
||||||
|
},
|
||||||
|
None => wasm_err::<u32>(anyhow!("Couldn't get script"), &env)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
0
|
wasm_ok(0)
|
||||||
}).into()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,8 +130,9 @@ register! {
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let side = get_value!(side, env);
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
Ok(u8::from(side.value_func(&env)?.has_volatile_script(&c_name.as_ref().into()))).into()
|
wasm_ok(u8::from(side.has_volatile_script(&c_name.as_ref().into())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,14 +142,15 @@ register! {
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let side = get_value!(side, env);
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
let script = side.value_func(&env)?.get_volatile_script(&c_name.as_ref().into());
|
let script = side.get_volatile_script(&c_name.as_ref().into());
|
||||||
Ok(if let Some(script) = script {
|
if let Some(script) = script {
|
||||||
let script = script.get_as::<WebAssemblyScript>()?;
|
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
||||||
script.get_wasm_pointer()
|
wasm_ok(script.get_wasm_pointer())
|
||||||
} else {
|
} else {
|
||||||
0
|
wasm_ok(0)
|
||||||
}).into()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,10 +158,17 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
side: ExternRef<BattleSide>,
|
side: ExternRef<BattleSide>,
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> WasmResult<()> {
|
) -> WasmVoidResult {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let side = match side.value_func(&env) {
|
||||||
|
Ok(side) => side,
|
||||||
|
Err(e) => return WasmVoidResult::err(e, &env)
|
||||||
|
};
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
side.value_func(&env)?.remove_volatile_script(&c_name.as_ref().into()).into()
|
match side.remove_volatile_script(&c_name.as_ref().into()) {
|
||||||
|
Ok(_) => WasmVoidResult::ok(),
|
||||||
|
Err(e) => WasmVoidResult::err(e, &env)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::dynamic_data::{ChoiceQueue, Pokemon};
|
use crate::dynamic_data::{ChoiceQueue, Pokemon};
|
||||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
use crate::script_implementations::wasm::export_registry::{get_value, register, try_wasm, wasm_ok, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
use anyhow_ext::Context;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
|
@ -10,6 +11,9 @@ register! {
|
||||||
battle_random: ExternRef<ChoiceQueue>,
|
battle_random: ExternRef<ChoiceQueue>,
|
||||||
pokemon: ExternRef<Pokemon>
|
pokemon: ExternRef<Pokemon>
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(u8::from(battle_random.value_func(&env)?.move_pokemon_choice_next(pokemon.value_func(&env)?)?)).into()
|
let battle_random = get_value!(battle_random, env);
|
||||||
|
let pokemon = get_value!(pokemon, env);
|
||||||
|
let res = try_wasm!(battle_random.move_pokemon_choice_next(pokemon), env);
|
||||||
|
wasm_ok(u8::from(res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
use crate::dynamic_data::{ExecutingMove, HitData, LearnedMove, Pokemon};
|
use crate::dynamic_data::{ExecutingMove, HitData, LearnedMove, Pokemon};
|
||||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
use crate::script_implementations::wasm::export_registry::wasm_result::get_value_arc;
|
||||||
|
use crate::script_implementations::wasm::export_registry::{
|
||||||
|
get_value, get_value_call_getter, register, try_wasm, wasm_ok, WasmResult,
|
||||||
|
};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::MoveData;
|
use crate::static_data::MoveData;
|
||||||
|
use anyhow_ext::Context;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
|
@ -11,28 +15,31 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> WasmResult<ExternRef<Pokemon>> {
|
) -> WasmResult<ExternRef<Pokemon>> {
|
||||||
Ok(ExternRef::func_new(&env, executing_move.value_func(&env)?.user().as_ref())).into()
|
let user = get_value_call_getter!(executing_move.user(), env);
|
||||||
|
wasm_ok(ExternRef::<Pokemon>::func_new(&env, user.as_ref()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_get_use_move(
|
fn executing_move_get_use_move(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> WasmResult<ExternRef<dyn MoveData>> {
|
) -> WasmResult<ExternRef<dyn MoveData>> {
|
||||||
Ok(ExternRef::func_new(&env, executing_move.value_func(&env)?.use_move())).into()
|
let use_move = get_value_call_getter!(executing_move.use_move(), env);
|
||||||
|
wasm_ok(ExternRef::<dyn MoveData>::func_new(&env, use_move))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_get_chosen_move(
|
fn executing_move_get_chosen_move(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> WasmResult<ExternRef<LearnedMove>> {
|
) -> WasmResult<ExternRef<LearnedMove>> {
|
||||||
Ok(ExternRef::func_new(&env, executing_move.value_func(&env)?.chosen_move().as_ref())).into()
|
let chosen_move = get_value_call_getter!(executing_move.chosen_move(), env);
|
||||||
|
wasm_ok(ExternRef::<LearnedMove>::func_new(&env, chosen_move.as_ref()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_get_number_of_hits(
|
fn executing_move_get_number_of_hits(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(executing_move.value_func(&env)?.number_of_hits()).into()
|
wasm_ok(get_value_call_getter!(executing_move.number_of_hits(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_get_hit_data(
|
fn executing_move_get_hit_data(
|
||||||
|
@ -41,14 +48,17 @@ register! {
|
||||||
target: ExternRef<Pokemon>,
|
target: ExternRef<Pokemon>,
|
||||||
hit: u8
|
hit: u8
|
||||||
) -> WasmResult<ExternRef<HitData>> {
|
) -> WasmResult<ExternRef<HitData>> {
|
||||||
Ok(ExternRef::func_new(&env, executing_move.value_func(&env)?.get_hit_data(target.value_func(&env)?, hit)?)).into()
|
let executing_move = get_value!(executing_move, env);
|
||||||
|
let target = get_value_arc!(target, env);
|
||||||
|
let hit_data = try_wasm!(executing_move.get_hit_data(&target, hit), env);
|
||||||
|
wasm_ok(ExternRef::<HitData>::func_new(&env, hit_data))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_get_number_of_targets(
|
fn executing_move_get_number_of_targets(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
Ok(executing_move.value_func(&env)?.target_count() as u32).into()
|
wasm_ok(get_value_call_getter!(executing_move.target_count(), env) as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn executing_move_is_pokemon_target(
|
fn executing_move_is_pokemon_target(
|
||||||
|
@ -56,8 +66,9 @@ register! {
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
pokemon: ExternRef<Pokemon>
|
pokemon: ExternRef<Pokemon>
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
let pokemon = pokemon.value_func_arc(&env)?;
|
let executing_move = get_value!(executing_move, env);
|
||||||
Ok(if executing_move.value_func(&env)?.is_pokemon_target(&pokemon) { 1 } else { 0 }).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
wasm_ok(if executing_move.is_pokemon_target(&pokemon) { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,14 +76,15 @@ register! {
|
||||||
fn executing_move_get_script(
|
fn executing_move_get_script(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
executing_move: ExternRef<ExecutingMove>,
|
executing_move: ExternRef<ExecutingMove>,
|
||||||
) -> WasmResult<(u32 , u32)> {
|
) -> WasmResult<u32> {
|
||||||
let executing_move = executing_move.value_func(&env)?;
|
let executing_move = get_value!(executing_move, env);
|
||||||
let script = executing_move.script();
|
let script = executing_move.script();
|
||||||
if script.is_any() {
|
if script.is_any() {
|
||||||
let s = script.get_as::<WebAssemblyScript>()?.get_wasm_pointer();
|
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
||||||
return Ok((s, s + 4)).into()
|
let s = script.get_wasm_pointer();
|
||||||
|
return wasm_ok(s)
|
||||||
}
|
}
|
||||||
Ok((0, 0)).into()
|
wasm_ok(0u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,82 +1,97 @@
|
||||||
use crate::dynamic_data::HitData;
|
use crate::dynamic_data::HitData;
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||||
|
get_value_call_getter, get_value_void, wasm_ok, WasmVoidResultExtension,
|
||||||
|
};
|
||||||
|
use crate::script_implementations::wasm::export_registry::{register, WasmResult, WasmVoidResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
use anyhow_ext::Context;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
fn hit_data_get_damage(
|
fn hit_data_get_damage(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
hit.value_func(&env).unwrap().damage()
|
wasm_ok(get_value_call_getter!(hit.damage(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_data_is_critical(
|
fn hit_data_is_critical(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
u8::from(hit.value_func(&env).unwrap().is_critical())
|
let is_critical = get_value_call_getter!(hit.is_critical(), env);
|
||||||
|
wasm_ok(u8::from(is_critical))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_data_fail(
|
fn hit_data_fail(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
) {
|
) -> WasmVoidResult {
|
||||||
hit.value_func(&env).unwrap().fail()
|
let hit = get_value_void!(hit, env);
|
||||||
|
hit.fail();
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_data_get_base_power(
|
fn hit_data_get_base_power(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
hit.value_func(&env).unwrap().base_power()
|
wasm_ok(get_value_call_getter!(hit.base_power(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_data_get_effectiveness(
|
fn hit_data_get_effectiveness(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
) -> f32 {
|
) -> WasmResult<f32> {
|
||||||
hit.value_func(&env).unwrap().effectiveness()
|
wasm_ok(get_value_call_getter!(hit.effectiveness(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_data_get_move_type(
|
fn hit_data_get_move_type(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
hit.value_func(&env).unwrap().move_type().into()
|
wasm_ok(get_value_call_getter!(hit.move_type(), env).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_data_set_critical(
|
fn hit_data_set_critical(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
value: u8
|
value: u8
|
||||||
) {
|
) -> WasmVoidResult {
|
||||||
hit.value_func(&env).unwrap().set_critical(value == 1)
|
let hit = get_value_void!(hit, env);
|
||||||
|
hit.set_critical(value == 1);
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_data_set_effectiveness(
|
fn hit_data_set_effectiveness(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
effectiveness: f32
|
effectiveness: f32
|
||||||
) {
|
) -> WasmVoidResult {
|
||||||
hit.value_func(&env).unwrap().set_effectiveness(effectiveness)
|
let hit = get_value_void!(hit, env);
|
||||||
|
hit.set_effectiveness(effectiveness);
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_data_set_damage(
|
fn hit_data_set_damage(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
damage: u32
|
damage: u32
|
||||||
) {
|
) -> WasmVoidResult {
|
||||||
hit.value_func(&env).unwrap().set_damage(damage)
|
let hit = get_value_void!(hit, env);
|
||||||
|
hit.set_damage(damage);
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_data_set_move_type(
|
fn hit_data_set_move_type(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
hit: ExternRef<HitData>,
|
hit: ExternRef<HitData>,
|
||||||
move_type: u8
|
move_type: u8
|
||||||
) {
|
) -> WasmVoidResult {
|
||||||
hit.value_func(&env).unwrap().set_move_type(move_type.into())
|
let hit = get_value_void!(hit, env);
|
||||||
|
hit.set_move_type(move_type.into());
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,42 +1,52 @@
|
||||||
use std::intrinsics::transmute;
|
use std::intrinsics::transmute;
|
||||||
|
|
||||||
use crate::dynamic_data::LearnedMove;
|
use crate::dynamic_data::{LearnedMove, MoveLearnMethod};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||||
|
get_value_call_getter, get_value_void, wasm_ok, WasmVoidResult, WasmVoidResultExtension,
|
||||||
|
};
|
||||||
|
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::MoveData;
|
use crate::static_data::MoveData;
|
||||||
|
use anyhow_ext::Context;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
fn learned_move_get_learn_method(
|
fn learned_move_get_learn_method(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<LearnedMove>,
|
turn_choice: ExternRef<LearnedMove>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
unsafe {
|
unsafe {
|
||||||
transmute(turn_choice.value_func(&env).unwrap().learn_method())
|
let learn_method = get_value_call_getter!(turn_choice.learn_method(), &env);
|
||||||
|
wasm_ok(transmute::<MoveLearnMethod, u8>(learn_method))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn learned_move_get_move_data(
|
fn learned_move_get_move_data(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<LearnedMove>,
|
turn_choice: ExternRef<LearnedMove>,
|
||||||
) -> ExternRef<dyn MoveData> {
|
) -> WasmResult<ExternRef<dyn MoveData>> {
|
||||||
ExternRef::func_new(&env, turn_choice.value_func(&env).unwrap().move_data())
|
let move_data = get_value_call_getter!(turn_choice.move_data(), &env);
|
||||||
|
wasm_ok(ExternRef::<dyn MoveData>::func_new(&env, move_data))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn learned_move_restore_all_uses(
|
fn learned_move_restore_all_uses(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<LearnedMove>,
|
turn_choice: ExternRef<LearnedMove>,
|
||||||
) {
|
) -> WasmVoidResult {
|
||||||
turn_choice.value_func(&env).unwrap().restore_all_uses();
|
let turn_choice = get_value_void!(turn_choice, env);
|
||||||
|
turn_choice.restore_all_uses();
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn learned_move_restore_uses(
|
fn learned_move_restore_uses(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<LearnedMove>,
|
turn_choice: ExternRef<LearnedMove>,
|
||||||
amount: u8,
|
amount: u8,
|
||||||
) {
|
) -> WasmVoidResult {
|
||||||
turn_choice.value_func(&env).unwrap().restore_uses(amount).unwrap();
|
let turn_choice = get_value_void!(turn_choice, env);
|
||||||
|
turn_choice.restore_uses(amount);
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use crate::dynamic_data::{DynamicLibrary, ScriptOwnerData};
|
use crate::dynamic_data::{DynamicLibrary, ScriptOwnerData};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::register;
|
||||||
|
use crate::script_implementations::wasm::export_registry::wasm_result::{try_wasm, wasm_ok, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||||
|
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::StaticData;
|
use crate::static_data::StaticData;
|
||||||
|
use anyhow_ext::Context;
|
||||||
|
|
||||||
/// The battle registration
|
/// The battle registration
|
||||||
mod battle;
|
mod battle;
|
||||||
|
@ -32,8 +34,10 @@ register! {
|
||||||
fn dynamic_library_get_static_data(
|
fn dynamic_library_get_static_data(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
dynamic_lib: ExternRef<dyn DynamicLibrary>,
|
dynamic_lib: ExternRef<dyn DynamicLibrary>,
|
||||||
) -> ExternRef<dyn StaticData> {
|
) -> WasmResult<ExternRef<dyn StaticData>> {
|
||||||
ExternRef::func_new(&env, dynamic_lib.value_func_arc(&env).unwrap().static_data())
|
let dynamic_lib = try_wasm!(dynamic_lib.value_func_arc(&env), env);
|
||||||
|
let static_data = dynamic_lib.static_data();
|
||||||
|
wasm_ok(ExternRef::<dyn StaticData>::func_new(&env, static_data))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn script_get_owner(
|
fn script_get_owner(
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use crate::dynamic_data::{Pokemon, PokemonParty};
|
use crate::dynamic_data::{Pokemon, PokemonParty};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::register;
|
||||||
|
use crate::script_implementations::wasm::export_registry::wasm_result::{get_value, wasm_ok, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
use anyhow_ext::Context;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
|
@ -9,18 +11,21 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
party: ExternRef<PokemonParty>,
|
party: ExternRef<PokemonParty>,
|
||||||
index: u32
|
index: u32
|
||||||
) -> ExternRef<Pokemon> {
|
) -> WasmResult<ExternRef<Pokemon>> {
|
||||||
if let Some(v) = &party.value_func(&env).unwrap().pokemon()[index as usize] {
|
let party = get_value!(party, env);
|
||||||
|
wasm_ok(
|
||||||
|
if let Some(Some(v)) = &party.pokemon().get(index as usize) {
|
||||||
ExternRef::func_new(&env, v.as_ref())
|
ExternRef::func_new(&env, v.as_ref())
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn party_get_length(
|
fn party_get_length(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
party: ExternRef<PokemonParty>,
|
party: ExternRef<PokemonParty>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
party.value_func(&env).unwrap().length() as u32
|
let party = get_value!(party, env);
|
||||||
|
wasm_ok(party.length() as u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,10 @@ use std::mem::transmute;
|
||||||
|
|
||||||
use crate::defines::LevelInt;
|
use crate::defines::LevelInt;
|
||||||
use crate::dynamic_data::{Battle, DynamicLibrary, LearnedMove, Pokemon, VolatileScriptsOwner};
|
use crate::dynamic_data::{Battle, DynamicLibrary, LearnedMove, Pokemon, VolatileScriptsOwner};
|
||||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
use crate::script_implementations::wasm::export_registry::{
|
||||||
|
get_value_arc, get_value_arc_void, get_value_call_getter, get_value_void, register, try_wasm, wasm_err, wasm_ok,
|
||||||
|
WasmResult, WasmVoidResult, WasmVoidResultExtension,
|
||||||
|
};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
@ -10,6 +13,7 @@ use crate::static_data::{Ability, ClampedStatisticSet, Form, Nature, Species};
|
||||||
use crate::static_data::{Item, StatisticSet};
|
use crate::static_data::{Item, StatisticSet};
|
||||||
use crate::{ScriptCategory, VecExt};
|
use crate::{ScriptCategory, VecExt};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
use anyhow_ext::Context;
|
||||||
use std::ffi::{c_char, CStr, CString};
|
use std::ffi::{c_char, CStr, CString};
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
|
@ -18,72 +22,76 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<dyn DynamicLibrary>> {
|
) -> WasmResult<ExternRef<dyn DynamicLibrary>> {
|
||||||
let lib = pokemon.value_func(&env)?.library().clone();
|
let lib = get_value_call_getter!(pokemon.library(), env).clone();
|
||||||
Ok(ExternRef::func_new(&env, &lib)).into()
|
wasm_ok(ExternRef::<dyn DynamicLibrary>::func_new(&env, &lib))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_boosted_stats(
|
fn pokemon_get_boosted_stats(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<StatisticSet<u32>>> {
|
) -> WasmResult<ExternRef<StatisticSet<u32>>> {
|
||||||
let statistic_set = pokemon.value_func(&env)?.boosted_stats();
|
let statistic_set = get_value_call_getter!(pokemon.boosted_stats(), env).clone();
|
||||||
Ok(ExternRef::func_new(&env, statistic_set)).into()
|
wasm_ok(ExternRef::<StatisticSet<u32>>::func_new(&env, statistic_set))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_flat_stats(
|
fn pokemon_get_flat_stats(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<StatisticSet<u32>>> {
|
) -> WasmResult<ExternRef<StatisticSet<u32>>> {
|
||||||
let statistic_set = pokemon.value_func(&env)?.flat_stats();
|
let statistic_set = get_value_call_getter!(pokemon.flat_stats(), env).clone();
|
||||||
Ok(ExternRef::func_new(&env, statistic_set)).into()
|
wasm_ok(ExternRef::<StatisticSet<u32>>::func_new(&env, statistic_set))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_stat_boosts(
|
fn pokemon_get_stat_boosts(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<ClampedStatisticSet<i8, -6, 6>>> {
|
) -> WasmResult<ExternRef<ClampedStatisticSet<i8, -6, 6>>> {
|
||||||
let statistic_set = pokemon.value_func(&env)?.stat_boosts();
|
let statistic_set = get_value_call_getter!(pokemon.stat_boosts(), env).clone();
|
||||||
Ok(ExternRef::func_new(&env, statistic_set)).into()
|
wasm_ok(ExternRef::<ClampedStatisticSet<i8, -6, 6>>::func_new(&env, statistic_set))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_individual_values(
|
fn pokemon_get_individual_values(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<ClampedStatisticSet<u8, 0, 31>>> {
|
) -> WasmResult<ExternRef<ClampedStatisticSet<u8, 0, 31>>> {
|
||||||
let statistic_set = pokemon.value_func(&env)?.individual_values();
|
let statistic_set = get_value_call_getter!(pokemon.individual_values(), env).clone();
|
||||||
Ok(ExternRef::func_new(&env, statistic_set)).into()
|
wasm_ok(ExternRef::<ClampedStatisticSet<u8, 0, 31>>::func_new(&env, statistic_set))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_effort_values(
|
fn pokemon_get_effort_values(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<ClampedStatisticSet<u8, 0, 252>>> {
|
) -> WasmResult<ExternRef<ClampedStatisticSet<u8, 0, 252>>> {
|
||||||
let statistic_set = pokemon.value_func(&env)?.effort_values();
|
let statistic_set = get_value_call_getter!(pokemon.effort_values(), env).clone();
|
||||||
Ok(ExternRef::func_new(&env, statistic_set)).into()
|
wasm_ok(ExternRef::<ClampedStatisticSet<u8, 0, 252>>::func_new(&env, statistic_set))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_species(
|
fn pokemon_get_species(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<dyn Species>> {
|
) -> WasmResult<ExternRef<dyn Species>> {
|
||||||
let species = pokemon.value_func(&env)?.species();
|
let species = get_value_call_getter!(pokemon.species(), env).clone();
|
||||||
Ok(ExternRef::func_new(&env, &species)).into()
|
wasm_ok(ExternRef::<dyn Species>::func_new(&env, &species))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_weight(
|
fn pokemon_get_weight(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<f32> {
|
) -> WasmResult<f32> {
|
||||||
Ok(pokemon.value_func(&env)?.weight()).into()
|
wasm_ok(get_value_call_getter!(pokemon.weight(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_set_weight(
|
fn pokemon_set_weight(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
weight: f32,
|
weight: f32,
|
||||||
) -> WasmResult<()> {
|
) -> WasmVoidResult {
|
||||||
pokemon.value_func(&env)?.set_weight(weight);
|
let pokemon = match pokemon.value_func(&env) {
|
||||||
Ok(()).into()
|
Ok(pokemon) => pokemon,
|
||||||
|
Err(e) => return WasmVoidResult::err(e, &env),
|
||||||
|
};
|
||||||
|
pokemon.set_weight(weight);
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,7 +99,7 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<f32> {
|
) -> WasmResult<f32> {
|
||||||
Ok(pokemon.value_func(&env)?.height()).into()
|
wasm_ok(get_value_call_getter!(pokemon.height(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_gender(
|
fn pokemon_get_gender(
|
||||||
|
@ -99,7 +107,7 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
unsafe {
|
unsafe {
|
||||||
Ok(transmute(pokemon.value_func(&env)?.gender())).into()
|
wasm_ok(transmute(get_value_call_getter!(pokemon.gender(), env)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,10 +116,16 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
damage: u32,
|
damage: u32,
|
||||||
source: u8
|
source: u8
|
||||||
) -> WasmResult<()> {
|
) -> WasmVoidResult {
|
||||||
unsafe{
|
unsafe {
|
||||||
pokemon.value_func(&env)?.damage(damage, transmute(source))?;
|
let pokemon = match pokemon.value_func(&env) {
|
||||||
WasmResult::ok(())
|
Ok(pokemon) => pokemon,
|
||||||
|
Err(e) => return WasmVoidResult::err(e, &env),
|
||||||
|
};
|
||||||
|
match pokemon.damage(damage, transmute(source)) {
|
||||||
|
Ok(()) => WasmVoidResult::ok(),
|
||||||
|
Err(e) => WasmVoidResult::err(e, &env),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,14 +134,15 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
index: u32
|
index: u32
|
||||||
) -> WasmResult<ExternRef<LearnedMove>> {
|
) -> WasmResult<ExternRef<LearnedMove>> {
|
||||||
let read_lock = pokemon.value_func(&env)?.learned_moves().read();
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
let read_lock = pokemon.learned_moves().read();
|
||||||
let mv = read_lock.get(index as usize);
|
let mv = read_lock.get(index as usize);
|
||||||
Ok(if let Some(Some(mv)) = mv {
|
wasm_ok(if let Some(Some(mv)) = mv {
|
||||||
ExternRef::func_new(&env, mv)
|
ExternRef::<LearnedMove>::func_new(&env, mv)
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
ExternRef::null()
|
ExternRef::<LearnedMove>::null()
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_change_stat_boost(
|
fn pokemon_change_stat_boost(
|
||||||
|
@ -138,7 +153,9 @@ register! {
|
||||||
self_inflicted: u8
|
self_inflicted: u8
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
unsafe{
|
unsafe{
|
||||||
Ok(u8::from(pokemon.value_func(&env)?.change_stat_boost(transmute(stat), amount, self_inflicted == 1)?)).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
let res = try_wasm!(pokemon.change_stat_boost(transmute(stat), amount, self_inflicted == 1), env);
|
||||||
|
wasm_ok(u8::from(res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,45 +163,51 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<Battle>> {
|
) -> WasmResult<ExternRef<Battle>> {
|
||||||
Ok(if let Some(battle) = pokemon.value_func(&env)?.get_battle() {
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
ExternRef::func_new(&env, battle)
|
wasm_ok(if let Some(battle) = pokemon.get_battle() {
|
||||||
|
let r = ExternRef::func_new(&env, &battle);
|
||||||
|
std::mem::forget(battle);
|
||||||
|
r
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_battle_index(
|
fn pokemon_get_battle_index(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if let Some(i) = pokemon.value_func(&env)?.get_battle_index() {
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
wasm_ok(if let Some(i) = pokemon.get_battle_index() {
|
||||||
i
|
i
|
||||||
} else {
|
} else {
|
||||||
255
|
255
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_battle_side_index(
|
fn pokemon_get_battle_side_index(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if let Some(i) = pokemon.value_func(&env)?.get_battle_side_index() {
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
wasm_ok(if let Some(i) = pokemon.get_battle_side_index() {
|
||||||
i
|
i
|
||||||
} else {
|
} else {
|
||||||
255
|
255
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_held_item(
|
fn pokemon_get_held_item(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<dyn Item>> {
|
) -> WasmResult<ExternRef<dyn Item>> {
|
||||||
let read_lock = pokemon.value_func(&env)?.held_item().read();
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
Ok(if let Some(item) = read_lock.as_ref() {
|
let read_lock = pokemon.held_item().read();
|
||||||
ExternRef::func_new(&env, item.as_ref())
|
wasm_ok(if let Some(item) = read_lock.as_ref() {
|
||||||
|
ExternRef::<dyn Item>::func_new(&env, item.as_ref())
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::<dyn Item>::null()
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_has_held_item(
|
fn pokemon_has_held_item(
|
||||||
|
@ -194,7 +217,8 @@ register! {
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
let name : *mut c_char = env.data().data().get_raw_pointer(name);
|
let name : *mut c_char = env.data().data().get_raw_pointer(name);
|
||||||
let name = unsafe { CStr::from_ptr(name) };
|
let name = unsafe { CStr::from_ptr(name) };
|
||||||
Ok(u8::from(pokemon.value_func(&env)?.has_held_item(&name.into()))).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
wasm_ok(u8::from(pokemon.has_held_item(&name.into())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_heal(
|
fn pokemon_heal(
|
||||||
|
@ -203,51 +227,62 @@ register! {
|
||||||
amount: u32,
|
amount: u32,
|
||||||
allow_revive: u8
|
allow_revive: u8
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(u8::from(pokemon.value_func(&env)?.heal(amount, allow_revive == 1))).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
wasm_ok(u8::from(pokemon.heal(amount, allow_revive == 1)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_clear_status(
|
fn pokemon_clear_status(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<()> {
|
) -> WasmVoidResult {
|
||||||
pokemon.value_func(&env)?.clear_status();
|
let pokemon = match pokemon.value_func(&env) {
|
||||||
WasmResult::ok(())
|
Ok(pokemon) => pokemon,
|
||||||
|
Err(e) => return WasmVoidResult::err(e, &env),
|
||||||
|
};
|
||||||
|
pokemon.clear_status();
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_active_ability(
|
fn pokemon_get_active_ability(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<dyn Ability>> {
|
) -> WasmResult<ExternRef<dyn Ability>> {
|
||||||
Ok(ExternRef::func_new(&env, &pokemon.value_func(&env)?.active_ability())).into()
|
let active_ability = get_value_call_getter!(pokemon.active_ability(), env);
|
||||||
|
wasm_ok(ExternRef::<dyn Ability>::func_new(&env, &active_ability))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_real_ability(
|
fn pokemon_get_real_ability(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<(u8, u8)> {
|
) -> WasmResult<u16> {
|
||||||
let index = &pokemon.value_func(&env)?.real_ability();
|
let index = get_value_call_getter!(pokemon.real_ability(), env);
|
||||||
WasmResult::ok((if index.hidden { 1 } else { 0 }, index.index))
|
let t: (u8, u8) = (if index.hidden { 1 } else { 0 }, index.index);
|
||||||
|
let r: u16 = unsafe { transmute(t) };
|
||||||
|
wasm_ok(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_is_ability_overriden(
|
fn pokemon_get_is_ability_overriden(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if pokemon.value_func(&env)?.is_ability_overriden() { 1 } else { 0 }).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
wasm_ok(if pokemon.is_ability_overriden() { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_allowed_experience_gain(
|
fn pokemon_get_allowed_experience_gain(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if pokemon.value_func(&env)?.allowed_experience_gain() { 1 } else { 0 }).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
wasm_ok(if pokemon.allowed_experience_gain() { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_is_usable(
|
fn pokemon_get_is_usable(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if pokemon.value_func(&env)?.is_usable() { 1 } else { 0 }).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
wasm_ok(if pokemon.is_usable() { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,39 +291,45 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
item: ExternRef<dyn Item>
|
item: ExternRef<dyn Item>
|
||||||
) -> WasmResult<ExternRef<dyn Item>> {
|
) -> WasmResult<ExternRef<dyn Item>> {
|
||||||
let item = item.value_func_arc(&env)?;
|
let item = get_value_arc!(item, env);
|
||||||
let old_item = pokemon.value_func(&env)?.set_held_item(&item);
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
Ok(if let Some(old_item) = old_item {
|
let old_item = pokemon.set_held_item(&item);
|
||||||
ExternRef::func_new(&env, &old_item)
|
wasm_ok(if let Some(old_item) = old_item {
|
||||||
|
ExternRef::<dyn Item>::func_new(&env, &old_item)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::null()
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_remove_held_item(
|
fn pokemon_remove_held_item(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<dyn Item>> {
|
) -> WasmResult<ExternRef<dyn Item>> {
|
||||||
let old_item = pokemon.value_func(&env)?.remove_held_item();
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
Ok(if let Some(old_item) = old_item {
|
let old_item = pokemon.remove_held_item();
|
||||||
ExternRef::func_new(&env, &old_item)
|
wasm_ok(if let Some(old_item) = old_item {
|
||||||
|
ExternRef::<dyn Item>::func_new(&env, &old_item)
|
||||||
} else {
|
} else {
|
||||||
ExternRef::null()
|
ExternRef::<dyn Item>::null()
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_consume_held_item(
|
fn pokemon_consume_held_item(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if pokemon.value_func(&env)?.consume_held_item()? { 1 } else { 0 }).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
let res = try_wasm!(pokemon.consume_held_item(), env);
|
||||||
|
wasm_ok(if res { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_types_length(
|
fn pokemon_get_types_length(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>
|
pokemon: ExternRef<Pokemon>
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
Ok(pokemon.value_func(&env)?.types().len() as u32).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
let len = pokemon.types().len();
|
||||||
|
wasm_ok(len as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_type(
|
fn pokemon_get_type(
|
||||||
|
@ -296,7 +337,13 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
index: u32
|
index: u32
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok((*pokemon.value_func(&env)?.types().get_res(index as usize)?).into()).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
let types = pokemon.types();
|
||||||
|
let type_v = types.get_res(index as usize);
|
||||||
|
match type_v {
|
||||||
|
Ok(t) => wasm_ok(u8::from(*t)),
|
||||||
|
Err(e) => wasm_err::<u8>(e, &env),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_has_type(
|
fn pokemon_has_type(
|
||||||
|
@ -304,7 +351,8 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
t: u8
|
t: u8
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(if pokemon.value_func(&env)?.types().contains(&t.into()) { 1 } else { 0 }).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
wasm_ok(if pokemon.types().contains(&t.into()) { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_change_species(
|
fn pokemon_change_species(
|
||||||
|
@ -312,102 +360,117 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
species: ExternRef<dyn Species>,
|
species: ExternRef<dyn Species>,
|
||||||
form: ExternRef<dyn Form>,
|
form: ExternRef<dyn Form>,
|
||||||
) -> WasmResult<()> {
|
) -> WasmVoidResult {
|
||||||
pokemon.value_func(&env)?.change_species(
|
let pokemon = get_value_void!(pokemon, env);
|
||||||
species.value_func_arc(&env)?,
|
let species = get_value_arc_void!(species, env);
|
||||||
form.value_func_arc(&env)?,
|
let form = get_value_arc_void!(form, env);
|
||||||
)?;
|
|
||||||
WasmResult::ok(())
|
match pokemon.change_species(
|
||||||
|
species,
|
||||||
|
form,
|
||||||
|
) {
|
||||||
|
Ok(_) => WasmVoidResult::ok(),
|
||||||
|
Err(e) => WasmVoidResult::err(e, &env),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_change_form(
|
fn pokemon_change_form(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
form: ExternRef<dyn Form>,
|
form: ExternRef<dyn Form>,
|
||||||
) -> WasmResult<()> {
|
) -> WasmVoidResult {
|
||||||
pokemon.value_func(&env)?.change_form(
|
let pokemon = get_value_void!(pokemon, env);
|
||||||
&form.value_func_arc(&env)?,
|
let form = get_value_arc_void!(form, env);
|
||||||
)?;
|
match pokemon.change_form(&form) {
|
||||||
WasmResult::ok(())
|
Ok(_) => WasmVoidResult::ok(),
|
||||||
|
Err(e) => WasmVoidResult::err(e, &env),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_current_health(
|
fn pokemon_get_current_health(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
Ok(pokemon.value_func(&env)?.current_health()).into()
|
wasm_ok(get_value_call_getter!(pokemon.current_health(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_nature(
|
fn pokemon_get_nature(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<dyn Nature>> {
|
) -> WasmResult<ExternRef<dyn Nature>> {
|
||||||
Ok(ExternRef::func_new(&env, pokemon.value_func(&env)?.nature())).into()
|
let nature = get_value_call_getter!(pokemon.nature(), env);
|
||||||
|
wasm_ok(ExternRef::<dyn Nature>::func_new(&env, nature))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_form(
|
fn pokemon_get_form(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<dyn Form>> {
|
) -> WasmResult<ExternRef<dyn Form>> {
|
||||||
Ok(ExternRef::func_new(&env, &pokemon.value_func(&env)?.form())).into()
|
let form = get_value_call_getter!(pokemon.form(), env);
|
||||||
|
wasm_ok(ExternRef::<dyn Form>::func_new(&env, &form))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_display_species(
|
fn pokemon_get_display_species(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<dyn Species>> {
|
) -> WasmResult<ExternRef<dyn Species>> {
|
||||||
Ok(ExternRef::func_new(&env, &pokemon.value_func(&env)?.display_species())).into()
|
let display_species = get_value_call_getter!(pokemon.display_species(), env);
|
||||||
|
wasm_ok(ExternRef::<dyn Species>::func_new(&env, &display_species))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_display_form(
|
fn pokemon_get_display_form(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<ExternRef<dyn Form>> {
|
) -> WasmResult<ExternRef<dyn Form>> {
|
||||||
Ok(ExternRef::func_new(&env, &pokemon.value_func(&env)?.display_form())).into()
|
let display_form = get_value_call_getter!(pokemon.display_form(), env);
|
||||||
|
wasm_ok(ExternRef::<dyn Form>::func_new(&env, &display_form))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_level(
|
fn pokemon_get_level(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<LevelInt> {
|
) -> WasmResult<LevelInt> {
|
||||||
Ok(pokemon.value_func(&env)?.level()).into()
|
wasm_ok(get_value_call_getter!(pokemon.level(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_experience(
|
fn pokemon_get_experience(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
Ok(pokemon.value_func(&env)?.experience()).into()
|
wasm_ok(get_value_call_getter!(pokemon.experience(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_unique_identifier(
|
fn pokemon_get_unique_identifier(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
Ok(pokemon.value_func(&env)?.unique_identifier()).into()
|
wasm_ok(get_value_call_getter!(pokemon.unique_identifier(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_coloring(
|
fn pokemon_get_coloring(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
Ok(pokemon.value_func(&env)?.coloring()).into()
|
wasm_ok(get_value_call_getter!(pokemon.coloring(), env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pokemon_get_nickname(
|
fn pokemon_get_nickname(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
let pokemon = pokemon.value_func(&env)?;
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
let nickname = pokemon.nickname();
|
let nickname = pokemon.nickname();
|
||||||
if let Some(nickname) = nickname {
|
if let Some(nickname) = nickname {
|
||||||
let nickname: CString = match CString::new(nickname.as_str()) {
|
let nickname: CString = match CString::new(nickname.as_str()) {
|
||||||
Ok(nickname) => nickname,
|
Ok(nickname) => nickname,
|
||||||
Err(e) => return WasmResult::err(e.into()),
|
Err(e) => return wasm_err::<u32>(e.into(), &env),
|
||||||
};
|
};
|
||||||
env.data().data().copy_value_vec_to_wasm(nickname.as_bytes()).into()
|
match env.data().data().copy_value_vec_to_wasm(nickname.as_bytes()) {
|
||||||
|
Ok(ptr) => wasm_ok(ptr),
|
||||||
|
Err(e) => wasm_err::<u32>(e, &env),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(0).into()
|
wasm_ok(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,13 +482,14 @@ register! {
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
let script = pokemon.value_func(&env)?.add_volatile_script(&c_name.as_ref().into())?;
|
let script = try_wasm!(pokemon.add_volatile_script(&c_name.as_ref().into()), env);
|
||||||
if let Some(script) = script {
|
if let Some(script) = script {
|
||||||
let script = script.get_as::<WebAssemblyScript>()?;
|
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
||||||
Ok(script.get_wasm_pointer()).into()
|
wasm_ok(script.get_wasm_pointer())
|
||||||
} else {
|
} else {
|
||||||
Ok(0).into()
|
wasm_ok(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,23 +499,27 @@ register! {
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
script_ptr: u32
|
script_ptr: u32
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
let pokemon : &Pokemon = pokemon.value_func(&env)?;
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
unsafe{
|
unsafe{
|
||||||
let env = env.data().data();
|
let env_data = env.data().data();
|
||||||
let name_ptr = match env.script_function_cache().script_get_name(&env)?.call(&mut env.store_mut(), script_ptr){
|
let name_ptr = match try_wasm!(env_data.script_function_cache().script_get_name(&env_data), env).call(&mut env_data.store_mut(), script_ptr){
|
||||||
Ok(name_ptr) => name_ptr,
|
Ok(name_ptr) => name_ptr,
|
||||||
Err(e) => return WasmResult::err(e.into())
|
Err(e) => return wasm_err::<u32>(e.into(), &env)
|
||||||
};
|
};
|
||||||
let c_name: &CStr = CStr::from_ptr(env.get_raw_pointer(name_ptr));
|
let c_name: &CStr = CStr::from_ptr(env_data.get_raw_pointer(name_ptr));
|
||||||
let script = env.setup_script(script_ptr, ScriptCategory::Pokemon, &c_name.as_ref().into(), pokemon.into())?;
|
let script = try_wasm!(env_data.setup_script(script_ptr, ScriptCategory::Pokemon, &c_name.as_ref().into(), pokemon.as_ref().into()), env);
|
||||||
env.script_function_cache().dealloc_cstring(&env, name_ptr)?;
|
try_wasm!(env_data.script_function_cache().dealloc_cstring(&env_data, name_ptr), env);
|
||||||
|
|
||||||
if let Some(script) = script {
|
if let Some(script) = script {
|
||||||
let script = pokemon.add_volatile_script_with_script(script)?;
|
let script = try_wasm!(pokemon.add_volatile_script_with_script(script), env);
|
||||||
let s = script.as_ref().ok_or(anyhow!("Unable to get script"))?.get_as::<WebAssemblyScript>()?;
|
let s = match script.as_ref() {
|
||||||
WasmResult::ok(s.get_wasm_pointer())
|
Some(s) => s,
|
||||||
|
None => return wasm_err::<u32>(anyhow!("Unable to get script").into(), &env)
|
||||||
|
};
|
||||||
|
let s = try_wasm!(s.get_as::<WebAssemblyScript>(), env);
|
||||||
|
wasm_ok(s.get_wasm_pointer())
|
||||||
} else {
|
} else {
|
||||||
WasmResult::ok(0)
|
wasm_ok(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +531,8 @@ register! {
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
Ok(u8::from(pokemon.value_func(&env)?.has_volatile_script(&c_name.as_ref().into()))).into()
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
|
wasm_ok(u8::from(pokemon.has_volatile_script(&c_name.as_ref().into())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,13 +543,14 @@ register! {
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
let script = pokemon.value_func(&env)?.get_volatile_script(&c_name.as_ref().into());
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
Ok(if let Some(script) = script {
|
let script = pokemon.get_volatile_script(&c_name.as_ref().into());
|
||||||
let script = script.get_as::<WebAssemblyScript>()?;
|
wasm_ok(if let Some(script) = script {
|
||||||
|
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
||||||
script.get_wasm_pointer()
|
script.get_wasm_pointer()
|
||||||
} else {
|
} else {
|
||||||
0
|
0
|
||||||
}).into()
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,11 +558,14 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
name_ptr: u32
|
name_ptr: u32
|
||||||
) -> WasmResult<()> {
|
) -> WasmVoidResult {
|
||||||
unsafe {
|
unsafe {
|
||||||
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr));
|
||||||
pokemon.value_func(&env)?.remove_volatile_script(&c_name.as_ref().into())?;
|
let pokemon = get_value_void!(pokemon, env);
|
||||||
WasmResult::ok(())
|
match pokemon.remove_volatile_script(&c_name.as_ref().into()) {
|
||||||
|
Ok(_) => WasmVoidResult::ok(),
|
||||||
|
Err(e) => WasmVoidResult::err(e.into(), &env)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,12 +573,13 @@ register! {
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
pokemon: ExternRef<Pokemon>,
|
pokemon: ExternRef<Pokemon>,
|
||||||
) -> WasmResult<u32> {
|
) -> WasmResult<u32> {
|
||||||
let pokemon = pokemon.value_func(&env)?;
|
let pokemon = get_value_arc!(pokemon, env);
|
||||||
let script = pokemon.ability_script();
|
let script = pokemon.ability_script();
|
||||||
if script.is_any() {
|
if script.is_any() {
|
||||||
return Ok(script.get_as::<WebAssemblyScript>()?.get_wasm_pointer()).into();
|
let script = try_wasm!(script.get_as::<WebAssemblyScript>(), env);
|
||||||
|
return wasm_ok(script.get_wasm_pointer());
|
||||||
}
|
}
|
||||||
WasmResult::ok(0)
|
wasm_ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
use crate::dynamic_data::{LearnedMove, Pokemon, TurnChoice};
|
use crate::dynamic_data::{LearnedMove, Pokemon, TurnChoice};
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||||
|
get_value, get_value_call_getter, get_value_void, wasm_err,
|
||||||
|
};
|
||||||
|
use crate::script_implementations::wasm::export_registry::{
|
||||||
|
register, wasm_ok, WasmResult, WasmVoidResult, WasmVoidResultExtension,
|
||||||
|
};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
use crate::script_implementations::wasm::script::WebAssemblyScript;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
|
use anyhow_ext::Context;
|
||||||
use wasmer::FunctionEnvMut;
|
use wasmer::FunctionEnvMut;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
|
@ -12,100 +16,132 @@ register! {
|
||||||
fn turn_choice_get_user(
|
fn turn_choice_get_user(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> ExternRef<Pokemon> {
|
) -> WasmResult<ExternRef<Pokemon>> {
|
||||||
let turn_choice = turn_choice.value_func(&env).unwrap();
|
let user = get_value_call_getter!(turn_choice.user(), &env);
|
||||||
ExternRef::func_new(&env, turn_choice.user().as_ref().deref())
|
wasm_ok(ExternRef::func_new(&env, user))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_get_kind(
|
fn turn_choice_get_kind(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
match turn_choice.value_func(&env).unwrap() {
|
let turn_choice = get_value!(turn_choice, env);
|
||||||
|
wasm_ok(match turn_choice {
|
||||||
TurnChoice::Move(_) => 0,
|
TurnChoice::Move(_) => 0,
|
||||||
TurnChoice::Item(_) => 1,
|
TurnChoice::Item(_) => 1,
|
||||||
TurnChoice::Switch(_) => 2,
|
TurnChoice::Switch(_) => 2,
|
||||||
TurnChoice::Flee(_) => 3,
|
TurnChoice::Flee(_) => 3,
|
||||||
TurnChoice::Pass(_) => 4,
|
TurnChoice::Pass(_) => 4,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_get_speed(
|
fn turn_choice_get_speed(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
turn_choice.value_func(&env).unwrap().speed()
|
wasm_ok(get_value_call_getter!(turn_choice.speed(), &env))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_has_failed(
|
fn turn_choice_has_failed(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if turn_choice.value_func(&env).unwrap().has_failed() { 1 } else { 0 }
|
wasm_ok(if get_value_call_getter!(turn_choice.has_failed(), &env) { 1 } else { 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_fail(
|
fn turn_choice_fail(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) {
|
) -> WasmVoidResult {
|
||||||
turn_choice.value_func(&env).unwrap().fail();
|
let turn_choice = get_value_void!(turn_choice, env);
|
||||||
|
turn_choice.fail();
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn turn_choice_move_priority(
|
fn turn_choice_move_priority(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> i8 {
|
) -> WasmResult<i8> {
|
||||||
if let TurnChoice::Move(d) = turn_choice.value_func(&env).unwrap() {
|
return match turn_choice.value_func(&env) {
|
||||||
return d.priority()
|
Ok(v) => {
|
||||||
|
match v {
|
||||||
|
TurnChoice::Move(m) => wasm_ok(m.priority()),
|
||||||
|
_ => wasm_err::<i8>(anyhow_ext::anyhow!("Invalid turn choice"), &env)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => wasm_err::<i8>(e, &env),
|
||||||
}
|
}
|
||||||
panic!("Invalid turn choice");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_move_used_move(
|
fn turn_choice_move_used_move(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> ExternRef<LearnedMove> {
|
) -> WasmResult<ExternRef<LearnedMove>> {
|
||||||
if let TurnChoice::Move(d) = turn_choice.value_func(&env).unwrap() {
|
return match turn_choice.value_func(&env) {
|
||||||
return ExternRef::func_new(&env, d.used_move().as_ref());
|
Ok(v) => {
|
||||||
|
match v {
|
||||||
|
TurnChoice::Move(m) => wasm_ok(ExternRef::<LearnedMove>::func_new(&env, m.used_move())),
|
||||||
|
_ => wasm_err::<ExternRef<LearnedMove>>(anyhow_ext::anyhow!("Invalid turn choice"), &env)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => wasm_err::<ExternRef<LearnedMove>>(e, &env),
|
||||||
}
|
}
|
||||||
panic!("Invalid turn choice");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_move_target_side(
|
fn turn_choice_move_target_side(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if let TurnChoice::Move(d) = turn_choice.value_func(&env).unwrap() {
|
return match turn_choice.value_func(&env) {
|
||||||
return d.target_side();
|
Ok(v) => {
|
||||||
|
match v {
|
||||||
|
TurnChoice::Move(m) => wasm_ok(m.target_side()),
|
||||||
|
_ => wasm_err::<u8>(anyhow_ext::anyhow!("Invalid turn choice"), &env)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => wasm_err::<u8>(e, &env),
|
||||||
}
|
}
|
||||||
panic!("Invalid turn choice");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_move_target_index(
|
fn turn_choice_move_target_index(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> u8 {
|
) -> WasmResult<u8> {
|
||||||
if let TurnChoice::Move(d) = turn_choice.value_func(&env).unwrap() {
|
return match turn_choice.value_func(&env) {
|
||||||
return d.target_index();
|
Ok(v) => {
|
||||||
|
match v {
|
||||||
|
TurnChoice::Move(m) => wasm_ok(m.target_index()),
|
||||||
|
_ => wasm_err::<u8>(anyhow_ext::anyhow!("Invalid turn choice"), &env)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => wasm_err::<u8>(e, &env),
|
||||||
}
|
}
|
||||||
panic!("Invalid turn choice");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_choice_move_script(
|
fn turn_choice_move_script(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
turn_choice: ExternRef<TurnChoice>,
|
turn_choice: ExternRef<TurnChoice>,
|
||||||
) -> u32 {
|
) -> WasmResult<u32> {
|
||||||
if let TurnChoice::Move(d) = turn_choice.value_func(&env).unwrap() {
|
return match turn_choice.value_func(&env) {
|
||||||
|
Ok(v) => {
|
||||||
|
match v {
|
||||||
|
TurnChoice::Move(d) => {
|
||||||
if let Some(script) = d.script().get() {
|
if let Some(script) = d.script().get() {
|
||||||
let read_lock = script.read();
|
let read_lock = script.read();
|
||||||
if let Some(script) = read_lock.as_ref() {
|
if let Some(script) = read_lock.as_ref() {
|
||||||
return script.as_any().downcast_ref::<WebAssemblyScript>().unwrap().get_wasm_pointer()
|
if let Some(v) = script.as_any().downcast_ref::<WebAssemblyScript>(){
|
||||||
|
return wasm_ok(v.get_wasm_pointer())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
panic!("Invalid turn choice");
|
return wasm_ok(0);
|
||||||
|
},
|
||||||
|
_ => wasm_err::<u32>(anyhow_ext::anyhow!("Invalid turn choice"), &env)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => wasm_err::<u32>(e, &env),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
use anyhow_ext::anyhow;
|
use anyhow_ext::anyhow;
|
||||||
use anyhow_ext::Result;
|
|
||||||
use num_traits::{NumCast, PrimInt};
|
|
||||||
use std::ffi::{c_char, CStr, CString};
|
use std::ffi::{c_char, CStr, CString};
|
||||||
use std::mem::{align_of, forget};
|
use std::mem::{align_of, forget};
|
||||||
use std::ops::{ControlFlow, FromResidual, Try};
|
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||||
|
|
||||||
use wasmer::{FromToNativeWasmType, FunctionEnv, FunctionEnvMut, Imports, NativeWasmTypeInto, StoreMut};
|
|
||||||
|
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::EffectParameter;
|
use crate::static_data::EffectParameter;
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
|
use anyhow_ext::Context;
|
||||||
|
|
||||||
/// Dynamic data registration
|
/// Dynamic data registration
|
||||||
mod dynamic_data;
|
mod dynamic_data;
|
||||||
/// Static data registration
|
/// Static data registration
|
||||||
mod static_data;
|
mod static_data;
|
||||||
|
mod wasm_object;
|
||||||
|
mod wasm_result;
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use wasm_result::*;
|
||||||
|
|
||||||
/// Register a single function.
|
/// Register a single function.
|
||||||
macro_rules! register_func_with_env {
|
macro_rules! register_func_with_env {
|
||||||
|
@ -94,52 +96,50 @@ fn _print(env: FunctionEnvMut<WebAssemblyEnv>, p: u32) {
|
||||||
|
|
||||||
/// Triggers when WASM panics.
|
/// Triggers when WASM panics.
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
fn _error(env: FunctionEnvMut<WebAssemblyEnv>, message: u32, file: u32, line: u32, position: u32) {
|
fn _error(env: FunctionEnvMut<WebAssemblyEnv>, message: u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mem: *const c_char = env.data().data().get_raw_pointer(message);
|
let mem: *const c_char = env.data().data().get_raw_pointer(message);
|
||||||
let message_str = CStr::from_ptr(mem);
|
let message_str = CStr::from_ptr(mem);
|
||||||
let mem: *const c_char = env.data().data().get_raw_pointer(file);
|
panic!("WASM Error: {}", message_str.to_str().unwrap());
|
||||||
let file_str = CStr::from_ptr(mem);
|
|
||||||
|
|
||||||
panic!(
|
|
||||||
"WASM Error: {} in file {}, line: {}:{}",
|
|
||||||
message_str.to_str().unwrap(),
|
|
||||||
file_str.to_str().unwrap(),
|
|
||||||
line,
|
|
||||||
position
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a single item from an earlier passed VecExternRef
|
/// Get a single item from an earlier passed VecExternRef
|
||||||
fn _vec_extern_ref_get_value(env: FunctionEnvMut<WebAssemblyEnv>, reference: u32, index: u32) -> WasmResult<u32> {
|
fn _vec_extern_ref_get_value(env: FunctionEnvMut<WebAssemblyEnv>, reference: u32, index: u32) -> WasmResult<u32> {
|
||||||
let res = env
|
let res = try_wasm!(
|
||||||
|
env.data()
|
||||||
.data()
|
.data()
|
||||||
.data()
|
.get_extern_vec_ref_extern_ref(reference as usize, index as usize),
|
||||||
.get_extern_vec_ref_extern_ref(reference as usize, index as usize)?;
|
env
|
||||||
Ok(res as u32).into()
|
);
|
||||||
|
wasm_ok(res as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the hash value of a StringKey.
|
/// Gets the hash value of a StringKey.
|
||||||
fn string_key_get_hash(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> WasmResult<u32> {
|
fn string_key_get_hash(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> WasmResult<u32> {
|
||||||
Ok(string_key.value_func(&env)?.hash()).into()
|
let value = get_value!(string_key, env);
|
||||||
|
wasm_ok(value.hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a null-terminated C string from a StringKey. Note that this involves a copy into WASM
|
/// Get a null-terminated C string from a StringKey. Note that this involves a copy into WASM
|
||||||
/// memory, so this is relatively heavy.
|
/// memory, so this is relatively heavy.
|
||||||
fn string_key_get_str(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> WasmResult<u32> {
|
fn string_key_get_str(env: FunctionEnvMut<WebAssemblyEnv>, string_key: ExternRef<StringKey>) -> (u32, u32) {
|
||||||
let string_key = string_key.value_func(&env)?.str();
|
let value = get_value!(string_key, env);
|
||||||
let wasm_string_ptr = env
|
let string_key = value.str();
|
||||||
|
let wasm_string_ptr = try_wasm!(
|
||||||
|
env.data()
|
||||||
.data()
|
.data()
|
||||||
.data()
|
.allocate_mem((string_key.len() + 1) as u32, align_of::<CString>() as u32),
|
||||||
.allocate_mem((string_key.len() + 1) as u32, align_of::<CString>() as u32)?;
|
env
|
||||||
|
);
|
||||||
let mut wasm_string: Vec<u8> =
|
let mut wasm_string: Vec<u8> =
|
||||||
unsafe { Vec::from_raw_parts(wasm_string_ptr.0, string_key.len() + 1, string_key.len() + 1) };
|
unsafe { Vec::from_raw_parts(wasm_string_ptr.0, string_key.len() + 1, string_key.len() + 1) };
|
||||||
wasm_string.resize(string_key.len() + 1, 0);
|
wasm_string.resize(string_key.len() + 1, 0);
|
||||||
string_key.as_bytes().clone_into(&mut wasm_string);
|
string_key.as_bytes().clone_into(&mut wasm_string);
|
||||||
wasm_string.insert(string_key.len(), 0_u8);
|
wasm_string.insert(string_key.len(), 0_u8);
|
||||||
forget(wasm_string);
|
forget(wasm_string);
|
||||||
Ok(wasm_string_ptr.1).into()
|
println!("Returning v: {:?}", wasm_string_ptr.1);
|
||||||
|
wasm_ok(wasm_string_ptr.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the type of an EffectParameter
|
/// Gets the type of an EffectParameter
|
||||||
|
@ -147,14 +147,13 @@ fn effect_parameter_get_type(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
parameter: ExternRef<EffectParameter>,
|
parameter: ExternRef<EffectParameter>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
let v = parameter.value_func(&env)?;
|
let value = get_value!(parameter, env);
|
||||||
Ok(match v {
|
wasm_ok(match value {
|
||||||
EffectParameter::Bool(_, _) => 1,
|
EffectParameter::Bool(_, _) => 1,
|
||||||
EffectParameter::Int(_, _) => 2,
|
EffectParameter::Int(_, _) => 2,
|
||||||
EffectParameter::Float(_, _) => 3,
|
EffectParameter::Float(_, _) => 3,
|
||||||
EffectParameter::String(_, _) => 4,
|
EffectParameter::String(_, _) => 4,
|
||||||
})
|
})
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner bool data of an EffectParameter. Panics if it's not a bool.
|
/// Gets the inner bool data of an EffectParameter. Panics if it's not a bool.
|
||||||
|
@ -162,12 +161,11 @@ fn effect_parameter_as_bool(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
parameter: ExternRef<EffectParameter>,
|
parameter: ExternRef<EffectParameter>,
|
||||||
) -> WasmResult<u8> {
|
) -> WasmResult<u8> {
|
||||||
let v = parameter.value_func(&env)?;
|
let value = get_value!(parameter, env);
|
||||||
match v {
|
match value {
|
||||||
EffectParameter::Bool(_, b) => Ok(<u8 as From<bool>>::from(*b)),
|
EffectParameter::Bool(_, b) => wasm_ok(<u8 as From<bool>>::from(*b)),
|
||||||
_ => Err(anyhow!("Unexpected parameter type. Expected bool, got {}", v)),
|
_ => wasm_err::<u8>(anyhow!("Unexpected parameter type. Expected bool, got {}", value), &env),
|
||||||
}
|
}
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner int data of an EffectParameter. Panics if it's not an int.
|
/// Gets the inner int data of an EffectParameter. Panics if it's not an int.
|
||||||
|
@ -175,12 +173,11 @@ fn effect_parameter_as_int(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
parameter: ExternRef<EffectParameter>,
|
parameter: ExternRef<EffectParameter>,
|
||||||
) -> WasmResult<i64> {
|
) -> WasmResult<i64> {
|
||||||
let v = parameter.value_func(&env)?;
|
let value = get_value!(parameter, env);
|
||||||
match v {
|
match value {
|
||||||
EffectParameter::Int(_, i) => Ok(*i),
|
EffectParameter::Int(_, i) => wasm_ok(*i),
|
||||||
_ => Err(anyhow!("Unexpected parameter type. Expected int, got {}", v)),
|
_ => wasm_err::<i64>(anyhow!("Unexpected parameter type. Expected int, got {}", value), &env),
|
||||||
}
|
}
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner float data of an EffectParameter. Panics if it's not a float.
|
/// Gets the inner float data of an EffectParameter. Panics if it's not a float.
|
||||||
|
@ -188,12 +185,14 @@ fn effect_parameter_as_float(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
parameter: ExternRef<EffectParameter>,
|
parameter: ExternRef<EffectParameter>,
|
||||||
) -> WasmResult<f32> {
|
) -> WasmResult<f32> {
|
||||||
let v = parameter.value_func(&env)?;
|
let value = get_value!(parameter, env);
|
||||||
match v {
|
match value {
|
||||||
EffectParameter::Float(_, f) => Ok(*f),
|
EffectParameter::Float(_, f) => wasm_ok(*f),
|
||||||
_ => Err(anyhow!("Unexpected parameter type. Expected float, got {}", v)),
|
_ => wasm_err::<f32>(
|
||||||
|
anyhow!("Unexpected parameter type. Expected float, got {}", value),
|
||||||
|
&env,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the inner string data of an EffectParameter. Panics if it's not a string.
|
/// Gets the inner string data of an EffectParameter. Panics if it's not a string.
|
||||||
|
@ -201,58 +200,12 @@ fn effect_parameter_as_string(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
parameter: ExternRef<EffectParameter>,
|
parameter: ExternRef<EffectParameter>,
|
||||||
) -> WasmResult<ExternRef<StringKey>> {
|
) -> WasmResult<ExternRef<StringKey>> {
|
||||||
let v = parameter.value_func(&env)?;
|
let value = get_value!(parameter, env);
|
||||||
match v {
|
match value {
|
||||||
EffectParameter::String(_, s) => Ok(ExternRef::func_new(&env, s)),
|
EffectParameter::Float(_, s) => wasm_ok(ExternRef::<StringKey>::func_new(&env, s)),
|
||||||
_ => Err(anyhow!("Unexpected parameter type. Expected string, got {}", v)),
|
_ => wasm_err::<ExternRef<StringKey>>(
|
||||||
}
|
anyhow!("Unexpected parameter type. Expected string, got {}", value),
|
||||||
.into()
|
&env,
|
||||||
}
|
),
|
||||||
|
|
||||||
/// A result type that can be given to, or returned from WASM.
|
|
||||||
struct WasmResult<T>(Result<T>);
|
|
||||||
|
|
||||||
impl<T> WasmResult<T> {
|
|
||||||
/// Create a new WasmResult with an OK value.
|
|
||||||
pub fn ok(value: T) -> Self {
|
|
||||||
Self(Ok(value))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new WasmResult with an Err value.
|
|
||||||
pub fn err(value: anyhow_ext::Error) -> Self {
|
|
||||||
Self(Err(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> From<Result<T>> for WasmResult<T> {
|
|
||||||
fn from(value: Result<T>) -> Self {
|
|
||||||
Self(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> FromResidual for WasmResult<T> {
|
|
||||||
fn from_residual(residual: <Self as Try>::Residual) -> Self {
|
|
||||||
match residual {
|
|
||||||
Ok(_) => {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
Err(e) => WasmResult(Err(e)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Try for WasmResult<T> {
|
|
||||||
type Output = T;
|
|
||||||
type Residual = <Result<T> as Try>::Residual;
|
|
||||||
|
|
||||||
fn from_output(output: Self::Output) -> Self {
|
|
||||||
Self(Ok(output))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
|
|
||||||
match self.0 {
|
|
||||||
Ok(v) => ControlFlow::Continue(v),
|
|
||||||
Err(e) => ControlFlow::Break(Err(e)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
use crate::script_implementations::wasm::export_registry::FunctionEnvMut;
|
use crate::script_implementations::wasm::export_registry::wasm_result::try_wasm;
|
||||||
use crate::script_implementations::wasm::export_registry::{register, WasmResult};
|
use crate::script_implementations::wasm::export_registry::{register, wasm_ok, FunctionEnvMut, WasmResult};
|
||||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::{Form, StatisticSet};
|
use crate::static_data::{Form, StatisticSet};
|
||||||
use crate::StringKey;
|
use crate::StringKey;
|
||||||
|
use anyhow_ext::Context;
|
||||||
|
|
||||||
register! {
|
register! {
|
||||||
|
|
||||||
|
@ -18,11 +19,12 @@ fn form_get_name(
|
||||||
fn form_get_types(
|
fn form_get_types(
|
||||||
env: FunctionEnvMut<WebAssemblyEnv>,
|
env: FunctionEnvMut<WebAssemblyEnv>,
|
||||||
form: ExternRef<dyn Form>
|
form: ExternRef<dyn Form>
|
||||||
) -> WasmResult<(u32, u32)> {
|
) -> WasmResult<u64> {
|
||||||
let form = form.value_func_arc(&env).unwrap();
|
let form = form.value_func_arc(&env).unwrap();
|
||||||
let vec = form.types();
|
let vec = form.types();
|
||||||
let wasm_ptr = env.data().data().copy_value_vec_to_wasm(vec)?;
|
let wasm_ptr = try_wasm!(env.data().data().copy_value_vec_to_wasm(vec), env);
|
||||||
Ok((wasm_ptr, vec.len() as u32)).into()
|
let r: u64 = unsafe { std::mem::transmute((wasm_ptr, vec.len() as u32)) };
|
||||||
|
wasm_ok(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn form_get_height(
|
fn form_get_height(
|
||||||
|
|
|
@ -2,13 +2,17 @@ use std::mem::transmute;
|
||||||
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
use wasmer::{FunctionEnv, FunctionEnvMut, Imports, StoreMut};
|
||||||
|
|
||||||
use crate::defines::LevelInt;
|
use crate::defines::LevelInt;
|
||||||
use crate::script_implementations::wasm::export_registry::register;
|
use crate::script_implementations::wasm::export_registry::wasm_result::{
|
||||||
|
get_value, get_value_void, wasm_ok, WasmResult,
|
||||||
|
};
|
||||||
|
use crate::script_implementations::wasm::export_registry::{register, WasmVoidResult, WasmVoidResultExtension};
|
||||||
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
use crate::script_implementations::wasm::extern_ref::ExternRef;
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv;
|
||||||
use crate::static_data::{
|
use crate::static_data::{
|
||||||
ItemLibrary, LibrarySettings, MoveLibrary, SpeciesLibrary, StaticData, StaticStatisticSet, StatisticSet,
|
ItemLibrary, LibrarySettings, MoveLibrary, SpeciesLibrary, StaticData, StaticStatisticSet, StatisticSet,
|
||||||
TypeLibrary,
|
TypeLibrary,
|
||||||
};
|
};
|
||||||
|
use anyhow_ext::Context;
|
||||||
|
|
||||||
/// Ability data registration
|
/// Ability data registration
|
||||||
mod ability;
|
mod ability;
|
||||||
|
@ -62,27 +66,34 @@ register! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statistic_set_get(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8) -> i64 {
|
fn statistic_set_get(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8) -> WasmResult<i64> {
|
||||||
unsafe {
|
unsafe {
|
||||||
statistics_set.value_func(&env).unwrap().get_stat(transmute(stat)) as i64
|
let statistics_set = get_value!(statistics_set, env);
|
||||||
|
wasm_ok(statistics_set.get_stat(transmute(stat)) as i64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statistic_set_set(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8, value: u64) {
|
fn statistic_set_set(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8, value: u64) -> WasmVoidResult {
|
||||||
unsafe {
|
unsafe {
|
||||||
statistics_set.value_func(&env).unwrap().set_stat(transmute(stat), value as u32)
|
let statistics_set = get_value_void!(statistics_set, env);
|
||||||
|
statistics_set.set_stat(transmute(stat), value as u32);
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statistic_set_increase_stat(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8, value: u64) {
|
fn statistic_set_increase_stat(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8, value: u64) -> WasmVoidResult {
|
||||||
unsafe {
|
unsafe {
|
||||||
statistics_set.value_func(&env).unwrap().increase_stat(transmute(stat), value as u32)
|
let statistics_set = get_value_void!(statistics_set, env);
|
||||||
|
statistics_set.increase_stat(transmute(stat), value as u32);
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn statistic_set_decrease_stat(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8, value: u64) {
|
fn statistic_set_decrease_stat(env: FunctionEnvMut<WebAssemblyEnv>, statistics_set: ExternRef<StatisticSet<u32>>, stat: u8, value: u64) -> WasmVoidResult {
|
||||||
unsafe {
|
unsafe {
|
||||||
statistics_set.value_func(&env).unwrap().decrease_stat(transmute(stat), value as u32)
|
let statistics_set = get_value_void!(statistics_set, env);
|
||||||
|
statistics_set.decrease_stat(transmute(stat), value as u32);
|
||||||
|
WasmVoidResult::ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
use crate::script_implementations::wasm::script_resolver::{WebAssemblyEnv, WebAssemblyEnvironmentData};
|
||||||
|
use anyhow::Error;
|
||||||
|
use std::ffi::{c_char, CString};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use wasmer::{FromToNativeWasmType, FunctionEnvMut};
|
||||||
|
|
||||||
|
/// A result type that can be given to, or returned from WASM.
|
||||||
|
pub type WasmResult<T> = (u32, T);
|
||||||
|
|
||||||
|
/// A result type that can be given to, or returned from WASM, but does not contain a value.
|
||||||
|
pub type WasmVoidResult = u32;
|
||||||
|
|
||||||
|
pub(crate) trait WasmVoidResultExtension {
|
||||||
|
fn into_result(self, env: FunctionEnvMut<WebAssemblyEnv>) -> anyhow_ext::Result<()>;
|
||||||
|
fn into_result_env(self, env: &Arc<WebAssemblyEnvironmentData>) -> anyhow_ext::Result<()>;
|
||||||
|
fn from_result(res: anyhow_ext::Result<()>, env: &FunctionEnvMut<WebAssemblyEnv>) -> Self;
|
||||||
|
fn ok() -> Self;
|
||||||
|
fn err(err: anyhow::Error, env: &FunctionEnvMut<WebAssemblyEnv>) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn wasm_ok<T>(value: T) -> WasmResult<T>
|
||||||
|
where
|
||||||
|
T: FromToNativeWasmType,
|
||||||
|
<T as FromToNativeWasmType>::Native: Default,
|
||||||
|
{
|
||||||
|
(0, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn wasm_err<T>(err: Error, env: &FunctionEnvMut<WebAssemblyEnv>) -> WasmResult<T>
|
||||||
|
where
|
||||||
|
T: FromToNativeWasmType + Default,
|
||||||
|
{
|
||||||
|
let s = CString::new(err.to_string()).unwrap();
|
||||||
|
let ptr = env.data().data().copy_value_vec_to_wasm(s.as_bytes()).unwrap();
|
||||||
|
(ptr, <T as Default>::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WasmVoidResultExtension for WasmVoidResult {
|
||||||
|
fn into_result(self, env: FunctionEnvMut<WebAssemblyEnv>) -> anyhow::Result<()> {
|
||||||
|
Self::into_result_env(self, &env.data().data())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_result_env(self, env: &Arc<WebAssemblyEnvironmentData>) -> anyhow::Result<()> {
|
||||||
|
if self == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
unsafe {
|
||||||
|
let ptr = self;
|
||||||
|
let mem: *mut c_char = env.get_raw_pointer(ptr as u32);
|
||||||
|
let string = std::ffi::CStr::from_ptr(mem);
|
||||||
|
let e = anyhow_ext::anyhow!("{}", string.to_str().unwrap());
|
||||||
|
env.script_function_cache().dealloc_cstring(&env, ptr as u32).unwrap();
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_result(res: anyhow::Result<()>, env: &FunctionEnvMut<WebAssemblyEnv>) -> Self {
|
||||||
|
match res {
|
||||||
|
Ok(_) => 0,
|
||||||
|
Err(e) => {
|
||||||
|
let s = CString::new(e.to_string()).unwrap();
|
||||||
|
let ptr = env.data().data().copy_value_vec_to_wasm(s.as_bytes()).unwrap();
|
||||||
|
ptr as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ok() -> Self {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn err(err: Error, env: &FunctionEnvMut<WebAssemblyEnv>) -> Self {
|
||||||
|
let s = CString::new(err.to_string()).unwrap();
|
||||||
|
let ptr = env.data().data().copy_value_vec_to_wasm(s.as_bytes()).unwrap();
|
||||||
|
ptr as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! try_wasm {
|
||||||
|
($e:expr, $env:expr) => {
|
||||||
|
match $e.with_context(|| format!("WASM function {}", stdext::function_name!())) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
return crate::script_implementations::wasm::export_registry::wasm_err(e.into(), &$env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! try_wasm_void {
|
||||||
|
($e:expr, $env:expr) => {
|
||||||
|
match $e.with_context(|| format!("WASM function {}", stdext::function_name!())) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
return WasmVoidResult::from_result(Err(e.into()), &$env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) use try_wasm;
|
||||||
|
pub(super) use try_wasm_void;
|
||||||
|
|
||||||
|
macro_rules! get_value {
|
||||||
|
($e:expr, $env:expr) => {
|
||||||
|
crate::script_implementations::wasm::export_registry::try_wasm!($e.value_func(&$env), $env)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! get_value_arc {
|
||||||
|
($e:expr, $env:expr) => {
|
||||||
|
crate::script_implementations::wasm::export_registry::try_wasm!($e.value_func_arc(&$env), $env)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! get_value_void {
|
||||||
|
($e:expr, $env:expr) => {
|
||||||
|
crate::script_implementations::wasm::export_registry::try_wasm_void!($e.value_func(&$env), $env)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! get_value_arc_void {
|
||||||
|
($e:expr, $env:expr) => {
|
||||||
|
crate::script_implementations::wasm::export_registry::try_wasm_void!($e.value_func_arc(&$env), $env)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) use get_value;
|
||||||
|
pub(super) use get_value_arc;
|
||||||
|
pub(super) use get_value_arc_void;
|
||||||
|
pub(super) use get_value_void;
|
||||||
|
|
||||||
|
macro_rules! get_value_call_getter {
|
||||||
|
($e:ident.$func:ident(), $env:expr) => {{
|
||||||
|
let _value = crate::script_implementations::wasm::export_registry::try_wasm!($e.value_func(&$env), $env);
|
||||||
|
_value.$func()
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) use get_value_call_getter;
|
|
@ -32,6 +32,15 @@ impl<T: ?Sized> Clone for ExternRef<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: ?Sized> Default for ExternRef<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
index: 0,
|
||||||
|
_phantom: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: ValueIdentifiable + ?Sized> ExternRef<T> {
|
impl<T: ValueIdentifiable + ?Sized> ExternRef<T> {
|
||||||
/// Instantiates a new ExternRef for a bit of data. If we already have made an Extern Ref for
|
/// Instantiates a new ExternRef for a bit of data. If we already have made an Extern Ref for
|
||||||
/// this data and type, we use that instead.
|
/// this data and type, we use that instead.
|
||||||
|
@ -164,6 +173,18 @@ impl<T> Clone for VecExternRef<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Copy for VecExternRef<T> {}
|
||||||
|
|
||||||
|
impl<T> Default for VecExternRef<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
index: 0,
|
||||||
|
size: 0,
|
||||||
|
_phantom: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: 'static> VecExternRef<T> {
|
impl<T: 'static> VecExternRef<T> {
|
||||||
/// Instantiates a new VecExternRef for a given slice.
|
/// Instantiates a new VecExternRef for a given slice.
|
||||||
pub fn new(env: &WebAssemblyEnvironmentData, value: &Vec<T>) -> Self {
|
pub fn new(env: &WebAssemblyEnvironmentData, value: &Vec<T>) -> Self {
|
||||||
|
|
|
@ -8,6 +8,7 @@ use hashbrown::HashSet;
|
||||||
use crate::dynamic_data::{
|
use crate::dynamic_data::{
|
||||||
Battle, DamageSource, DynamicLibrary, ExecutingMove, Pokemon, Script, ScriptOwnerData, TurnChoice,
|
Battle, DamageSource, DynamicLibrary, ExecutingMove, Pokemon, Script, ScriptOwnerData, TurnChoice,
|
||||||
};
|
};
|
||||||
|
use crate::script_implementations::wasm::export_registry::WasmVoidResultExtension;
|
||||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
||||||
use crate::script_implementations::wasm::WebAssemblyScriptCapabilities;
|
use crate::script_implementations::wasm::WebAssemblyScriptCapabilities;
|
||||||
|
@ -75,7 +76,10 @@ impl WebAssemblyScript {
|
||||||
/// Util macro to reduce function call verbosity.
|
/// Util macro to reduce function call verbosity.
|
||||||
macro_rules! call_func {
|
macro_rules! call_func {
|
||||||
($func:ident, $env:ident, $self:ident $(, $par_name:expr)*) => {
|
($func:ident, $env:ident, $self:ident $(, $par_name:expr)*) => {
|
||||||
$func.call(&mut $env.store_mut(), $self.self_ptr $(, $par_name)*).unwrap();
|
match $func.call(&mut $env.store_mut(), $self.self_ptr $(, $par_name)*) {
|
||||||
|
Ok(res) => res.into_result_env($env)?,
|
||||||
|
Err(e) => return Err(e.into()),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ use parking_lot::RwLock;
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
|
|
||||||
use crate::dynamic_data::{Battle, DynamicLibrary, ExecutingMove, Pokemon, TurnChoice};
|
use crate::dynamic_data::{Battle, DynamicLibrary, ExecutingMove, Pokemon, TurnChoice};
|
||||||
|
use crate::script_implementations::wasm::export_registry::WasmVoidResult;
|
||||||
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
||||||
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
||||||
use crate::static_data::{EffectParameter, Item, TypeIdentifier};
|
use crate::static_data::{EffectParameter, Item, TypeIdentifier};
|
||||||
|
@ -26,7 +27,7 @@ macro_rules! script_function_cache {
|
||||||
script_get_name: RwLock<Option<TypedFunction<(u32), u32>>>,
|
script_get_name: RwLock<Option<TypedFunction<(u32), u32>>>,
|
||||||
dealloc_cstring: RwLock<Option<TypedFunction<(u32), ()>>>,
|
dealloc_cstring: RwLock<Option<TypedFunction<(u32), ()>>>,
|
||||||
$(
|
$(
|
||||||
$name: RwLock<Option<TypedFunction<(u32$(, $par_type)*), ()>>>,
|
$name: RwLock<Option<TypedFunction<(u32$(, $par_type)*), WasmVoidResult>>>,
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ macro_rules! script_function_cache {
|
||||||
let exported = env.exported_functions();
|
let exported = env.exported_functions();
|
||||||
let f = exported.get::<StringKey>(&stringify!([< script_ $name >]).into());
|
let f = exported.get::<StringKey>(&stringify!([< script_ $name >]).into());
|
||||||
if let Some(f) = f {
|
if let Some(f) = f {
|
||||||
let func: TypedFunction<(u32 $(,$par_type)*), ()> = f.typed(&env.store_ref()).unwrap();
|
let func: TypedFunction<(u32 $(,$par_type)*), WasmVoidResult> = f.typed(&env.store_ref()).unwrap();
|
||||||
let _ = self.$name.write().insert(func);
|
let _ = self.$name.write().insert(func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +50,7 @@ macro_rules! script_function_cache {
|
||||||
pub(crate) fn [<$name>](
|
pub(crate) fn [<$name>](
|
||||||
&self,
|
&self,
|
||||||
env: &Arc<WebAssemblyEnvironmentData>,
|
env: &Arc<WebAssemblyEnvironmentData>,
|
||||||
) -> Option<TypedFunction<(u32 $(,$par_type)*), ()>> {
|
) -> Option<TypedFunction<(u32 $(,$par_type)*), WasmVoidResult>> {
|
||||||
{
|
{
|
||||||
let read_lock = self.$name.read();
|
let read_lock = self.$name.read();
|
||||||
if let Some(f) = read_lock.as_ref() {
|
if let Some(f) = read_lock.as_ref() {
|
||||||
|
|
|
@ -3,8 +3,7 @@ use std::fmt::{Debug, Formatter};
|
||||||
use std::mem::{align_of, forget, size_of};
|
use std::mem::{align_of, forget, size_of};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow_ext::{anyhow, ensure, Context, Result};
|
||||||
use anyhow_ext::{anyhow, ensure};
|
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use parking_lot::lock_api::RwLockReadGuard;
|
use parking_lot::lock_api::RwLockReadGuard;
|
||||||
use parking_lot::{RawRwLock, RwLock};
|
use parking_lot::{RawRwLock, RwLock};
|
||||||
|
@ -54,7 +53,7 @@ struct ScriptCapabilitiesKey {
|
||||||
impl WebAssemblyScriptResolver {
|
impl WebAssemblyScriptResolver {
|
||||||
/// Instantiates a new WebAssemblyScriptResolver.
|
/// Instantiates a new WebAssemblyScriptResolver.
|
||||||
pub fn new() -> Box<WebAssemblyScriptResolver> {
|
pub fn new() -> Box<WebAssemblyScriptResolver> {
|
||||||
let compiler = wasmer::Cranelift::default();
|
let compiler = wasmer::LLVM::default();
|
||||||
let mut features = Features::new();
|
let mut features = Features::new();
|
||||||
features.multi_value = true;
|
features.multi_value = true;
|
||||||
features.reference_types = true;
|
features.reference_types = true;
|
||||||
|
@ -122,7 +121,7 @@ impl WebAssemblyScriptResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let instance = Instance::new(&mut self.store_mut(), module, &imports)?;
|
let instance = Instance::new(&mut self.store_mut(), module, &imports).context("Setting up the instance")?;
|
||||||
let exports = &instance.exports;
|
let exports = &instance.exports;
|
||||||
|
|
||||||
let init_fn = exports.get_extern("_init");
|
let init_fn = exports.get_extern("_init");
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use pkmn_lib::dynamic_data::Battle;
|
use pkmn_lib::dynamic_data::Battle;
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ pub enum TestDataGetter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestDataGetter {
|
impl TestDataGetter {
|
||||||
pub fn get(&self, battle: &Battle) -> String {
|
pub fn get(&self, battle: &Arc<Battle>) -> String {
|
||||||
match self {
|
match self {
|
||||||
TestDataGetter::PokemonHealth { index } => battle
|
TestDataGetter::PokemonHealth { index } => battle
|
||||||
.get_pokemon(index[0], index[1])
|
.get_pokemon(index[0], index[1])
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl TestCase {
|
||||||
for party in parties {
|
for party in parties {
|
||||||
battle_parties.push(BattleParty::new(party.0.clone(), party.1).unwrap());
|
battle_parties.push(BattleParty::new(party.0.clone(), party.1).unwrap());
|
||||||
}
|
}
|
||||||
let mut battle = Battle::new(
|
let battle = Battle::new(
|
||||||
library,
|
library,
|
||||||
battle_parties,
|
battle_parties,
|
||||||
self.battle_setup.can_flee,
|
self.battle_setup.can_flee,
|
||||||
|
@ -67,7 +67,7 @@ impl TestCase {
|
||||||
Some(self.battle_setup.seed),
|
Some(self.battle_setup.seed),
|
||||||
);
|
);
|
||||||
for action in &self.actions {
|
for action in &self.actions {
|
||||||
action.execute(&mut battle);
|
action.execute(&battle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use pkmn_lib::dynamic_data::Battle;
|
use pkmn_lib::dynamic_data::Battle;
|
||||||
use pkmn_lib::dynamic_data::{MoveChoice, PassChoice, TurnChoice};
|
use pkmn_lib::dynamic_data::{MoveChoice, PassChoice, TurnChoice};
|
||||||
|
@ -31,11 +32,11 @@ pub enum TestStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestStep {
|
impl TestStep {
|
||||||
pub fn execute(&self, battle: &mut Battle) {
|
pub fn execute(&self, battle: &Arc<Battle>) {
|
||||||
match self {
|
match self {
|
||||||
TestStep::SetPokemon { place, from_party } => {
|
TestStep::SetPokemon { place, from_party } => {
|
||||||
let p = battle.parties()[from_party[0] as usize].get_pokemon(from_party[1] as usize);
|
let p = battle.parties()[from_party[0] as usize].get_pokemon(from_party[1] as usize);
|
||||||
battle.sides_mut()[place[0] as usize].set_pokemon(place[1], p).unwrap();
|
battle.sides()[place[0] as usize].set_pokemon(place[1], p).unwrap();
|
||||||
}
|
}
|
||||||
TestStep::SetMoveChoice {
|
TestStep::SetMoveChoice {
|
||||||
for_pokemon,
|
for_pokemon,
|
||||||
|
@ -72,7 +73,7 @@ impl TestStep {
|
||||||
assert!(battle.try_set_choice(TurnChoice::Pass(PassChoice::new(p))).unwrap());
|
assert!(battle.try_set_choice(TurnChoice::Pass(PassChoice::new(p))).unwrap());
|
||||||
}
|
}
|
||||||
TestStep::Assert { value, expected } => {
|
TestStep::Assert { value, expected } => {
|
||||||
let v = value.get(battle);
|
let v = value.get(&battle);
|
||||||
assert_eq!(&v, expected)
|
assert_eq!(&v, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue