From a743c47345ba7891952555ebe6e191d2c430e6b0 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 22 May 2020 21:50:24 +0800 Subject: [PATCH] Refactor. --- src/fn_register.rs | 4 +- src/module.rs | 108 +++++++++++++++++++++++++++++--------------- src/packages/mod.rs | 26 ++++------- 3 files changed, 83 insertions(+), 55 deletions(-) diff --git a/src/fn_register.rs b/src/fn_register.rs index ec2be474..67763298 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -175,7 +175,7 @@ macro_rules! def_register { > RegisterFn 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 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),*)) ); diff --git a/src/module.rs b/src/module.rs index 48e6e936..6c366a35 100644 --- a/src/module.rs +++ b/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, /// External Rust functions. - functions: HashMap, CF)>, + functions: HashMap, 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, + all_functions: HashMap, } impl fmt::Debug for Module { @@ -164,7 +164,7 @@ impl Module { /// module.set_var("answer", 42_i64); /// assert_eq!(module.get_var_value::("answer").unwrap(), 42); /// ``` - pub fn set_var, T: Variant + Clone>(&mut self, name: K, value: T) { + pub fn set_var(&mut self, name: impl Into, 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>(&mut self, name: K, sub_module: Module) { + pub fn set_sub_module(&mut self, name: impl Into, 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, + 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, T: Variant + Clone>( + pub fn set_fn_0( &mut self, - name: K, + name: impl Into, #[cfg(not(feature = "sync"))] func: impl Fn() -> FuncReturn + 'static, #[cfg(feature = "sync")] func: impl Fn() -> FuncReturn + 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, A: Variant + Clone, T: Variant + Clone>( + pub fn set_fn_1( &mut self, - name: K, + name: impl Into, #[cfg(not(feature = "sync"))] func: impl Fn(A) -> FuncReturn + 'static, #[cfg(feature = "sync")] func: impl Fn(A) -> FuncReturn + Send + Sync + 'static, ) -> u64 { let f = move |args: &mut FnCallArgs| func(mem::take(args[0]).cast::()).map(Dynamic::from); let args = [TypeId::of::()]; - 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, A: Variant + Clone, T: Variant + Clone>( + pub fn set_fn_1_mut( &mut self, - name: K, + name: impl Into, #[cfg(not(feature = "sync"))] func: impl Fn(&mut A) -> FuncReturn + 'static, #[cfg(feature = "sync")] func: impl Fn(&mut A) -> FuncReturn + Send + Sync + 'static, ) -> u64 { @@ -352,7 +370,12 @@ impl Module { func(args[0].downcast_mut::().unwrap()).map(Dynamic::from) }; let args = [TypeId::of::()]; - 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, A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>( + pub fn set_fn_2( &mut self, - name: K, + name: impl Into, #[cfg(not(feature = "sync"))] func: impl Fn(A, B) -> FuncReturn + 'static, #[cfg(feature = "sync")] func: impl Fn(A, B) -> FuncReturn + Send + Sync + 'static, ) -> u64 { @@ -383,7 +406,12 @@ impl Module { func(a, b).map(Dynamic::from) }; let args = [TypeId::of::(), TypeId::of::()]; - 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, - A: Variant + Clone, - B: Variant + Clone, - T: Variant + Clone, - >( + pub fn set_fn_2_mut( &mut self, - name: K, + name: impl Into, #[cfg(not(feature = "sync"))] func: impl Fn(&mut A, B) -> FuncReturn + 'static, #[cfg(feature = "sync")] func: impl Fn(&mut A, B) -> FuncReturn + Send + Sync + 'static, ) -> u64 { @@ -418,7 +441,12 @@ impl Module { func(a, b).map(Dynamic::from) }; let args = [TypeId::of::(), TypeId::of::()]; - 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, A: Variant + Clone, B: Variant + Clone, C: Variant + Clone, T: Variant + Clone, >( &mut self, - name: K, + name: impl Into, #[cfg(not(feature = "sync"))] func: impl Fn(A, B, C) -> FuncReturn + 'static, #[cfg(feature = "sync")] func: impl Fn(A, B, C) -> FuncReturn + Send + Sync + 'static, ) -> u64 { @@ -456,7 +483,12 @@ impl Module { func(a, b, c).map(Dynamic::from) }; let args = [TypeId::of::(), TypeId::of::(), TypeId::of::()]; - 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, A: Variant + Clone, B: Variant + Clone, C: Variant + Clone, T: Variant + Clone, >( &mut self, - name: K, + name: impl Into, #[cfg(not(feature = "sync"))] func: impl Fn(&mut A, B, C) -> FuncReturn + 'static, #[cfg(feature = "sync")] func: impl Fn(&mut A, B, C) -> FuncReturn + Send + Sync + 'static, ) -> u64 { @@ -495,7 +526,12 @@ impl Module { func(a, b, c).map(Dynamic::from) }; let args = [TypeId::of::(), TypeId::of::(), TypeId::of::()]; - 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> { + ) -> Result<&CallableFunction, Box> { 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())); } } diff --git a/src/packages/mod.rs b/src/packages/mod.rs index 54b6ecea..075a1c68 100644 --- a/src/packages/mod.rs +++ b/src/packages/mod.rs @@ -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; - -/// Type which `Arc`-wraps a `Module` to facilitate sharing library instances. -#[cfg(feature = "sync")] -pub type PackageLibrary = Arc; +/// A sharable `Module` to facilitate sharing library instances. +pub type PackageLibrary = Shared; /// 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, -} +pub(crate) struct PackagesCollection(StaticVec); 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 { - self.packages + self.0 .iter() .map(|p| p.get_iter(id)) .find(|f| f.is_some())