Rename packages to global modules.

This commit is contained in:
Stephen Chung
2020-12-22 23:45:14 +08:00
parent eb46ec8296
commit 15fb03218c
34 changed files with 192 additions and 218 deletions

View File

@@ -613,8 +613,8 @@ pub struct Engine {
/// A module containing all functions directly loaded into the Engine.
pub(crate) global_namespace: Module,
/// A collection of all library packages loaded into the Engine.
pub(crate) packages: StaticVec<Shared<Module>>,
/// A collection of all modules loaded into the global namespace of the Engine.
pub(crate) global_modules: StaticVec<Shared<Module>>,
/// A collection of all sub-modules directly loaded into the Engine.
pub(crate) global_sub_modules: Imports,
@@ -745,8 +745,8 @@ impl Engine {
let mut engine = Self {
id: Default::default(),
packages: Default::default(),
global_namespace: Default::default(),
global_modules: Default::default(),
global_sub_modules: Default::default(),
#[cfg(not(feature = "no_module"))]
@@ -798,20 +798,20 @@ impl Engine {
disable_doc_comments: false,
};
engine.load_package(StandardPackage::new().get());
engine.register_global_module(StandardPackage::new().as_shared_module());
engine
}
/// Create a new [`Engine`] with minimal built-in functions.
/// Use the [`load_package`][Engine::load_package] method to load additional packages of functions.
/// Use the [`register_global_module`][Engine::register_global_module] method to load additional packages of functions.
#[inline]
pub fn new_raw() -> Self {
Self {
id: Default::default(),
packages: Default::default(),
global_namespace: Default::default(),
global_modules: Default::default(),
global_sub_modules: Default::default(),
#[cfg(not(feature = "no_module"))]
@@ -1971,7 +1971,11 @@ impl Engine {
match self
.global_namespace
.get_fn(hash_fn, false)
.or_else(|| self.packages.iter().find_map(|m| m.get_fn(hash_fn, false)))
.or_else(|| {
self.global_modules
.iter()
.find_map(|m| m.get_fn(hash_fn, false))
})
.or_else(|| mods.get_fn(hash_fn))
{
// op= function registered as method
@@ -2180,7 +2184,11 @@ impl Engine {
let func = self
.global_namespace
.get_iter(iter_type)
.or_else(|| self.packages.iter().find_map(|m| m.get_iter(iter_type)))
.or_else(|| {
self.global_modules
.iter()
.find_map(|m| m.get_iter(iter_type))
})
.or_else(|| mods.get_iter(iter_type));
if let Some(func) = func {

View File

@@ -14,8 +14,8 @@ use crate::stdlib::{
};
use crate::utils::get_hasher;
use crate::{
scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, NativeCallContext,
ParseError, Position, AST,
scope::Scope, Dynamic, Engine, EvalAltResult, FnAccess, FnNamespace, Module, NativeCallContext,
ParseError, Position, Shared, AST,
};
#[cfg(not(feature = "no_index"))]
@@ -723,7 +723,23 @@ impl Engine {
self.register_indexer_get(getter)
.register_indexer_set(setter)
}
/// Register a [`Module`][crate::Module] as a fixed module namespace with the [`Engine`].
/// Register a shared [`Module`][crate::Module] into the global namespace of [`Engine`].
///
/// All functions and type iterators are automatically available to scripts without namespace qualifications.
///
/// Sub-modules and variables are **ignored**.
///
/// When searching for functions, modules loaded later are preferred.
/// In other words, loaded modules are searched in reverse order.
#[inline(always)]
pub fn register_global_module(&mut self, package: impl Into<Shared<Module>>) -> &mut Self {
// Insert the module into the front
self.global_modules.insert(0, package.into());
self
}
/// Register a shared [`Module`][crate::Module] as a static module namespace with the [`Engine`].
///
/// Functions marked `FnNamespace::Global` and type iterators are exposed to scripts without namespace qualifications.
///
/// # Example
///
@@ -738,17 +754,17 @@ impl Engine {
/// module.set_fn_1("calc", |x: i64| Ok(x + 1));
///
/// // Register the module as a fixed sub-module
/// engine.register_module("CalcService", module);
/// engine.register_static_module("CalcService", module);
///
/// assert_eq!(engine.eval::<i64>("CalcService::calc(41)")?, 42);
/// # Ok(())
/// # }
/// ```
#[cfg(not(feature = "no_module"))]
pub fn register_module(
pub fn register_static_module(
&mut self,
name: impl Into<crate::ImmutableString>,
module: impl Into<crate::Shared<crate::Module>>,
module: impl Into<Shared<Module>>,
) -> &mut Self {
let module = module.into();
@@ -1681,7 +1697,11 @@ impl Engine {
});
if include_packages {
signatures.extend(self.packages.iter().flat_map(|m| m.gen_fn_signatures()));
signatures.extend(
self.global_modules
.iter()
.flat_map(|m| m.gen_fn_signatures()),
);
}
signatures

View File

@@ -2,22 +2,12 @@
use crate::stdlib::{format, string::String};
use crate::token::{is_valid_identifier, Token};
use crate::{Engine, Module, Shared};
use crate::Engine;
#[cfg(not(feature = "no_module"))]
use crate::stdlib::boxed::Box;
impl Engine {
/// Load a new package into the [`Engine`].
/// A simple [`Module`][crate::Module] is automatically converted into a package.
///
/// When searching for functions, packages loaded later are preferred.
/// In other words, loaded packages are searched in reverse order.
#[inline(always)]
pub fn load_package(&mut self, package: impl Into<Shared<Module>>) -> &mut Self {
self.packages.insert(0, package.into());
self
}
/// Control whether and how the [`Engine`] will optimize an [`AST`][crate::AST] after compilation.
///
/// Not available under the `no_optimize` feature.

View File

@@ -184,7 +184,11 @@ impl Engine {
let f = self
.global_namespace
.get_fn(hash_fn, pub_only)
.or_else(|| self.packages.iter().find_map(|m| m.get_fn(hash_fn, false)))
.or_else(|| {
self.global_modules
.iter()
.find_map(|m| m.get_fn(hash_fn, false))
})
.or_else(|| mods.get_fn(hash_fn));
state.functions_cache.insert(hash_fn, f.cloned());
@@ -460,8 +464,8 @@ impl Engine {
//|| (hash_script != 0 && self.global_namespace.contains_fn(hash_script, pub_only))
|| self.global_namespace.contains_fn(hash_fn, false)
// Then check packages
|| (hash_script != 0 && self.packages.iter().any(|m| m.contains_fn(hash_script, false)))
|| self.packages.iter().any(|m| m.contains_fn(hash_fn, false))
|| (hash_script != 0 && self.global_modules.iter().any(|m| m.contains_fn(hash_script, false)))
|| self.global_modules.iter().any(|m| m.contains_fn(hash_fn, false))
// Then check imported modules
|| (hash_script != 0 && mods.map(|m| m.contains_fn(hash_script)).unwrap_or(false))
|| mods.map(|m| m.contains_fn(hash_fn)).unwrap_or(false)
@@ -542,7 +546,7 @@ impl Engine {
})
//.or_else(|| self.global_namespace.get_fn(hash_script, pub_only))
.or_else(|| {
self.packages
self.global_modules
.iter()
.find_map(|m| m.get_fn(hash_script, false))
.map(|f| (f, None))

View File

@@ -1,8 +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::stdlib::{any::TypeId, string::String};
use crate::{Module, Shared, StaticVec};
use crate::{Module, Shared};
pub(crate) mod arithmetic;
mod array_basic;
@@ -39,7 +37,7 @@ pub trait Package {
fn init(lib: &mut Module);
/// Retrieve the generic package library from this package.
fn get(&self) -> Shared<Module>;
fn as_shared_module(&self) -> Shared<Module>;
}
/// Macro that makes it easy to define a _package_ (which is basically a shared module)
@@ -71,7 +69,7 @@ macro_rules! def_package {
pub struct $package($root::Shared<$root::Module>);
impl $root::packages::Package for $package {
fn get(&self) -> $root::Shared<$root::Module> {
fn as_shared_module(&self) -> $root::Shared<$root::Module> {
self.0.clone()
}

View File

@@ -219,17 +219,17 @@ impl Engine {
/// Functions from the following sources are included:
/// 1) Functions defined in an [`AST`][crate::AST]
/// 2) Functions registered into the global namespace
/// 3) Functions in registered sub-modules
/// 4) Functions in packages (optional)
/// 3) Functions in static modules
/// 4) Functions in global modules (optional)
pub fn gen_fn_metadata_with_ast_to_json(
&self,
ast: &AST,
include_packages: bool,
include_global: bool,
) -> serde_json::Result<String> {
let mut global: ModuleMetadata = Default::default();
if include_packages {
self.packages
if include_global {
self.global_modules
.iter()
.flat_map(|m| m.iter_fn().map(|f| f.into()))
.for_each(|info| global.functions.push(info));
@@ -260,9 +260,9 @@ impl Engine {
///
/// Functions from the following sources are included:
/// 1) Functions registered into the global namespace
/// 2) Functions in registered sub-modules
/// 3) Functions in packages (optional)
pub fn gen_fn_metadata_to_json(&self, include_packages: bool) -> serde_json::Result<String> {
self.gen_fn_metadata_with_ast_to_json(&Default::default(), include_packages)
/// 2) Functions in static modules
/// 3) Functions in global modules (optional)
pub fn gen_fn_metadata_to_json(&self, include_global: bool) -> serde_json::Result<String> {
self.gen_fn_metadata_with_ast_to_json(&Default::default(), include_global)
}
}