Add Engine::load_module.
This commit is contained in:
@@ -596,6 +596,8 @@ pub struct Engine {
|
||||
pub(crate) global_module: Module,
|
||||
/// A collection of all library packages loaded into the Engine.
|
||||
pub(crate) packages: PackagesCollection,
|
||||
/// A collection of all sub-modules directly loaded into the Engine.
|
||||
pub(crate) global_sub_modules: Imports,
|
||||
|
||||
/// A module resolution service.
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
@@ -711,6 +713,7 @@ impl Engine {
|
||||
|
||||
packages: Default::default(),
|
||||
global_module: Default::default(),
|
||||
global_sub_modules: Default::default(),
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
@@ -773,6 +776,7 @@ impl Engine {
|
||||
|
||||
packages: Default::default(),
|
||||
global_module: Default::default(),
|
||||
global_sub_modules: Default::default(),
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
module_resolver: None,
|
||||
@@ -1814,7 +1818,7 @@ impl Engine {
|
||||
|
||||
Expr::True(_) => Ok(true.into()),
|
||||
Expr::False(_) => Ok(false.into()),
|
||||
Expr::Unit(_) => Ok(().into()),
|
||||
Expr::Unit(_) => Ok(Dynamic::UNIT),
|
||||
|
||||
Expr::Custom(custom, _) => {
|
||||
let expressions = custom
|
||||
@@ -2090,7 +2094,7 @@ impl Engine {
|
||||
} else if let Some(def_stmt) = def_stmt {
|
||||
self.eval_stmt(scope, mods, state, lib, this_ptr, def_stmt, level)
|
||||
} else {
|
||||
Ok(().into())
|
||||
Ok(Dynamic::UNIT)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,9 @@ use crate::fn_register::{RegisterFn, RegisterResultFn};
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
use crate::{fn_args::FuncArgs, fn_call::ensure_no_data_race, module::Module, StaticVec};
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
use crate::fn_native::{shared_take_or_clone, Shared};
|
||||
|
||||
#[cfg(not(feature = "no_optimize"))]
|
||||
use crate::optimize::optimize_into_ast;
|
||||
|
||||
@@ -772,6 +775,45 @@ impl Engine {
|
||||
self.register_indexer_get(getter)
|
||||
.register_indexer_set(setter)
|
||||
}
|
||||
/// Register a `Module` as a sub-module with the `Engine`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # fn main() -> Result<(), Box<rhai::EvalAltResult>> {
|
||||
/// use rhai::{Engine, Module};
|
||||
///
|
||||
/// let mut engine = Engine::new();
|
||||
///
|
||||
/// // Create the module
|
||||
/// let mut module = Module::new();
|
||||
/// module.set_fn_1("calc", |x: i64| Ok(x + 1));
|
||||
///
|
||||
/// // Register the module as a sub-module
|
||||
/// engine.register_module("CalcService", module);
|
||||
///
|
||||
/// assert_eq!(engine.eval::<i64>("CalcService::calc(41)")?, 42);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
pub fn register_module(
|
||||
&mut self,
|
||||
name: impl Into<ImmutableString>,
|
||||
module: impl Into<Shared<Module>>,
|
||||
) -> &mut Self {
|
||||
let module = module.into();
|
||||
|
||||
if !module.is_indexed() {
|
||||
// Index the module (making a clone copy if necessary) if it is not indexed
|
||||
let mut module = shared_take_or_clone(module);
|
||||
module.build_index();
|
||||
self.global_sub_modules.push(name, module);
|
||||
} else {
|
||||
self.global_sub_modules.push(name, module);
|
||||
}
|
||||
self
|
||||
}
|
||||
/// Compile a string into an `AST`, which can be used later for evaluation.
|
||||
///
|
||||
/// # Example
|
||||
@@ -1368,7 +1410,8 @@ impl Engine {
|
||||
scope: &mut Scope,
|
||||
ast: &AST,
|
||||
) -> Result<T, Box<EvalAltResult>> {
|
||||
let mut mods = Default::default();
|
||||
let mut mods = self.global_sub_modules.clone();
|
||||
|
||||
let (result, _) = self.eval_ast_with_scope_raw(scope, &mut mods, ast)?;
|
||||
|
||||
let typ = self.map_type_name(result.type_name());
|
||||
@@ -1446,7 +1489,8 @@ impl Engine {
|
||||
scope: &mut Scope,
|
||||
ast: &AST,
|
||||
) -> Result<(), Box<EvalAltResult>> {
|
||||
let mut mods = Default::default();
|
||||
let mut mods = self.global_sub_modules.clone();
|
||||
|
||||
self.eval_statements_raw(scope, &mut mods, ast.statements(), &[ast.lib()])
|
||||
.map(|_| ())
|
||||
}
|
||||
@@ -1599,7 +1643,7 @@ impl Engine {
|
||||
.ok_or_else(|| EvalAltResult::ErrorFunctionNotFound(name.into(), NO_POS))?;
|
||||
|
||||
let mut state = Default::default();
|
||||
let mut mods = Default::default();
|
||||
let mut mods = self.global_sub_modules.clone();
|
||||
|
||||
// Check for data race.
|
||||
if cfg!(not(feature = "no_closure")) {
|
||||
|
@@ -16,7 +16,11 @@ use crate::{calc_native_fn_hash, calc_script_fn_hash, StaticVec};
|
||||
use crate::ast::ScriptFnDef;
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
use crate::{ast::AST, engine::Engine, scope::Scope};
|
||||
use crate::{
|
||||
ast::AST,
|
||||
engine::{Engine, Imports},
|
||||
scope::Scope,
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
use crate::engine::{Array, FN_IDX_GET, FN_IDX_SET};
|
||||
@@ -1361,7 +1365,8 @@ impl Module {
|
||||
ast: &AST,
|
||||
engine: &Engine,
|
||||
) -> Result<Self, Box<EvalAltResult>> {
|
||||
let mut mods = Default::default();
|
||||
let mut mods = engine.global_sub_modules.clone();
|
||||
let orig_mods_len = mods.len();
|
||||
|
||||
// Run the script
|
||||
engine.eval_ast_with_scope_raw(&mut scope, &mut mods, &ast)?;
|
||||
@@ -1380,8 +1385,11 @@ impl Module {
|
||||
}
|
||||
});
|
||||
|
||||
// Modules left in the scope become sub-modules
|
||||
mods.iter().for_each(|(alias, m)| {
|
||||
// Extra modules left in the scope become sub-modules
|
||||
let mut func_mods: Imports = Default::default();
|
||||
|
||||
mods.into_iter().skip(orig_mods_len).for_each(|(alias, m)| {
|
||||
func_mods.push(alias.clone(), m.clone());
|
||||
module.set_sub_module(alias, m);
|
||||
});
|
||||
|
||||
@@ -1396,7 +1404,7 @@ impl Module {
|
||||
// Encapsulate AST environment
|
||||
let mut func = func.as_ref().clone();
|
||||
func.lib = Some(ast_lib.clone());
|
||||
func.mods = mods.clone();
|
||||
func.mods = func_mods.clone();
|
||||
module.set_script_fn(func.into());
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user