Change sub-modules to shared.

This commit is contained in:
Stephen Chung 2020-11-09 22:44:20 +08:00
parent e69444293c
commit c41f5aefcb
3 changed files with 30 additions and 47 deletions

View File

@ -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 {

View File

@ -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()
}

View File

@ -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