Merge pull request #291 from schungx/master
Change sub-modules to shared.
This commit is contained in:
commit
9bf8219803
@ -18,7 +18,7 @@ use crate::{calc_native_fn_hash, StaticVec};
|
||||
use crate::INT;
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
use crate::{fn_native::shared_try_take, module::ModuleResolver};
|
||||
use crate::{fn_native::shared_take_or_clone, module::ModuleResolver};
|
||||
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
@ -2159,8 +2159,7 @@ impl Engine {
|
||||
if let Some(name_def) = alias {
|
||||
if !module.is_indexed() {
|
||||
// Index the module (making a clone copy if necessary) if it is not indexed
|
||||
let mut module =
|
||||
shared_try_take(module).unwrap_or_else(|m| m.as_ref().clone());
|
||||
let mut module = shared_take_or_clone(module);
|
||||
module.build_index();
|
||||
mods.push(name_def.name.clone(), module);
|
||||
} else {
|
||||
|
@ -176,6 +176,7 @@ impl<'e, 'a, 'm, 'pm> NativeCallContext<'e, 'a, 'm, 'pm> {
|
||||
|
||||
/// Consume a `Shared` resource and return a mutable reference to the wrapped value.
|
||||
/// If the resource is shared (i.e. has other outstanding references), a cloned copy is used.
|
||||
#[inline(always)]
|
||||
pub fn shared_make_mut<T: Clone>(value: &mut Shared<T>) -> &mut T {
|
||||
#[cfg(not(feature = "sync"))]
|
||||
return Rc::make_mut(value);
|
||||
@ -183,7 +184,14 @@ pub fn shared_make_mut<T: Clone>(value: &mut Shared<T>) -> &mut T {
|
||||
return Arc::make_mut(value);
|
||||
}
|
||||
|
||||
/// Consume a `Shared` resource if is unique (i.e. not shared), or clone it otherwise.
|
||||
#[inline(always)]
|
||||
pub fn shared_take_or_clone<T: Clone>(value: Shared<T>) -> T {
|
||||
shared_try_take(value).unwrap_or_else(|v| v.as_ref().clone())
|
||||
}
|
||||
|
||||
/// Consume a `Shared` resource if is unique (i.e. not shared).
|
||||
#[inline(always)]
|
||||
pub fn shared_try_take<T>(value: Shared<T>) -> Result<T, Shared<T>> {
|
||||
#[cfg(not(feature = "sync"))]
|
||||
return Rc::try_unwrap(value);
|
||||
@ -196,6 +204,7 @@ pub fn shared_try_take<T>(value: Shared<T>) -> Result<T, Shared<T>> {
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the resource is shared (i.e. has other outstanding references).
|
||||
#[inline(always)]
|
||||
pub fn shared_take<T>(value: Shared<T>) -> T {
|
||||
shared_try_take(value).map_err(|_| ()).unwrap()
|
||||
}
|
||||
|
@ -2,7 +2,10 @@
|
||||
|
||||
use crate::ast::{FnAccess, Ident};
|
||||
use crate::dynamic::{Dynamic, Variant};
|
||||
use crate::fn_native::{CallableFunction, FnCallArgs, IteratorFn, NativeCallContext, SendSync};
|
||||
use crate::fn_native::{
|
||||
shared_make_mut, shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn,
|
||||
NativeCallContext, SendSync, Shared,
|
||||
};
|
||||
use crate::fn_register::by_value as cast_arg;
|
||||
use crate::result::EvalAltResult;
|
||||
use crate::token::{Token, NO_POS};
|
||||
@ -10,7 +13,7 @@ use crate::utils::{ImmutableString, StraightHasherBuilder};
|
||||
use crate::{calc_native_fn_hash, calc_script_fn_hash, StaticVec};
|
||||
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
use crate::{ast::ScriptFnDef, fn_native::Shared};
|
||||
use crate::ast::ScriptFnDef;
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
use crate::{ast::AST, engine::Engine, scope::Scope};
|
||||
@ -56,10 +59,10 @@ pub struct FuncInfo {
|
||||
/// external Rust functions, and script-defined functions.
|
||||
///
|
||||
/// Not available under the `no_module` feature.
|
||||
#[derive(Default)]
|
||||
#[derive(Default, Clone)]
|
||||
pub struct Module {
|
||||
/// Sub-modules.
|
||||
modules: HashMap<String, Module>,
|
||||
modules: HashMap<String, Shared<Module>>,
|
||||
/// Module variables.
|
||||
variables: HashMap<String, Dynamic>,
|
||||
/// Flattened collection of all module variables, including those in sub-modules.
|
||||
@ -99,19 +102,6 @@ impl fmt::Debug for Module {
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Module {
|
||||
#[inline(always)]
|
||||
fn clone(&self) -> Self {
|
||||
// Only clone the index at the top level
|
||||
Self {
|
||||
all_variables: self.all_variables.clone(),
|
||||
all_functions: self.all_functions.clone(),
|
||||
indexed: self.indexed,
|
||||
..self.do_clone(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<Module> for Module {
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> &Module {
|
||||
@ -195,25 +185,6 @@ impl Module {
|
||||
self.indexed
|
||||
}
|
||||
|
||||
/// Clone the module, optionally skipping the index.
|
||||
#[inline(always)]
|
||||
fn do_clone(&self, clone_index: bool) -> Self {
|
||||
Self {
|
||||
modules: if clone_index {
|
||||
self.modules.clone()
|
||||
} else {
|
||||
self.modules
|
||||
.iter()
|
||||
.map(|(k, m)| (k.clone(), m.do_clone(clone_index)))
|
||||
.collect()
|
||||
},
|
||||
variables: self.variables.clone(),
|
||||
functions: self.functions.clone(),
|
||||
type_iterators: self.type_iterators.clone(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Does a variable exist in the module?
|
||||
///
|
||||
/// # Example
|
||||
@ -377,7 +348,7 @@ impl Module {
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn get_sub_module(&self, name: &str) -> Option<&Module> {
|
||||
self.modules.get(name)
|
||||
self.modules.get(name).map(|m| m.as_ref())
|
||||
}
|
||||
|
||||
/// Get a mutable reference to a sub-module.
|
||||
@ -394,7 +365,7 @@ impl Module {
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn get_sub_module_mut(&mut self, name: &str) -> Option<&mut Module> {
|
||||
self.modules.get_mut(name)
|
||||
self.modules.get_mut(name).map(shared_make_mut)
|
||||
}
|
||||
|
||||
/// Set a sub-module into the module.
|
||||
@ -412,7 +383,11 @@ impl Module {
|
||||
/// assert!(module.get_sub_module("question").is_some());
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_sub_module(&mut self, name: impl Into<String>, sub_module: Module) -> &mut Self {
|
||||
pub fn set_sub_module(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
sub_module: impl Into<Shared<Module>>,
|
||||
) -> &mut Self {
|
||||
self.modules.insert(name.into(), sub_module.into());
|
||||
self.indexed = false;
|
||||
self
|
||||
@ -1160,7 +1135,7 @@ impl Module {
|
||||
#[inline]
|
||||
pub fn combine_flatten(&mut self, other: Self) -> &mut Self {
|
||||
other.modules.into_iter().for_each(|(_, m)| {
|
||||
self.combine_flatten(m);
|
||||
self.combine_flatten(shared_take_or_clone(m));
|
||||
});
|
||||
self.variables.extend(other.variables.into_iter());
|
||||
self.functions.extend(other.functions.into_iter());
|
||||
@ -1213,7 +1188,7 @@ impl Module {
|
||||
other.modules.iter().for_each(|(k, v)| {
|
||||
let mut m = Self::new();
|
||||
m.merge_filtered(v, _filter);
|
||||
self.modules.insert(k.clone(), m);
|
||||
self.set_sub_module(k, m);
|
||||
});
|
||||
#[cfg(feature = "no_function")]
|
||||
self.modules
|
||||
@ -1266,8 +1241,8 @@ impl Module {
|
||||
pub fn count(&self) -> (usize, usize, usize) {
|
||||
(
|
||||
self.variables.len(),
|
||||
self.variables.len(),
|
||||
self.variables.len(),
|
||||
self.functions.len(),
|
||||
self.type_iterators.len(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1393,7 +1368,7 @@ impl Module {
|
||||
|
||||
// Modules left in the scope become sub-modules
|
||||
mods.iter().for_each(|(alias, m)| {
|
||||
module.modules.insert(alias.to_string(), m.as_ref().clone());
|
||||
module.set_sub_module(alias, m);
|
||||
});
|
||||
|
||||
// Non-private functions defined become module functions
|
||||
|
Loading…
Reference in New Issue
Block a user