Make Engine Send+Sync.
This commit is contained in:
parent
9d7091ad9d
commit
a79f2a209c
@ -68,7 +68,7 @@ Optional features
|
|||||||
| `only_i32` | Set the system integer type to `i32` and disable all other integer types. `INT` is set to `i32`. |
|
| `only_i32` | Set the system integer type to `i32` and disable all other integer types. `INT` is set to `i32`. |
|
||||||
| `only_i64` | Set the system integer type to `i64` and disable all other integer types. `INT` is set to `i64`. |
|
| `only_i64` | Set the system integer type to `i64` and disable all other integer types. `INT` is set to `i64`. |
|
||||||
| `no_std` | Build for `no-std`. Notice that additional dependencies will be pulled in to replace `std` features. |
|
| `no_std` | Build for `no-std`. Notice that additional dependencies will be pulled in to replace `std` features. |
|
||||||
| `sync` | Restrict all values types to those that are `Send + Sync`. Under this feature, [`Scope`] and `AST` are both `Send + Sync`. |
|
| `sync` | Restrict all values types to those that are `Send + Sync`. Under this feature, `Engine`, [`Scope`] and `AST` are all `Send + Sync`. |
|
||||||
|
|
||||||
By default, Rhai includes all the standard functionalities in a small, tight package. Most features are here to opt-**out** of certain functionalities that are not needed.
|
By default, Rhai includes all the standard functionalities in a small, tight package. Most features are here to opt-**out** of certain functionalities that are not needed.
|
||||||
Excluding unneeded functionalities can result in smaller, faster builds as well as less bugs due to a more restricted language.
|
Excluding unneeded functionalities can result in smaller, faster builds as well as less bugs due to a more restricted language.
|
||||||
|
88
src/api.rs
88
src/api.rs
@ -22,6 +22,44 @@ use crate::stdlib::{
|
|||||||
#[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 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<'e> Engine<'e> {
|
impl<'e> Engine<'e> {
|
||||||
/// Register a custom function.
|
/// Register a custom function.
|
||||||
pub(crate) fn register_fn_raw(&mut self, fn_name: &str, args: Vec<TypeId>, f: Box<FnAny>) {
|
pub(crate) fn register_fn_raw(&mut self, fn_name: &str, args: Vec<TypeId>, f: Box<FnAny>) {
|
||||||
@ -126,10 +164,7 @@ impl<'e> Engine<'e> {
|
|||||||
|
|
||||||
/// Register an iterator adapter for a type with the `Engine`.
|
/// Register an iterator adapter for a type with the `Engine`.
|
||||||
/// This is an advanced feature.
|
/// This is an advanced feature.
|
||||||
pub fn register_iterator<T: Any, F>(&mut self, f: F)
|
pub fn register_iterator<T: Any, F: IteratorCallback>(&mut self, f: F) {
|
||||||
where
|
|
||||||
F: Fn(&Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + 'static,
|
|
||||||
{
|
|
||||||
self.type_iterators.insert(TypeId::of::<T>(), Box::new(f));
|
self.type_iterators.insert(TypeId::of::<T>(), Box::new(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,11 +205,12 @@ impl<'e> Engine<'e> {
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn register_get<T: Any + Clone, U: Any + Clone>(
|
pub fn register_get<T, U, F>(&mut self, name: &str, callback: F)
|
||||||
&mut self,
|
where
|
||||||
name: &str,
|
T: Any + Clone,
|
||||||
callback: impl Fn(&mut T) -> U + 'static,
|
U: Any + Clone,
|
||||||
) {
|
F: ObjectGetCallback<T, U>,
|
||||||
|
{
|
||||||
self.register_fn(&make_getter(name), callback);
|
self.register_fn(&make_getter(name), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,11 +251,12 @@ impl<'e> Engine<'e> {
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn register_set<T: Any + Clone, U: Any + Clone>(
|
pub fn register_set<T, U, F>(&mut self, name: &str, callback: F)
|
||||||
&mut self,
|
where
|
||||||
name: &str,
|
T: Any + Clone,
|
||||||
callback: impl Fn(&mut T, U) -> () + 'static,
|
U: Any + Clone,
|
||||||
) {
|
F: ObjectSetCallback<T, U>,
|
||||||
|
{
|
||||||
self.register_fn(&make_setter(name), callback);
|
self.register_fn(&make_setter(name), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,12 +299,13 @@ impl<'e> Engine<'e> {
|
|||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn register_get_set<T: Any + Clone, U: Any + Clone>(
|
pub fn register_get_set<T, U, G, S>(&mut self, name: &str, get_fn: G, set_fn: S)
|
||||||
&mut self,
|
where
|
||||||
name: &str,
|
T: Any + Clone,
|
||||||
get_fn: impl Fn(&mut T) -> U + 'static,
|
U: Any + Clone,
|
||||||
set_fn: impl Fn(&mut T, U) -> () + 'static,
|
G: ObjectGetCallback<T, U>,
|
||||||
) {
|
S: ObjectSetCallback<T, U>,
|
||||||
|
{
|
||||||
self.register_get(name, get_fn);
|
self.register_get(name, get_fn);
|
||||||
self.register_set(name, set_fn);
|
self.register_set(name, set_fn);
|
||||||
}
|
}
|
||||||
@ -925,6 +963,11 @@ impl<'e> Engine<'e> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
pub fn on_print(&mut self, callback: impl FnMut(&str) + Send + Sync + 'e) {
|
||||||
|
self.on_print = Box::new(callback);
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
pub fn on_print(&mut self, callback: impl FnMut(&str) + 'e) {
|
pub fn on_print(&mut self, callback: impl FnMut(&str) + 'e) {
|
||||||
self.on_print = Box::new(callback);
|
self.on_print = Box::new(callback);
|
||||||
}
|
}
|
||||||
@ -949,6 +992,11 @@ impl<'e> Engine<'e> {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
pub fn on_debug(&mut self, callback: impl FnMut(&str) + Send + Sync + 'e) {
|
||||||
|
self.on_debug = Box::new(callback);
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
pub fn on_debug(&mut self, callback: impl FnMut(&str) + 'e) {
|
pub fn on_debug(&mut self, callback: impl FnMut(&str) + 'e) {
|
||||||
self.on_debug = Box::new(callback);
|
self.on_debug = Box::new(callback);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! Helper module that allows registration of the _core library_ and
|
//! Helper module that allows registration of the _core library_ and
|
||||||
//! _standard library_ of utility functions.
|
//! _standard library_ of utility functions.
|
||||||
|
|
||||||
use crate::any::Any;
|
use crate::any::{Any, Dynamic};
|
||||||
use crate::engine::{Engine, FUNC_TO_STRING, KEYWORD_DEBUG, KEYWORD_PRINT};
|
use crate::engine::{Engine, FUNC_TO_STRING, KEYWORD_DEBUG, KEYWORD_PRINT};
|
||||||
use crate::fn_register::{RegisterDynamicFn, RegisterFn, RegisterResultFn};
|
use crate::fn_register::{RegisterDynamicFn, RegisterFn, RegisterResultFn};
|
||||||
use crate::parser::{Position, INT};
|
use crate::parser::{Position, INT};
|
||||||
@ -612,8 +612,9 @@ impl Engine<'_> {
|
|||||||
reg_fn1!(self, KEYWORD_DEBUG, to_debug, String, Array);
|
reg_fn1!(self, KEYWORD_DEBUG, to_debug, String, Array);
|
||||||
|
|
||||||
// Register array iterator
|
// Register array iterator
|
||||||
self.register_iterator::<Array, _>(|a| {
|
self.register_iterator::<Array, _>(|a: &Dynamic| {
|
||||||
Box::new(a.downcast_ref::<Array>().unwrap().clone().into_iter())
|
Box::new(a.downcast_ref::<Array>().unwrap().clone().into_iter())
|
||||||
|
as Box<dyn Iterator<Item = Dynamic>>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,13 +637,13 @@ impl Engine<'_> {
|
|||||||
where
|
where
|
||||||
Range<T>: Iterator<Item = T>,
|
Range<T>: Iterator<Item = T>,
|
||||||
{
|
{
|
||||||
engine.register_iterator::<Range<T>, _>(|a| {
|
engine.register_iterator::<Range<T>, _>(|a: &Dynamic| {
|
||||||
Box::new(
|
Box::new(
|
||||||
a.downcast_ref::<Range<T>>()
|
a.downcast_ref::<Range<T>>()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone()
|
.clone()
|
||||||
.map(|n| n.into_dynamic()),
|
.map(|n| n.into_dynamic()),
|
||||||
)
|
) as Box<dyn Iterator<Item = Dynamic>>
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,8 +32,14 @@ pub type Map = HashMap<String, Dynamic>;
|
|||||||
|
|
||||||
pub type FnCallArgs<'a> = [&'a mut Variant];
|
pub type FnCallArgs<'a> = [&'a mut Variant];
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
pub type FnAny = dyn Fn(&mut FnCallArgs, Position) -> Result<Dynamic, EvalAltResult> + Send + Sync;
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
pub type FnAny = dyn Fn(&mut FnCallArgs, Position) -> Result<Dynamic, EvalAltResult>;
|
pub type FnAny = dyn Fn(&mut FnCallArgs, Position) -> Result<Dynamic, EvalAltResult>;
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
type IteratorFn = dyn Fn(&Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + Send + Sync;
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
type IteratorFn = dyn Fn(&Dynamic) -> Box<dyn Iterator<Item = Dynamic>>;
|
type IteratorFn = dyn Fn(&Dynamic) -> Box<dyn Iterator<Item = Dynamic>>;
|
||||||
|
|
||||||
pub const MAX_CALL_STACK_DEPTH: usize = 64;
|
pub const MAX_CALL_STACK_DEPTH: usize = 64;
|
||||||
@ -193,8 +199,15 @@ pub struct Engine<'e> {
|
|||||||
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) on_print: Box<dyn FnMut(&str) + Send + Sync + 'e>,
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
pub(crate) on_print: Box<dyn FnMut(&str) + 'e>,
|
pub(crate) on_print: Box<dyn FnMut(&str) + 'e>,
|
||||||
|
|
||||||
/// Closure for implementing the `debug` command.
|
/// Closure for implementing the `debug` command.
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
pub(crate) on_debug: Box<dyn FnMut(&str) + Send + Sync + 'e>,
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
pub(crate) on_debug: Box<dyn FnMut(&str) + 'e>,
|
pub(crate) on_debug: Box<dyn FnMut(&str) + 'e>,
|
||||||
|
|
||||||
/// Optimize the AST after compilation.
|
/// Optimize the AST after compilation.
|
||||||
@ -280,6 +293,11 @@ fn extract_prop_from_setter(fn_name: &str) -> Option<&str> {
|
|||||||
impl Engine<'_> {
|
impl Engine<'_> {
|
||||||
/// Create a new `Engine`
|
/// Create a new `Engine`
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
// fn abc<F: Fn() + Send + Sync>(f: F) {
|
||||||
|
// f();
|
||||||
|
// }
|
||||||
|
// abc(|| ());
|
||||||
|
|
||||||
Default::default()
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,13 @@ macro_rules! def_register {
|
|||||||
// ^ dereferencing function
|
// ^ dereferencing function
|
||||||
impl<
|
impl<
|
||||||
$($par: Any + Clone,)*
|
$($par: Any + Clone,)*
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
FN: Fn($($param),*) -> RET + Send + Sync + 'static,
|
||||||
|
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
FN: Fn($($param),*) -> RET + 'static,
|
FN: Fn($($param),*) -> RET + 'static,
|
||||||
|
|
||||||
RET: Any
|
RET: Any
|
||||||
> RegisterFn<FN, ($($mark,)*), RET> for Engine<'_>
|
> RegisterFn<FN, ($($mark,)*), RET> for Engine<'_>
|
||||||
{
|
{
|
||||||
@ -171,6 +177,11 @@ macro_rules! def_register {
|
|||||||
|
|
||||||
impl<
|
impl<
|
||||||
$($par: Any + Clone,)*
|
$($par: Any + Clone,)*
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
FN: Fn($($param),*) -> Dynamic + Send + Sync + 'static,
|
||||||
|
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
FN: Fn($($param),*) -> Dynamic + 'static,
|
FN: Fn($($param),*) -> Dynamic + 'static,
|
||||||
> RegisterDynamicFn<FN, ($($mark,)*)> for Engine<'_>
|
> RegisterDynamicFn<FN, ($($mark,)*)> for Engine<'_>
|
||||||
{
|
{
|
||||||
@ -202,7 +213,12 @@ macro_rules! def_register {
|
|||||||
|
|
||||||
impl<
|
impl<
|
||||||
$($par: Any + Clone,)*
|
$($par: Any + Clone,)*
|
||||||
|
|
||||||
|
#[cfg(feature = "sync")]
|
||||||
|
FN: Fn($($param),*) -> Result<RET, EvalAltResult> + Send + Sync + 'static,
|
||||||
|
#[cfg(not(feature = "sync"))]
|
||||||
FN: Fn($($param),*) -> Result<RET, EvalAltResult> + 'static,
|
FN: Fn($($param),*) -> Result<RET, EvalAltResult> + 'static,
|
||||||
|
|
||||||
RET: Any
|
RET: Any
|
||||||
> RegisterResultFn<FN, ($($mark,)*), RET> for Engine<'_>
|
> RegisterResultFn<FN, ($($mark,)*), RET> for Engine<'_>
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user