From 08977e2a62f3aa3717160faa69c0677967ce8e01 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Fri, 21 Aug 2020 21:48:45 +0800 Subject: [PATCH] Use combine_flatten for plugin modules. --- RELEASES.md | 9 +++++++++ src/module.rs | 33 +++++++++++++++++++++++++++++++-- src/packages/array_basic.rs | 2 +- src/packages/fn_basic.rs | 2 +- src/packages/logic.rs | 2 +- src/packages/map_basic.rs | 4 ++-- src/packages/math_basic.rs | 4 ++-- src/packages/string_more.rs | 4 ++-- src/packages/time_basic.rs | 2 +- src/parser.rs | 4 ++-- src/settings.rs | 1 + tests/plugins.rs | 16 +++++++++++----- 12 files changed, 64 insertions(+), 19 deletions(-) diff --git a/RELEASES.md b/RELEASES.md index d42f41e2..fb624187 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -4,6 +4,15 @@ Rhai Release Notes Version 0.19.0 ============== +New features +------------ + +* Adds `Module::combine_flatten` to combine two modules while flattening to the root level. + + +Version 0.18.2 +============== + Bug fixes --------- diff --git a/src/module.rs b/src/module.rs index 28c64ff0..c6e161b6 100644 --- a/src/module.rs +++ b/src/module.rs @@ -931,6 +931,24 @@ impl Module { /// Combine another module into this module. /// The other module is consumed to merge into this module. pub fn combine(&mut self, other: Self) -> &mut Self { + self.modules.extend(other.modules.into_iter()); + self.variables.extend(other.variables.into_iter()); + self.functions.extend(other.functions.into_iter()); + self.type_iterators.extend(other.type_iterators.into_iter()); + self.all_functions.clear(); + self.all_variables.clear(); + self.indexed = false; + self + } + + /// Combine another module into this module. + /// The other module is consumed to merge into this module. + /// Sub-modules are flattened onto the root module, with higher level overriding lower level. + pub fn combine_flatten(&mut self, other: Self) -> &mut Self { + other.modules.into_iter().for_each(|(_, m)| { + self.combine_flatten(m); + }); + self.variables.extend(other.variables.into_iter()); self.functions.extend(other.functions.into_iter()); self.type_iterators.extend(other.type_iterators.into_iter()); @@ -942,15 +960,26 @@ impl Module { /// Merge another module into this module. pub fn merge(&mut self, other: &Self) -> &mut Self { - self.merge_filtered(other, |_, _, _| true) + self.merge_filtered(other, &|_, _, _| true) } /// Merge another module into this module, with only selected script-defined functions based on a filter predicate. pub(crate) fn merge_filtered( &mut self, other: &Self, - _filter: impl Fn(FnAccess, &str, usize) -> bool, + _filter: &impl Fn(FnAccess, &str, usize) -> bool, ) -> &mut Self { + #[cfg(not(feature = "no_function"))] + for (k, v) in &other.modules { + let mut m = Self::new(); + m.merge_filtered(v, _filter); + self.modules.insert(k.clone(), m); + } + + #[cfg(feature = "no_function")] + self.modules + .extend(other.modules.iter().map(|(k, v)| (k.clone(), v.clone()))); + self.variables .extend(other.variables.iter().map(|(k, v)| (k.clone(), v.clone()))); diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 433f815f..5b117731 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -59,7 +59,7 @@ macro_rules! reg_pad { } def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, { - lib.combine(exported_module!(array_functions)); + lib.combine_flatten(exported_module!(array_functions)); reg_functions!(lib += basic; INT, bool, char, ImmutableString, FnPtr, Array, Unit); reg_pad!(lib, INT, bool, char, ImmutableString, FnPtr, Array, Unit); diff --git a/src/packages/fn_basic.rs b/src/packages/fn_basic.rs index a115485a..274b85e1 100644 --- a/src/packages/fn_basic.rs +++ b/src/packages/fn_basic.rs @@ -3,7 +3,7 @@ use crate::fn_native::FnPtr; use crate::plugin::*; def_package!(crate:BasicFnPackage:"Basic Fn functions.", lib, { - lib.combine(exported_module!(fn_ptr_functions)); + lib.combine_flatten(exported_module!(fn_ptr_functions)); }); #[export_module] diff --git a/src/packages/logic.rs b/src/packages/logic.rs index 60d7d75c..0c994dca 100644 --- a/src/packages/logic.rs +++ b/src/packages/logic.rs @@ -47,7 +47,7 @@ macro_rules! gen_cmp_functions { macro_rules! reg_functions { ($mod_name:ident += $root:ident ; $($arg_type:ident),+) => { - $($mod_name.combine(exported_module!($root::$arg_type::functions));)* + $($mod_name.combine_flatten(exported_module!($root::$arg_type::functions));)* } } diff --git a/src/packages/map_basic.rs b/src/packages/map_basic.rs index 5834e66b..97e4a9a9 100644 --- a/src/packages/map_basic.rs +++ b/src/packages/map_basic.rs @@ -9,11 +9,11 @@ use crate::plugin::*; use crate::stdlib::vec::Vec; def_package!(crate:BasicMapPackage:"Basic object map utilities.", lib, { - lib.combine(exported_module!(map_functions)); + lib.combine_flatten(exported_module!(map_functions)); // Register map access functions #[cfg(not(feature = "no_index"))] - lib.combine(exported_module!(index_functions)); + lib.combine_flatten(exported_module!(index_functions)); }); #[export_module] diff --git a/src/packages/math_basic.rs b/src/packages/math_basic.rs index f8679766..d5904998 100644 --- a/src/packages/math_basic.rs +++ b/src/packages/math_basic.rs @@ -26,10 +26,10 @@ def_package!(crate:BasicMathPackage:"Basic mathematic functions.", lib, { #[cfg(not(feature = "no_float"))] { // Floating point functions - lib.combine(exported_module!(float_functions)); + lib.combine_flatten(exported_module!(float_functions)); // Trig functions - lib.combine(exported_module!(trig_functions)); + lib.combine_flatten(exported_module!(trig_functions)); // Register conversion functions lib.set_fn_1("to_float", |x: INT| Ok(x as FLOAT)); diff --git a/src/packages/string_more.rs b/src/packages/string_more.rs index fbcb2acd..a387ac40 100644 --- a/src/packages/string_more.rs +++ b/src/packages/string_more.rs @@ -60,9 +60,9 @@ def_package!(crate:MoreStringPackage:"Additional string utilities, including str reg_functions!(lib += float; f32, f64); #[cfg(not(feature = "no_index"))] - lib.combine(exported_module!(index_functions)); + lib.combine_flatten(exported_module!(index_functions)); - lib.combine(exported_module!(string_functions)); + lib.combine_flatten(exported_module!(string_functions)); lib.set_raw_fn( "pad", diff --git a/src/packages/time_basic.rs b/src/packages/time_basic.rs index 6aff8096..d1401288 100644 --- a/src/packages/time_basic.rs +++ b/src/packages/time_basic.rs @@ -26,7 +26,7 @@ use instant::Instant; def_package!(crate:BasicTimePackage:"Basic timing utilities.", lib, { // Register date/time functions - lib.combine(exported_module!(time_functions)); + lib.combine_flatten(exported_module!(time_functions)); }); #[export_module] diff --git a/src/parser.rs b/src/parser.rs index b8bb9cd8..da184a16 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -133,7 +133,7 @@ impl AST { filter: impl Fn(FnAccess, &str, usize) -> bool, ) -> Self { let mut functions: Module = Default::default(); - functions.merge_filtered(&self.1, filter); + functions.merge_filtered(&self.1, &filter); Self(Default::default(), functions) } @@ -266,7 +266,7 @@ impl AST { }; let mut functions = functions.clone(); - functions.merge_filtered(&other.1, filter); + functions.merge_filtered(&other.1, &filter); Self::new(ast, functions) } diff --git a/src/settings.rs b/src/settings.rs index 6e9e020d..4f0f7ccf 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -17,6 +17,7 @@ use crate::stdlib::boxed::Box; impl Engine { /// Load a new package into the `Engine`. + /// Anything that can be converted into a `PackageLibrary` is accepted, including a simple `Module`. /// /// When searching for functions, packages loaded later are preferred. /// In other words, loaded packages are searched in reverse order. diff --git a/tests/plugins.rs b/tests/plugins.rs index 9d40107e..46a52ede 100644 --- a/tests/plugins.rs +++ b/tests/plugins.rs @@ -10,11 +10,16 @@ mod test { pub mod special_array_package { use rhai::{Array, INT}; - #[rhai_fn(get = "foo", return_raw)] - #[inline(always)] - pub fn foo(array: &mut Array) -> Result> { - Ok(array[0].clone()) + #[cfg(not(feature = "no_object"))] + #[rhai_mod()] + pub mod feature { + #[rhai_fn(get = "foo", return_raw)] + #[inline(always)] + pub fn foo(array: &mut Array) -> Result> { + Ok(array[0].clone()) + } } + #[rhai_fn(name = "test")] #[inline(always)] pub fn len(array: &mut Array, mul: INT) -> INT { @@ -59,7 +64,8 @@ gen_unary_functions!(greet = make_greeting(INT, bool, char) -> String); fn test_plugins_package() -> Result<(), Box> { let mut engine = Engine::new(); - let m = exported_module!(test::special_array_package); + let mut m = Module::new(); + m.combine_flatten(exported_module!(test::special_array_package)); engine.load_package(m); reg_functions!(engine += greet::single(INT, bool, char));