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; macro_rules! script_function_cache { ( $( $name:ident -> $return:ty )* ) => { #[derive(Default)] pub struct ScriptFunctionCache { $( $name: RwLock>, )* } impl ScriptFunctionCache { $( paste! { #[cold] fn [](&self, env: &Arc) { let exported = env.exported_functions(); let f = exported.get::(&stringify!([< script_ $name >]).into()); if let Some(f) = f { let func: $return = f.native().unwrap(); let _ = self.$name.write().insert(func); } } pub(crate) fn [<$name>]( &self, env: &Arc, ) -> Option<$return> { { let read_lock = self.$name.read(); if let Some(f) = read_lock.as_ref() { return Some(f.clone()); } } self.[](env); self.$name.read().as_ref().cloned() } } )* } } } script_function_cache! { on_initialize -> NativeFunc<(u32, ExternRef, VecExternRef), ()> on_before_turn -> NativeFunc<(u32, u32), ()> }