use crate::dynamic_data::{Battle, BattleSide, Pokemon, ScriptCategory, VolatileScriptsOwner}; 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::script::WebAssemblyScript; use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv; use anyhow::anyhow; use std::ffi::CStr; use wasmer::FunctionEnvMut; register! { fn battleside_has_fled_battle( env: FunctionEnvMut, side: ExternRef, ) -> WasmResult { wasm_ok(u8::from(get_value_call_getter!(side.has_fled_battle(), env))) } fn battleside_is_defeated( env: FunctionEnvMut, side: ExternRef, ) -> WasmResult { wasm_ok(u8::from(get_value_call_getter!(side.is_defeated(), env))) } fn battleside_get_side_index( env: FunctionEnvMut, side: ExternRef, ) -> WasmResult { wasm_ok(get_value_call_getter!(side.index(), env)) } fn battleside_get_pokemon_per_side( env: FunctionEnvMut, side: ExternRef, ) -> WasmResult { wasm_ok(get_value_call_getter!(side.pokemon_per_side(), env)) } fn battleside_get_battle( env: FunctionEnvMut, side: ExternRef, ) -> WasmResult> { let value = get_value_call_getter!(side.battle(), env); let value = try_wasm!(value, env); wasm_ok(ExternRef::func_new(&env, (&value).into())) } fn battleside_get_pokemon( env: FunctionEnvMut, side: ExternRef, index: u32 ) -> WasmResult> { let side = get_value!(side, env); let x = wasm_ok(if let Some(Some(p)) = side.pokemon().get(index as usize) { ExternRef::::func_new(&env, p.into()) } else { ExternRef::null() }); x } fn battle_side_get_has_fled_battle( env: FunctionEnvMut, side: ExternRef, ) -> WasmResult { wasm_ok(if get_value_call_getter!(side.has_fled_battle(), env) { 1 } else { 0 }) } fn battle_side_get_is_defeated( env: FunctionEnvMut, side: ExternRef, ) -> WasmResult { wasm_ok(if get_value_call_getter!(side.is_defeated(), env) { 1 } else { 0 }) } fn battleside_add_volatile_by_name( env: FunctionEnvMut, side: ExternRef, name_ptr: u32 ) -> WasmResult { unsafe { let side = get_value!(side, env); let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr)); let script = try_wasm!(side.add_volatile_script(&c_name.as_ref().into()), env); wasm_ok(if let Some(script) = script { let script = try_wasm!(script.get_as::(), env); script.get_wasm_pointer() } else { 0 }) } } fn battleside_add_volatile( env: FunctionEnvMut, side: ExternRef, script_ptr: u32 ) -> WasmResult { let side = get_value!(side, env); unsafe { let e = env.data().data(); let name_func = try_wasm!(e.script_function_cache().script_get_name(&e), env); let name_ptr = try_wasm!(name_func.call(&mut e.store_mut(), script_ptr), env); let c_name: &CStr = CStr::from_ptr(e.get_raw_pointer(name_ptr)); let script = try_wasm!(e.setup_script(script_ptr, ScriptCategory::Side, &c_name.as_ref().into(), (&side).into()), env); try_wasm!(e.script_function_cache().dealloc_cstring(&e, name_ptr), env); if let Some(script) = script { let script = try_wasm!(side.add_volatile_script_with_script(script), env); let script = script.as_ref(); match script { Some(script) => { let script = try_wasm!(script.get_as::(), env); wasm_ok(script.get_wasm_pointer()) }, None => wasm_err::(anyhow!("Couldn't get script"), &env) } } else { wasm_ok(0) } } } fn battleside_has_volatile( env: FunctionEnvMut, side: ExternRef, name_ptr: u32 ) -> WasmResult { unsafe { let side = get_value!(side, env); let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr)); wasm_ok(u8::from(side.has_volatile_script(&c_name.as_ref().into()))) } } fn battleside_get_volatile( env: FunctionEnvMut, side: ExternRef, name_ptr: u32 ) -> WasmResult { unsafe { let side = get_value!(side, env); let c_name = CStr::from_ptr(env.data().data().get_raw_pointer(name_ptr)); let script = side.get_volatile_script(&c_name.as_ref().into()); if let Some(script) = script { let script = try_wasm!(script.get_as::(), env); wasm_ok(script.get_wasm_pointer()) } else { wasm_ok(0) } } } fn battleside_remove_volatile( env: FunctionEnvMut, side: ExternRef, name_ptr: u32 ) -> WasmVoidResult { 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)); match side.remove_volatile_script(&c_name.as_ref().into()) { Ok(_) => WasmVoidResult::ok(), Err(e) => WasmVoidResult::err(e, &env) } } } }