Fix sync feature.

This commit is contained in:
Stephen Chung 2020-05-12 16:32:22 +08:00
parent 2e28967565
commit 03c64688ad
7 changed files with 88 additions and 63 deletions

View File

@ -93,7 +93,7 @@ pub trait Variant: Any + Send + Sync {
fn as_mut_any(&mut self) -> &mut dyn Any; fn as_mut_any(&mut self) -> &mut dyn Any;
/// Convert this `Variant` trait object to an `Any` trait object. /// Convert this `Variant` trait object to an `Any` trait object.
fn as_box_any(self) -> Box<dyn Any>; fn as_box_any(self: Box<Self>) -> Box<dyn Any>;
/// Get the name of this type. /// Get the name of this type.
fn type_name(&self) -> &'static str; fn type_name(&self) -> &'static str;

View File

@ -4,6 +4,9 @@ use crate::any::{Dynamic, Variant};
use crate::engine::{make_getter, make_setter, Engine, State, FUNC_INDEXER}; use crate::engine::{make_getter, make_setter, Engine, State, FUNC_INDEXER};
use crate::error::ParseError; use crate::error::ParseError;
use crate::fn_call::FuncArgs; use crate::fn_call::FuncArgs;
use crate::fn_native::{
IteratorCallback, ObjectGetCallback, ObjectIndexerCallback, ObjectSetCallback,
};
use crate::fn_register::RegisterFn; use crate::fn_register::RegisterFn;
use crate::optimize::{optimize_into_ast, OptimizationLevel}; use crate::optimize::{optimize_into_ast, OptimizationLevel};
use crate::parser::{parse, parse_global_expr, AST}; use crate::parser::{parse, parse_global_expr, AST};
@ -22,56 +25,10 @@ use crate::stdlib::{
mem, mem,
string::{String, ToString}, string::{String, ToString},
}; };
#[cfg(not(feature = "no_std"))] #[cfg(not(feature = "no_std"))]
use crate::stdlib::{fs::File, io::prelude::*, path::PathBuf}; use crate::stdlib::{fs::File, io::prelude::*, path::PathBuf};
// Define callback function types
#[cfg(feature = "sync")]
pub trait ObjectGetCallback<T, U>: Fn(&mut T) -> U + Send + Sync + 'static {}
#[cfg(feature = "sync")]
impl<F: Fn(&mut T) -> U + Send + Sync + 'static, T, U> ObjectGetCallback<T, U> for F {}
#[cfg(not(feature = "sync"))]
pub trait ObjectGetCallback<T, U>: Fn(&mut T) -> U + 'static {}
#[cfg(not(feature = "sync"))]
impl<F: Fn(&mut T) -> U + 'static, T, U> ObjectGetCallback<T, U> for F {}
#[cfg(feature = "sync")]
pub trait ObjectSetCallback<T, U>: Fn(&mut T, U) + Send + Sync + 'static {}
#[cfg(feature = "sync")]
impl<F: Fn(&mut T, U) + Send + Sync + 'static, T, U> ObjectSetCallback<T, U> for F {}
#[cfg(not(feature = "sync"))]
pub trait ObjectSetCallback<T, U>: Fn(&mut T, U) + 'static {}
#[cfg(not(feature = "sync"))]
impl<F: Fn(&mut T, U) + 'static, T, U> ObjectSetCallback<T, U> for F {}
#[cfg(feature = "sync")]
pub trait ObjectIndexerCallback<T, X, U>: Fn(&mut T, X) -> U + Send + Sync + 'static {}
#[cfg(feature = "sync")]
impl<F: Fn(&mut T, X) -> U + Send + Sync + 'static, T, X, U> ObjectIndexerCallback<T, X, U> for F {}
#[cfg(not(feature = "sync"))]
pub trait ObjectIndexerCallback<T, X, U>: Fn(&mut T, X) -> U + 'static {}
#[cfg(not(feature = "sync"))]
impl<F: Fn(&mut T, X) -> U + 'static, T, X, U> ObjectIndexerCallback<T, X, U> for F {}
#[cfg(feature = "sync")]
pub trait IteratorCallback:
Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Send + Sync + 'static
{
}
#[cfg(feature = "sync")]
impl<F: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Send + Sync + 'static> IteratorCallback
for F
{
}
#[cfg(not(feature = "sync"))]
pub trait IteratorCallback: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + 'static {}
#[cfg(not(feature = "sync"))]
impl<F: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + 'static> IteratorCallback for F {}
/// Engine public API /// Engine public API
impl Engine { impl Engine {
/// Register a custom type for use with the `Engine`. /// Register a custom type for use with the `Engine`.

View File

@ -3,7 +3,7 @@
use crate::any::{Dynamic, Union}; use crate::any::{Dynamic, Union};
use crate::calc_fn_hash; use crate::calc_fn_hash;
use crate::error::ParseErrorType; use crate::error::ParseErrorType;
use crate::fn_native::{FnCallArgs, NativeFunctionABI}; use crate::fn_native::{FnCallArgs, NativeFunctionABI, PrintCallback};
use crate::optimize::OptimizationLevel; use crate::optimize::OptimizationLevel;
use crate::packages::{ use crate::packages::{
CorePackage, Package, PackageLibrary, PackageStore, PackagesCollection, StandardPackage, CorePackage, Package, PackageLibrary, PackageStore, PackagesCollection, StandardPackage,
@ -293,18 +293,9 @@ pub struct Engine {
pub(crate) type_names: HashMap<String, String>, pub(crate) type_names: HashMap<String, String>,
/// Closure for implementing the `print` command. /// Closure for implementing the `print` command.
#[cfg(feature = "sync")] pub(crate) print: Box<PrintCallback>,
pub(crate) print: Box<dyn Fn(&str) + Send + Sync + 'static>,
/// Closure for implementing the `print` command.
#[cfg(not(feature = "sync"))]
pub(crate) print: Box<dyn Fn(&str) + 'static>,
/// Closure for implementing the `debug` command. /// Closure for implementing the `debug` command.
#[cfg(feature = "sync")] pub(crate) debug: Box<PrintCallback>,
pub(crate) debug: Box<dyn Fn(&str) + Send + Sync + 'static>,
/// Closure for implementing the `debug` command.
#[cfg(not(feature = "sync"))]
pub(crate) debug: Box<dyn Fn(&str) + 'static>,
/// Optimize the AST after compilation. /// Optimize the AST after compilation.
pub(crate) optimization_level: OptimizationLevel, pub(crate) optimization_level: OptimizationLevel,

View File

@ -17,6 +17,58 @@ pub type IteratorFn = dyn Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Sen
#[cfg(not(feature = "sync"))] #[cfg(not(feature = "sync"))]
pub type IteratorFn = dyn Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>>; pub type IteratorFn = dyn Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>>;
#[cfg(feature = "sync")]
pub type PrintCallback = dyn Fn(&str) + Send + Sync + 'static;
#[cfg(not(feature = "sync"))]
pub type PrintCallback = dyn Fn(&str) + 'static;
// Define callback function types
#[cfg(feature = "sync")]
pub trait ObjectGetCallback<T, U>: Fn(&mut T) -> U + Send + Sync + 'static {}
#[cfg(feature = "sync")]
impl<F: Fn(&mut T) -> U + Send + Sync + 'static, T, U> ObjectGetCallback<T, U> for F {}
#[cfg(not(feature = "sync"))]
pub trait ObjectGetCallback<T, U>: Fn(&mut T) -> U + 'static {}
#[cfg(not(feature = "sync"))]
impl<F: Fn(&mut T) -> U + 'static, T, U> ObjectGetCallback<T, U> for F {}
#[cfg(feature = "sync")]
pub trait ObjectSetCallback<T, U>: Fn(&mut T, U) + Send + Sync + 'static {}
#[cfg(feature = "sync")]
impl<F: Fn(&mut T, U) + Send + Sync + 'static, T, U> ObjectSetCallback<T, U> for F {}
#[cfg(not(feature = "sync"))]
pub trait ObjectSetCallback<T, U>: Fn(&mut T, U) + 'static {}
#[cfg(not(feature = "sync"))]
impl<F: Fn(&mut T, U) + 'static, T, U> ObjectSetCallback<T, U> for F {}
#[cfg(feature = "sync")]
pub trait ObjectIndexerCallback<T, X, U>: Fn(&mut T, X) -> U + Send + Sync + 'static {}
#[cfg(feature = "sync")]
impl<F: Fn(&mut T, X) -> U + Send + Sync + 'static, T, X, U> ObjectIndexerCallback<T, X, U> for F {}
#[cfg(not(feature = "sync"))]
pub trait ObjectIndexerCallback<T, X, U>: Fn(&mut T, X) -> U + 'static {}
#[cfg(not(feature = "sync"))]
impl<F: Fn(&mut T, X) -> U + 'static, T, X, U> ObjectIndexerCallback<T, X, U> for F {}
#[cfg(feature = "sync")]
pub trait IteratorCallback:
Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Send + Sync + 'static
{
}
#[cfg(feature = "sync")]
impl<F: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Send + Sync + 'static> IteratorCallback
for F
{
}
#[cfg(not(feature = "sync"))]
pub trait IteratorCallback: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + 'static {}
#[cfg(not(feature = "sync"))]
impl<F: Fn(Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + 'static> IteratorCallback for F {}
/// A type representing the type of ABI of a native Rust function. /// A type representing the type of ABI of a native Rust function.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum NativeFunctionABI { pub enum NativeFunctionABI {
@ -28,6 +80,7 @@ pub enum NativeFunctionABI {
} }
/// A trait implemented by all native Rust functions that are callable by Rhai. /// A trait implemented by all native Rust functions that are callable by Rhai.
#[cfg(not(feature = "sync"))]
pub trait NativeCallable { pub trait NativeCallable {
/// Get the ABI type of a native Rust function. /// Get the ABI type of a native Rust function.
fn abi(&self) -> NativeFunctionABI; fn abi(&self) -> NativeFunctionABI;
@ -35,6 +88,15 @@ pub trait NativeCallable {
fn call(&self, args: &mut FnCallArgs, pos: Position) -> Result<Dynamic, Box<EvalAltResult>>; fn call(&self, args: &mut FnCallArgs, pos: Position) -> Result<Dynamic, Box<EvalAltResult>>;
} }
/// A trait implemented by all native Rust functions that are callable by Rhai.
#[cfg(feature = "sync")]
pub trait NativeCallable: Send + Sync {
/// Get the ABI type of a native Rust function.
fn abi(&self) -> NativeFunctionABI;
/// Call a native Rust function.
fn call(&self, args: &mut FnCallArgs, pos: Position) -> Result<Dynamic, Box<EvalAltResult>>;
}
/// A type encapsulating a native Rust function callable by Rhai. /// A type encapsulating a native Rust function callable by Rhai.
pub struct NativeFunction(Box<FnAny>, NativeFunctionABI); pub struct NativeFunction(Box<FnAny>, NativeFunctionABI);

View File

@ -119,14 +119,14 @@ pub struct Mut<T>(T);
/// Dereference into &mut. /// Dereference into &mut.
#[inline(always)] #[inline(always)]
pub fn by_ref<T: Clone + 'static>(data: &mut Dynamic) -> &mut T { pub fn by_ref<T: Variant + Clone>(data: &mut Dynamic) -> &mut T {
// Directly cast the &mut Dynamic into &mut T to access the underlying data. // Directly cast the &mut Dynamic into &mut T to access the underlying data.
data.downcast_mut::<T>().unwrap() data.downcast_mut::<T>().unwrap()
} }
/// Dereference into value. /// Dereference into value.
#[inline(always)] #[inline(always)]
pub fn by_value<T: Clone + 'static>(data: &mut Dynamic) -> T { pub fn by_value<T: Variant + Clone>(data: &mut Dynamic) -> T {
// We consume the argument and then replace it with () - the argument is not supposed to be used again. // We consume the argument and then replace it with () - the argument is not supposed to be used again.
// This way, we avoid having to clone the argument again, because it is already a clone when passed here. // This way, we avoid having to clone the argument again, because it is already a clone when passed here.
mem::take(data).cast::<T>() mem::take(data).cast::<T>()

View File

@ -31,6 +31,7 @@ use crate::stdlib::{
}; };
/// A trait that encapsulates a module resolution service. /// A trait that encapsulates a module resolution service.
#[cfg(not(feature = "sync"))]
pub trait ModuleResolver { pub trait ModuleResolver {
/// Resolve a module based on a path string. /// Resolve a module based on a path string.
fn resolve( fn resolve(
@ -42,6 +43,19 @@ pub trait ModuleResolver {
) -> Result<Module, Box<EvalAltResult>>; ) -> Result<Module, Box<EvalAltResult>>;
} }
/// A trait that encapsulates a module resolution service.
#[cfg(feature = "sync")]
pub trait ModuleResolver: Send + Sync {
/// Resolve a module based on a path string.
fn resolve(
&self,
engine: &Engine,
scope: Scope,
path: &str,
pos: Position,
) -> Result<Module, Box<EvalAltResult>>;
}
/// Default function access mode. /// Default function access mode.
const DEF_ACCESS: FnAccess = FnAccess::Public; const DEF_ACCESS: FnAccess = FnAccess::Public;

View File

@ -83,6 +83,7 @@ fn test_module_resolver() -> Result<(), Box<EvalAltResult>> {
} }
#[test] #[test]
#[cfg(not(feature = "no_function"))]
fn test_module_from_ast() -> Result<(), Box<EvalAltResult>> { fn test_module_from_ast() -> Result<(), Box<EvalAltResult>> {
let mut engine = Engine::new(); let mut engine = Engine::new();
@ -100,7 +101,7 @@ fn test_module_from_ast() -> Result<(), Box<EvalAltResult>> {
x + 1 x + 1
} }
fn add_len(x, y) { fn add_len(x, y) {
x + y.len() x + len(y)
} }
private fn hidden() { private fn hidden() {
throw "you shouldn't see me!"; throw "you shouldn't see me!";