2022-08-20 10:22:12 +00:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
use parking_lot::RwLock;
|
|
|
|
use paste::paste;
|
|
|
|
use wasmer::NativeFunc;
|
|
|
|
|
|
|
|
use crate::dynamic_data::{DynamicLibrary, TurnChoice};
|
|
|
|
use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef};
|
|
|
|
use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData;
|
|
|
|
use crate::static_data::EffectParameter;
|
|
|
|
use crate::StringKey;
|
|
|
|
|
2022-08-26 16:23:35 +00:00
|
|
|
/// A macro to generate the script function cache a bit easier.
|
2022-08-20 10:22:12 +00:00
|
|
|
macro_rules! script_function_cache {
|
|
|
|
(
|
|
|
|
$(
|
2022-08-26 16:23:35 +00:00
|
|
|
$name:ident($($par_type:ty),*$(,)?)
|
2022-08-20 10:22:12 +00:00
|
|
|
)*
|
|
|
|
) => {
|
|
|
|
#[derive(Default)]
|
2022-08-26 16:23:35 +00:00
|
|
|
#[allow(unused_parens)]
|
2022-08-20 10:22:12 +00:00
|
|
|
pub struct ScriptFunctionCache {
|
|
|
|
$(
|
2022-08-26 16:23:35 +00:00
|
|
|
$name: RwLock<Option<NativeFunc<(u32$(, $par_type)*), ()>>>,
|
2022-08-20 10:22:12 +00:00
|
|
|
)*
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ScriptFunctionCache {
|
|
|
|
$(
|
|
|
|
paste! {
|
|
|
|
#[cold]
|
2022-08-26 16:23:35 +00:00
|
|
|
#[allow(unused_parens)]
|
2022-08-20 10:22:12 +00:00
|
|
|
fn [<initialize_ $name>](&self, env: &Arc<WebAssemblyEnvironmentData>) {
|
|
|
|
let exported = env.exported_functions();
|
|
|
|
let f = exported.get::<StringKey>(&stringify!([< script_ $name >]).into());
|
|
|
|
if let Some(f) = f {
|
2022-08-26 16:23:35 +00:00
|
|
|
let func: NativeFunc<(u32 $(,$par_type)*), ()> = f.native().unwrap();
|
2022-08-20 10:22:12 +00:00
|
|
|
let _ = self.$name.write().insert(func);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-26 16:23:35 +00:00
|
|
|
#[allow(unused_parens)]
|
2022-08-20 10:22:12 +00:00
|
|
|
pub(crate) fn [<$name>](
|
|
|
|
&self,
|
|
|
|
env: &Arc<WebAssemblyEnvironmentData>,
|
2022-08-26 16:23:35 +00:00
|
|
|
) -> Option<NativeFunc<(u32 $(,$par_type)*), ()>> {
|
2022-08-20 10:22:12 +00:00
|
|
|
{
|
|
|
|
let read_lock = self.$name.read();
|
|
|
|
if let Some(f) = read_lock.as_ref() {
|
|
|
|
return Some(f.clone());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.[<initialize_ $name>](env);
|
|
|
|
self.$name.read().as_ref().cloned()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
script_function_cache! {
|
2022-08-26 16:23:35 +00:00
|
|
|
stack()
|
|
|
|
on_remove()
|
|
|
|
on_initialize(ExternRef<DynamicLibrary>, VecExternRef<EffectParameter>)
|
|
|
|
on_before_turn(ExternRef<TurnChoice>)
|
|
|
|
change_speed(ExternRef<TurnChoice>, u32)
|
|
|
|
change_priority(ExternRef<TurnChoice>, u32)
|
2022-08-20 10:22:12 +00:00
|
|
|
}
|