Refactor.
This commit is contained in:
parent
8d12dc2fc1
commit
a743c47345
@ -175,7 +175,7 @@ macro_rules! def_register {
|
||||
> RegisterFn<FN, ($($mark,)*), RET> for Engine
|
||||
{
|
||||
fn register_fn(&mut self, name: &str, f: FN) {
|
||||
self.global_module.set_fn(name.to_string(), FnAccess::Public,
|
||||
self.global_module.set_fn(name, FnAccess::Public,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
CallableFunction::$abi(make_func!(f : map_dynamic ; $($par => $clone),*))
|
||||
);
|
||||
@ -192,7 +192,7 @@ macro_rules! def_register {
|
||||
> RegisterResultFn<FN, ($($mark,)*)> for Engine
|
||||
{
|
||||
fn register_result_fn(&mut self, name: &str, f: FN) {
|
||||
self.global_module.set_fn(name.to_string(), FnAccess::Public,
|
||||
self.global_module.set_fn(name, FnAccess::Public,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
CallableFunction::$abi(make_func!(f : map_result ; $($par => $clone),*))
|
||||
);
|
||||
|
108
src/module.rs
108
src/module.rs
@ -3,7 +3,7 @@
|
||||
use crate::any::{Dynamic, Variant};
|
||||
use crate::calc_fn_hash;
|
||||
use crate::engine::{Engine, FunctionsLib};
|
||||
use crate::fn_native::{CallableFunction as CF, FnCallArgs, IteratorFn};
|
||||
use crate::fn_native::{CallableFunction, FnCallArgs, IteratorFn};
|
||||
use crate::parser::{
|
||||
FnAccess,
|
||||
FnAccess::{Private, Public},
|
||||
@ -47,7 +47,7 @@ pub struct Module {
|
||||
all_variables: HashMap<u64, Dynamic>,
|
||||
|
||||
/// External Rust functions.
|
||||
functions: HashMap<u64, (String, FnAccess, StaticVec<TypeId>, CF)>,
|
||||
functions: HashMap<u64, (String, FnAccess, StaticVec<TypeId>, CallableFunction)>,
|
||||
|
||||
/// Script-defined functions.
|
||||
fn_lib: FunctionsLib,
|
||||
@ -57,7 +57,7 @@ pub struct Module {
|
||||
|
||||
/// Flattened collection of all external Rust functions, native or scripted,
|
||||
/// including those in sub-modules.
|
||||
all_functions: HashMap<u64, CF>,
|
||||
all_functions: HashMap<u64, CallableFunction>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Module {
|
||||
@ -164,7 +164,7 @@ impl Module {
|
||||
/// module.set_var("answer", 42_i64);
|
||||
/// assert_eq!(module.get_var_value::<i64>("answer").unwrap(), 42);
|
||||
/// ```
|
||||
pub fn set_var<K: Into<String>, T: Variant + Clone>(&mut self, name: K, value: T) {
|
||||
pub fn set_var(&mut self, name: impl Into<String>, value: impl Variant + Clone) {
|
||||
self.variables.insert(name.into(), Dynamic::from(value));
|
||||
}
|
||||
|
||||
@ -244,7 +244,7 @@ impl Module {
|
||||
/// module.set_sub_module("question", sub_module);
|
||||
/// assert!(module.get_sub_module("question").is_some());
|
||||
/// ```
|
||||
pub fn set_sub_module<K: Into<String>>(&mut self, name: K, sub_module: Module) {
|
||||
pub fn set_sub_module(&mut self, name: impl Into<String>, sub_module: Module) {
|
||||
self.modules.insert(name.into(), sub_module.into());
|
||||
}
|
||||
|
||||
@ -269,7 +269,15 @@ impl Module {
|
||||
/// Set a Rust function into the module, returning a hash key.
|
||||
///
|
||||
/// If there is an existing Rust function of the same hash, it is replaced.
|
||||
pub fn set_fn(&mut self, name: String, access: FnAccess, params: &[TypeId], func: CF) -> u64 {
|
||||
pub fn set_fn(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
access: FnAccess,
|
||||
params: &[TypeId],
|
||||
func: CallableFunction,
|
||||
) -> u64 {
|
||||
let name = name.into();
|
||||
|
||||
let hash_fn = calc_fn_hash(empty(), &name, params.len(), params.iter().cloned());
|
||||
|
||||
let params = params.into_iter().cloned().collect();
|
||||
@ -293,15 +301,20 @@ impl Module {
|
||||
/// let hash = module.set_fn_0("calc", || Ok(42_i64));
|
||||
/// assert!(module.get_fn(hash).is_some());
|
||||
/// ```
|
||||
pub fn set_fn_0<K: Into<String>, T: Variant + Clone>(
|
||||
pub fn set_fn_0<T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: K,
|
||||
name: impl Into<String>,
|
||||
#[cfg(not(feature = "sync"))] func: impl Fn() -> FuncReturn<T> + 'static,
|
||||
#[cfg(feature = "sync")] func: impl Fn() -> FuncReturn<T> + Send + Sync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: &mut FnCallArgs| func().map(Dynamic::from);
|
||||
let args = [];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_pure(Box::new(f)))
|
||||
self.set_fn(
|
||||
name,
|
||||
Public,
|
||||
&args,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking one parameter into the module, returning a hash key.
|
||||
@ -317,16 +330,21 @@ impl Module {
|
||||
/// let hash = module.set_fn_1("calc", |x: i64| Ok(x + 1));
|
||||
/// assert!(module.get_fn(hash).is_some());
|
||||
/// ```
|
||||
pub fn set_fn_1<K: Into<String>, A: Variant + Clone, T: Variant + Clone>(
|
||||
pub fn set_fn_1<A: Variant + Clone, T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: K,
|
||||
name: impl Into<String>,
|
||||
#[cfg(not(feature = "sync"))] func: impl Fn(A) -> FuncReturn<T> + 'static,
|
||||
#[cfg(feature = "sync")] func: impl Fn(A) -> FuncReturn<T> + Send + Sync + 'static,
|
||||
) -> u64 {
|
||||
let f =
|
||||
move |args: &mut FnCallArgs| func(mem::take(args[0]).cast::<A>()).map(Dynamic::from);
|
||||
let args = [TypeId::of::<A>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_pure(Box::new(f)))
|
||||
self.set_fn(
|
||||
name,
|
||||
Public,
|
||||
&args,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking one mutable parameter into the module, returning a hash key.
|
||||
@ -342,9 +360,9 @@ impl Module {
|
||||
/// let hash = module.set_fn_1_mut("calc", |x: &mut i64| { *x += 1; Ok(*x) });
|
||||
/// assert!(module.get_fn(hash).is_some());
|
||||
/// ```
|
||||
pub fn set_fn_1_mut<K: Into<String>, A: Variant + Clone, T: Variant + Clone>(
|
||||
pub fn set_fn_1_mut<A: Variant + Clone, T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: K,
|
||||
name: impl Into<String>,
|
||||
#[cfg(not(feature = "sync"))] func: impl Fn(&mut A) -> FuncReturn<T> + 'static,
|
||||
#[cfg(feature = "sync")] func: impl Fn(&mut A) -> FuncReturn<T> + Send + Sync + 'static,
|
||||
) -> u64 {
|
||||
@ -352,7 +370,12 @@ impl Module {
|
||||
func(args[0].downcast_mut::<A>().unwrap()).map(Dynamic::from)
|
||||
};
|
||||
let args = [TypeId::of::<A>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_method(Box::new(f)))
|
||||
self.set_fn(
|
||||
name,
|
||||
Public,
|
||||
&args,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking two parameters into the module, returning a hash key.
|
||||
@ -370,9 +393,9 @@ impl Module {
|
||||
/// });
|
||||
/// assert!(module.get_fn(hash).is_some());
|
||||
/// ```
|
||||
pub fn set_fn_2<K: Into<String>, A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
|
||||
pub fn set_fn_2<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: K,
|
||||
name: impl Into<String>,
|
||||
#[cfg(not(feature = "sync"))] func: impl Fn(A, B) -> FuncReturn<T> + 'static,
|
||||
#[cfg(feature = "sync")] func: impl Fn(A, B) -> FuncReturn<T> + Send + Sync + 'static,
|
||||
) -> u64 {
|
||||
@ -383,7 +406,12 @@ impl Module {
|
||||
func(a, b).map(Dynamic::from)
|
||||
};
|
||||
let args = [TypeId::of::<A>(), TypeId::of::<B>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_pure(Box::new(f)))
|
||||
self.set_fn(
|
||||
name,
|
||||
Public,
|
||||
&args,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking two parameters (the first one mutable) into the module,
|
||||
@ -400,14 +428,9 @@ impl Module {
|
||||
/// });
|
||||
/// assert!(module.get_fn(hash).is_some());
|
||||
/// ```
|
||||
pub fn set_fn_2_mut<
|
||||
K: Into<String>,
|
||||
A: Variant + Clone,
|
||||
B: Variant + Clone,
|
||||
T: Variant + Clone,
|
||||
>(
|
||||
pub fn set_fn_2_mut<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: K,
|
||||
name: impl Into<String>,
|
||||
#[cfg(not(feature = "sync"))] func: impl Fn(&mut A, B) -> FuncReturn<T> + 'static,
|
||||
#[cfg(feature = "sync")] func: impl Fn(&mut A, B) -> FuncReturn<T> + Send + Sync + 'static,
|
||||
) -> u64 {
|
||||
@ -418,7 +441,12 @@ impl Module {
|
||||
func(a, b).map(Dynamic::from)
|
||||
};
|
||||
let args = [TypeId::of::<A>(), TypeId::of::<B>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_method(Box::new(f)))
|
||||
self.set_fn(
|
||||
name,
|
||||
Public,
|
||||
&args,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking three parameters into the module, returning a hash key.
|
||||
@ -437,14 +465,13 @@ impl Module {
|
||||
/// assert!(module.get_fn(hash).is_some());
|
||||
/// ```
|
||||
pub fn set_fn_3<
|
||||
K: Into<String>,
|
||||
A: Variant + Clone,
|
||||
B: Variant + Clone,
|
||||
C: Variant + Clone,
|
||||
T: Variant + Clone,
|
||||
>(
|
||||
&mut self,
|
||||
name: K,
|
||||
name: impl Into<String>,
|
||||
#[cfg(not(feature = "sync"))] func: impl Fn(A, B, C) -> FuncReturn<T> + 'static,
|
||||
#[cfg(feature = "sync")] func: impl Fn(A, B, C) -> FuncReturn<T> + Send + Sync + 'static,
|
||||
) -> u64 {
|
||||
@ -456,7 +483,12 @@ impl Module {
|
||||
func(a, b, c).map(Dynamic::from)
|
||||
};
|
||||
let args = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_pure(Box::new(f)))
|
||||
self.set_fn(
|
||||
name,
|
||||
Public,
|
||||
&args,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking three parameters (the first one mutable) into the module,
|
||||
@ -476,14 +508,13 @@ impl Module {
|
||||
/// assert!(module.get_fn(hash).is_some());
|
||||
/// ```
|
||||
pub fn set_fn_3_mut<
|
||||
K: Into<String>,
|
||||
A: Variant + Clone,
|
||||
B: Variant + Clone,
|
||||
C: Variant + Clone,
|
||||
T: Variant + Clone,
|
||||
>(
|
||||
&mut self,
|
||||
name: K,
|
||||
name: impl Into<String>,
|
||||
#[cfg(not(feature = "sync"))] func: impl Fn(&mut A, B, C) -> FuncReturn<T> + 'static,
|
||||
#[cfg(feature = "sync")] func: impl Fn(&mut A, B, C) -> FuncReturn<T> + Send + Sync + 'static,
|
||||
) -> u64 {
|
||||
@ -495,7 +526,12 @@ impl Module {
|
||||
func(a, b, c).map(Dynamic::from)
|
||||
};
|
||||
let args = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||
self.set_fn(name.into(), Public, &args, CF::from_method(Box::new(f)))
|
||||
self.set_fn(
|
||||
name,
|
||||
Public,
|
||||
&args,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Get a Rust function.
|
||||
@ -512,7 +548,7 @@ impl Module {
|
||||
/// let hash = module.set_fn_1("calc", |x: i64| Ok(x + 1));
|
||||
/// assert!(module.get_fn(hash).is_some());
|
||||
/// ```
|
||||
pub fn get_fn(&self, hash_fn: u64) -> Option<&CF> {
|
||||
pub fn get_fn(&self, hash_fn: u64) -> Option<&CallableFunction> {
|
||||
self.functions.get(&hash_fn).map(|(_, _, _, v)| v)
|
||||
}
|
||||
|
||||
@ -524,7 +560,7 @@ impl Module {
|
||||
&mut self,
|
||||
name: &str,
|
||||
hash_fn_native: u64,
|
||||
) -> Result<&CF, Box<EvalAltResult>> {
|
||||
) -> Result<&CallableFunction, Box<EvalAltResult>> {
|
||||
self.all_functions.get(&hash_fn_native).ok_or_else(|| {
|
||||
Box::new(EvalAltResult::ErrorFunctionNotFound(
|
||||
name.to_string(),
|
||||
@ -591,7 +627,7 @@ impl Module {
|
||||
module: &'a Module,
|
||||
qualifiers: &mut Vec<&'a str>,
|
||||
variables: &mut Vec<(u64, Dynamic)>,
|
||||
functions: &mut Vec<(u64, CF)>,
|
||||
functions: &mut Vec<(u64, CallableFunction)>,
|
||||
) {
|
||||
for (name, m) in &module.modules {
|
||||
// Index all the sub-modules first.
|
||||
@ -640,7 +676,7 @@ impl Module {
|
||||
fn_def.params.len(),
|
||||
empty(),
|
||||
);
|
||||
functions.push((hash_fn_def, CF::Script(fn_def.clone()).into()));
|
||||
functions.push((hash_fn_def, CallableFunction::Script(fn_def.clone()).into()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Module containing all built-in _packages_ available to Rhai, plus facilities to define custom packages.
|
||||
|
||||
use crate::fn_native::{CallableFunction, IteratorFn};
|
||||
use crate::fn_native::{CallableFunction, IteratorFn, Shared};
|
||||
use crate::module::Module;
|
||||
use crate::utils::StaticVec;
|
||||
|
||||
@ -44,35 +44,27 @@ pub trait Package {
|
||||
fn get(&self) -> PackageLibrary;
|
||||
}
|
||||
|
||||
/// Type which `Rc`-wraps a `Module` to facilitate sharing library instances.
|
||||
#[cfg(not(feature = "sync"))]
|
||||
pub type PackageLibrary = Rc<Module>;
|
||||
|
||||
/// Type which `Arc`-wraps a `Module` to facilitate sharing library instances.
|
||||
#[cfg(feature = "sync")]
|
||||
pub type PackageLibrary = Arc<Module>;
|
||||
/// A sharable `Module` to facilitate sharing library instances.
|
||||
pub type PackageLibrary = Shared<Module>;
|
||||
|
||||
/// Type containing a collection of `PackageLibrary` instances.
|
||||
/// All function and type iterator keys in the loaded packages are indexed for fast access.
|
||||
#[derive(Clone, Default)]
|
||||
pub(crate) struct PackagesCollection {
|
||||
/// Collection of `PackageLibrary` instances.
|
||||
packages: StaticVec<PackageLibrary>,
|
||||
}
|
||||
pub(crate) struct PackagesCollection(StaticVec<PackageLibrary>);
|
||||
|
||||
impl PackagesCollection {
|
||||
/// Add a `PackageLibrary` into the `PackagesCollection`.
|
||||
pub fn push(&mut self, package: PackageLibrary) {
|
||||
// Later packages override previous ones.
|
||||
self.packages.insert(0, package);
|
||||
self.0.insert(0, package);
|
||||
}
|
||||
/// Does the specified function hash key exist in the `PackagesCollection`?
|
||||
pub fn contains_fn(&self, hash: u64) -> bool {
|
||||
self.packages.iter().any(|p| p.contains_fn(hash))
|
||||
self.0.iter().any(|p| p.contains_fn(hash))
|
||||
}
|
||||
/// Get specified function via its hash key.
|
||||
pub fn get_fn(&self, hash: u64) -> Option<&CallableFunction> {
|
||||
self.packages
|
||||
self.0
|
||||
.iter()
|
||||
.map(|p| p.get_fn(hash))
|
||||
.find(|f| f.is_some())
|
||||
@ -80,11 +72,11 @@ impl PackagesCollection {
|
||||
}
|
||||
/// Does the specified TypeId iterator exist in the `PackagesCollection`?
|
||||
pub fn contains_iter(&self, id: TypeId) -> bool {
|
||||
self.packages.iter().any(|p| p.contains_iter(id))
|
||||
self.0.iter().any(|p| p.contains_iter(id))
|
||||
}
|
||||
/// Get the specified TypeId iterator.
|
||||
pub fn get_iter(&self, id: TypeId) -> Option<IteratorFn> {
|
||||
self.packages
|
||||
self.0
|
||||
.iter()
|
||||
.map(|p| p.get_iter(id))
|
||||
.find(|f| f.is_some())
|
||||
|
Loading…
Reference in New Issue
Block a user