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_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. |
|
||||
| `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.
|
||||
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"))]
|
||||
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> {
|
||||
/// Register a custom function.
|
||||
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`.
|
||||
/// This is an advanced feature.
|
||||
pub fn register_iterator<T: Any, F>(&mut self, f: F)
|
||||
where
|
||||
F: Fn(&Dynamic) -> Box<dyn Iterator<Item = Dynamic>> + 'static,
|
||||
{
|
||||
pub fn register_iterator<T: Any, F: IteratorCallback>(&mut self, f: F) {
|
||||
self.type_iterators.insert(TypeId::of::<T>(), Box::new(f));
|
||||
}
|
||||
|
||||
@ -170,11 +205,12 @@ impl<'e> Engine<'e> {
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
pub fn register_get<T: Any + Clone, U: Any + Clone>(
|
||||
&mut self,
|
||||
name: &str,
|
||||
callback: impl Fn(&mut T) -> U + 'static,
|
||||
) {
|
||||
pub fn register_get<T, U, F>(&mut self, name: &str, callback: F)
|
||||
where
|
||||
T: Any + Clone,
|
||||
U: Any + Clone,
|
||||
F: ObjectGetCallback<T, U>,
|
||||
{
|
||||
self.register_fn(&make_getter(name), callback);
|
||||
}
|
||||
|
||||
@ -215,11 +251,12 @@ impl<'e> Engine<'e> {
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
pub fn register_set<T: Any + Clone, U: Any + Clone>(
|
||||
&mut self,
|
||||
name: &str,
|
||||
callback: impl Fn(&mut T, U) -> () + 'static,
|
||||
) {
|
||||
pub fn register_set<T, U, F>(&mut self, name: &str, callback: F)
|
||||
where
|
||||
T: Any + Clone,
|
||||
U: Any + Clone,
|
||||
F: ObjectSetCallback<T, U>,
|
||||
{
|
||||
self.register_fn(&make_setter(name), callback);
|
||||
}
|
||||
|
||||
@ -262,12 +299,13 @@ impl<'e> Engine<'e> {
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
pub fn register_get_set<T: Any + Clone, U: Any + Clone>(
|
||||
&mut self,
|
||||
name: &str,
|
||||
get_fn: impl Fn(&mut T) -> U + 'static,
|
||||
set_fn: impl Fn(&mut T, U) -> () + 'static,
|
||||
) {
|
||||
pub fn register_get_set<T, U, G, S>(&mut self, name: &str, get_fn: G, set_fn: S)
|
||||
where
|
||||
T: Any + Clone,
|
||||
U: Any + Clone,
|
||||
G: ObjectGetCallback<T, U>,
|
||||
S: ObjectSetCallback<T, U>,
|
||||
{
|
||||
self.register_get(name, get_fn);
|
||||
self.register_set(name, set_fn);
|
||||
}
|
||||
@ -925,6 +963,11 @@ impl<'e> Engine<'e> {
|
||||
/// # 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) {
|
||||
self.on_print = Box::new(callback);
|
||||
}
|
||||
@ -949,6 +992,11 @@ impl<'e> Engine<'e> {
|
||||
/// # 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) {
|
||||
self.on_debug = Box::new(callback);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Helper module that allows registration of the _core library_ and
|
||||
//! _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::fn_register::{RegisterDynamicFn, RegisterFn, RegisterResultFn};
|
||||
use crate::parser::{Position, INT};
|
||||
@ -612,8 +612,9 @@ impl Engine<'_> {
|
||||
reg_fn1!(self, KEYWORD_DEBUG, to_debug, String, Array);
|
||||
|
||||
// Register array iterator
|
||||
self.register_iterator::<Array, _>(|a| {
|
||||
self.register_iterator::<Array, _>(|a: &Dynamic| {
|
||||
Box::new(a.downcast_ref::<Array>().unwrap().clone().into_iter())
|
||||
as Box<dyn Iterator<Item = Dynamic>>
|
||||
});
|
||||
}
|
||||
|
||||
@ -636,13 +637,13 @@ impl Engine<'_> {
|
||||
where
|
||||
Range<T>: Iterator<Item = T>,
|
||||
{
|
||||
engine.register_iterator::<Range<T>, _>(|a| {
|
||||
engine.register_iterator::<Range<T>, _>(|a: &Dynamic| {
|
||||
Box::new(
|
||||
a.downcast_ref::<Range<T>>()
|
||||
.unwrap()
|
||||
.clone()
|
||||
.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];
|
||||
|
||||
#[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>;
|
||||
|
||||
#[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>>;
|
||||
|
||||
pub const MAX_CALL_STACK_DEPTH: usize = 64;
|
||||
@ -193,8 +199,15 @@ pub struct Engine<'e> {
|
||||
pub(crate) type_names: HashMap<String, String>,
|
||||
|
||||
/// 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>,
|
||||
|
||||
/// 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>,
|
||||
|
||||
/// Optimize the AST after compilation.
|
||||
@ -280,6 +293,11 @@ fn extract_prop_from_setter(fn_name: &str) -> Option<&str> {
|
||||
impl Engine<'_> {
|
||||
/// Create a new `Engine`
|
||||
pub fn new() -> Self {
|
||||
// fn abc<F: Fn() + Send + Sync>(f: F) {
|
||||
// f();
|
||||
// }
|
||||
// abc(|| ());
|
||||
|
||||
Default::default()
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,13 @@ macro_rules! def_register {
|
||||
// ^ dereferencing function
|
||||
impl<
|
||||
$($par: Any + Clone,)*
|
||||
|
||||
#[cfg(feature = "sync")]
|
||||
FN: Fn($($param),*) -> RET + Send + Sync + 'static,
|
||||
|
||||
#[cfg(not(feature = "sync"))]
|
||||
FN: Fn($($param),*) -> RET + 'static,
|
||||
|
||||
RET: Any
|
||||
> RegisterFn<FN, ($($mark,)*), RET> for Engine<'_>
|
||||
{
|
||||
@ -171,6 +177,11 @@ macro_rules! def_register {
|
||||
|
||||
impl<
|
||||
$($par: Any + Clone,)*
|
||||
|
||||
#[cfg(feature = "sync")]
|
||||
FN: Fn($($param),*) -> Dynamic + Send + Sync + 'static,
|
||||
|
||||
#[cfg(not(feature = "sync"))]
|
||||
FN: Fn($($param),*) -> Dynamic + 'static,
|
||||
> RegisterDynamicFn<FN, ($($mark,)*)> for Engine<'_>
|
||||
{
|
||||
@ -202,7 +213,12 @@ macro_rules! def_register {
|
||||
|
||||
impl<
|
||||
$($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,
|
||||
|
||||
RET: Any
|
||||
> RegisterResultFn<FN, ($($mark,)*), RET> for Engine<'_>
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user