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;
/// 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.
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::error::ParseError;
use crate::fn_call::FuncArgs;
use crate::fn_native::{
IteratorCallback, ObjectGetCallback, ObjectIndexerCallback, ObjectSetCallback,
};
use crate::fn_register::RegisterFn;
use crate::optimize::{optimize_into_ast, OptimizationLevel};
use crate::parser::{parse, parse_global_expr, AST};
@ -22,56 +25,10 @@ use crate::stdlib::{
mem,
string::{String, ToString},
};
#[cfg(not(feature = "no_std"))]
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
impl Engine {
/// Register a custom type for use with the `Engine`.

View File

@ -3,7 +3,7 @@
use crate::any::{Dynamic, Union};
use crate::calc_fn_hash;
use crate::error::ParseErrorType;
use crate::fn_native::{FnCallArgs, NativeFunctionABI};
use crate::fn_native::{FnCallArgs, NativeFunctionABI, PrintCallback};
use crate::optimize::OptimizationLevel;
use crate::packages::{
CorePackage, Package, PackageLibrary, PackageStore, PackagesCollection, StandardPackage,
@ -293,18 +293,9 @@ pub struct Engine {
pub(crate) type_names: HashMap<String, String>,
/// Closure for implementing the `print` command.
#[cfg(feature = "sync")]
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>,
pub(crate) print: Box<PrintCallback>,
/// Closure for implementing the `debug` command.
#[cfg(feature = "sync")]
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>,
pub(crate) debug: Box<PrintCallback>,
/// Optimize the AST after compilation.
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"))]
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.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub enum NativeFunctionABI {
@ -28,6 +80,7 @@ pub enum NativeFunctionABI {
}
/// A trait implemented by all native Rust functions that are callable by Rhai.
#[cfg(not(feature = "sync"))]
pub trait NativeCallable {
/// Get the ABI type of a native Rust function.
fn abi(&self) -> NativeFunctionABI;
@ -35,6 +88,15 @@ pub trait NativeCallable {
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.
pub struct NativeFunction(Box<FnAny>, NativeFunctionABI);

View File

@ -119,14 +119,14 @@ pub struct Mut<T>(T);
/// Dereference into &mut.
#[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.
data.downcast_mut::<T>().unwrap()
}
/// Dereference into value.
#[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.
// This way, we avoid having to clone the argument again, because it is already a clone when passed here.
mem::take(data).cast::<T>()

View File

@ -31,6 +31,7 @@ use crate::stdlib::{
};
/// A trait that encapsulates a module resolution service.
#[cfg(not(feature = "sync"))]
pub trait ModuleResolver {
/// Resolve a module based on a path string.
fn resolve(
@ -42,6 +43,19 @@ pub trait ModuleResolver {
) -> 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.
const DEF_ACCESS: FnAccess = FnAccess::Public;

View File

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