Allow evaluating AST in Engine::call_fn_dynamic.
This commit is contained in:
parent
6aa0be546f
commit
d935401b03
@ -16,6 +16,7 @@ Breaking changes
|
|||||||
* Visibility (i.e. `pub` or not) for generated _plugin_ modules now follow the visibility of the underlying module.
|
* Visibility (i.e. `pub` or not) for generated _plugin_ modules now follow the visibility of the underlying module.
|
||||||
* Comparison operators between the sames types or different _numeric_ types now throw errors when they're not defined instead of returning the default. Only comparing between _different_ types will return the default.
|
* Comparison operators between the sames types or different _numeric_ types now throw errors when they're not defined instead of returning the default. Only comparing between _different_ types will return the default.
|
||||||
* Default stack-overflow and top-level expression nesting limits for release builds are lowered to 64 from 128.
|
* Default stack-overflow and top-level expression nesting limits for release builds are lowered to 64 from 128.
|
||||||
|
* `Engine::call_fn_dynamic` takes an additional parameter to optionally evaluate the given `AST` before calling the function.
|
||||||
|
|
||||||
New features
|
New features
|
||||||
------------
|
------------
|
||||||
@ -35,6 +36,7 @@ Enhancements
|
|||||||
* Arrays now have the `split` method.
|
* Arrays now have the `split` method.
|
||||||
* Comparisons between `FLOAT`/[`Decimal`](https://crates.io/crates/rust_decimal) and `INT` are now built in.
|
* Comparisons between `FLOAT`/[`Decimal`](https://crates.io/crates/rust_decimal) and `INT` are now built in.
|
||||||
* Comparisons between string and `char` are now built in.
|
* Comparisons between string and `char` are now built in.
|
||||||
|
* `Engine::call_fn_dynamic` can now optionally evaluate the given `AST` before calling the function.
|
||||||
|
|
||||||
|
|
||||||
Version 0.19.12
|
Version 0.19.12
|
||||||
|
@ -1613,6 +1613,13 @@ impl Engine {
|
|||||||
/// Call a script function defined in an [`AST`] with multiple arguments.
|
/// Call a script function defined in an [`AST`] with multiple arguments.
|
||||||
/// Arguments are passed as a tuple.
|
/// Arguments are passed as a tuple.
|
||||||
///
|
///
|
||||||
|
/// ## Warning
|
||||||
|
///
|
||||||
|
/// The [`AST`] is _not_ evaluated before calling the function. The function is called as-is.
|
||||||
|
///
|
||||||
|
/// If the [`AST`] needs to be evaluated before calling the function (usually to load external modules),
|
||||||
|
/// use [`call_fn_dynamic`][Engine::call_fn_dynamic].
|
||||||
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
@ -1633,11 +1640,11 @@ impl Engine {
|
|||||||
/// scope.push("foo", 42_i64);
|
/// scope.push("foo", 42_i64);
|
||||||
///
|
///
|
||||||
/// // Call the script-defined function
|
/// // Call the script-defined function
|
||||||
/// let result: i64 = engine.call_fn(&mut scope, &ast, "add", ( String::from("abc"), 123_i64 ) )?;
|
/// let result: i64 = engine.call_fn(&mut scope, &ast, "add", ( "abc", 123_i64 ) )?;
|
||||||
/// assert_eq!(result, 168);
|
/// assert_eq!(result, 168);
|
||||||
///
|
///
|
||||||
/// let result: i64 = engine.call_fn(&mut scope, &ast, "add1", ( String::from("abc"), ) )?;
|
/// let result: i64 = engine.call_fn(&mut scope, &ast, "add1", ( "abc", ) )?;
|
||||||
/// // ^^^^^^^^^^^^^^^^^^^^^^^^ tuple of one
|
/// // ^^^^^^^^^^ tuple of one
|
||||||
/// assert_eq!(result, 46);
|
/// assert_eq!(result, 46);
|
||||||
///
|
///
|
||||||
/// let result: i64 = engine.call_fn(&mut scope, &ast, "bar", () )?;
|
/// let result: i64 = engine.call_fn(&mut scope, &ast, "bar", () )?;
|
||||||
@ -1659,8 +1666,7 @@ impl Engine {
|
|||||||
args.parse(&mut arg_values);
|
args.parse(&mut arg_values);
|
||||||
let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect();
|
let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect();
|
||||||
|
|
||||||
let result =
|
let result = self.call_fn_dynamic_raw(scope, ast, false, name, &mut None, args.as_mut())?;
|
||||||
self.call_fn_dynamic_raw(scope, &[ast.lib()], name, &mut None, args.as_mut())?;
|
|
||||||
|
|
||||||
let typ = self.map_type_name(result.type_name());
|
let typ = self.map_type_name(result.type_name());
|
||||||
|
|
||||||
@ -1676,6 +1682,9 @@ impl Engine {
|
|||||||
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments
|
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments
|
||||||
/// and optionally a value for binding to the `this` pointer.
|
/// and optionally a value for binding to the `this` pointer.
|
||||||
///
|
///
|
||||||
|
/// There is also an option to evaluate the [`AST`] (e.g. to configuration the environment)
|
||||||
|
/// before calling the function.
|
||||||
|
///
|
||||||
/// # WARNING
|
/// # WARNING
|
||||||
///
|
///
|
||||||
/// All the arguments are _consumed_, meaning that they're replaced by `()`.
|
/// All the arguments are _consumed_, meaning that they're replaced by `()`.
|
||||||
@ -1704,19 +1713,19 @@ impl Engine {
|
|||||||
/// scope.push("foo", 42_i64);
|
/// scope.push("foo", 42_i64);
|
||||||
///
|
///
|
||||||
/// // Call the script-defined function
|
/// // Call the script-defined function
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "add", None, [ String::from("abc").into(), 123_i64.into() ])?;
|
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "add", None, [ "abc".into(), 123_i64.into() ])?;
|
||||||
/// // ^^^^ no 'this' pointer
|
/// // ^^^^ no 'this' pointer
|
||||||
/// assert_eq!(result.cast::<i64>(), 168);
|
/// assert_eq!(result.cast::<i64>(), 168);
|
||||||
///
|
///
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "add1", None, [ String::from("abc").into() ])?;
|
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "add1", None, [ "abc".into() ])?;
|
||||||
/// assert_eq!(result.cast::<i64>(), 46);
|
/// assert_eq!(result.cast::<i64>(), 46);
|
||||||
///
|
///
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "bar", None, [])?;
|
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "bar", None, [])?;
|
||||||
/// assert_eq!(result.cast::<i64>(), 21);
|
/// assert_eq!(result.cast::<i64>(), 21);
|
||||||
///
|
///
|
||||||
/// let mut value: Dynamic = 1_i64.into();
|
/// let mut value: Dynamic = 1_i64.into();
|
||||||
/// let result = engine.call_fn_dynamic(&mut scope, &ast, "action", Some(&mut value), [ 41_i64.into() ])?;
|
/// let result = engine.call_fn_dynamic(&mut scope, &ast, false, "action", Some(&mut value), [ 41_i64.into() ])?;
|
||||||
/// // ^^^^^^^^^^^^^^^^ binding the 'this' pointer
|
/// // ^^^^^^^^^^^^^^^^ binding the 'this' pointer
|
||||||
/// assert_eq!(value.as_int().unwrap(), 42);
|
/// assert_eq!(value.as_int().unwrap(), 42);
|
||||||
/// # }
|
/// # }
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
@ -1727,14 +1736,15 @@ impl Engine {
|
|||||||
pub fn call_fn_dynamic(
|
pub fn call_fn_dynamic(
|
||||||
&self,
|
&self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
lib: impl AsRef<crate::Module>,
|
ast: &AST,
|
||||||
|
eval_ast: bool,
|
||||||
name: &str,
|
name: &str,
|
||||||
mut this_ptr: Option<&mut Dynamic>,
|
mut this_ptr: Option<&mut Dynamic>,
|
||||||
mut arg_values: impl AsMut<[Dynamic]>,
|
mut arg_values: impl AsMut<[Dynamic]>,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect();
|
let mut args: crate::StaticVec<_> = arg_values.as_mut().iter_mut().collect();
|
||||||
|
|
||||||
self.call_fn_dynamic_raw(scope, &[lib.as_ref()], name, &mut this_ptr, args.as_mut())
|
self.call_fn_dynamic_raw(scope, ast, eval_ast, name, &mut this_ptr, args.as_mut())
|
||||||
}
|
}
|
||||||
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments.
|
/// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments.
|
||||||
///
|
///
|
||||||
@ -1749,18 +1759,24 @@ impl Engine {
|
|||||||
pub(crate) fn call_fn_dynamic_raw(
|
pub(crate) fn call_fn_dynamic_raw(
|
||||||
&self,
|
&self,
|
||||||
scope: &mut Scope,
|
scope: &mut Scope,
|
||||||
lib: &[&crate::Module],
|
ast: &AST,
|
||||||
|
eval_ast: bool,
|
||||||
name: &str,
|
name: &str,
|
||||||
this_ptr: &mut Option<&mut Dynamic>,
|
this_ptr: &mut Option<&mut Dynamic>,
|
||||||
args: &mut FnCallArgs,
|
args: &mut FnCallArgs,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
let fn_def = lib
|
let state = &mut Default::default();
|
||||||
.iter()
|
let mods = &mut (&self.global_sub_modules).into();
|
||||||
.find_map(|&m| m.get_script_fn(name, args.len(), true))
|
let lib = &[ast.lib()];
|
||||||
.ok_or_else(|| EvalAltResult::ErrorFunctionNotFound(name.into(), Position::NONE))?;
|
|
||||||
|
|
||||||
let mut state = Default::default();
|
if eval_ast {
|
||||||
let mut mods = (&self.global_sub_modules).into();
|
self.eval_global_statements(scope, mods, state, ast.statements(), lib, 0)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let fn_def = ast
|
||||||
|
.lib()
|
||||||
|
.get_script_fn(name, args.len(), true)
|
||||||
|
.ok_or_else(|| EvalAltResult::ErrorFunctionNotFound(name.into(), Position::NONE))?;
|
||||||
|
|
||||||
// Check for data race.
|
// Check for data race.
|
||||||
if cfg!(not(feature = "no_closure")) {
|
if cfg!(not(feature = "no_closure")) {
|
||||||
@ -1769,8 +1785,8 @@ impl Engine {
|
|||||||
|
|
||||||
self.call_script_fn(
|
self.call_script_fn(
|
||||||
scope,
|
scope,
|
||||||
&mut mods,
|
mods,
|
||||||
&mut state,
|
state,
|
||||||
lib,
|
lib,
|
||||||
this_ptr,
|
this_ptr,
|
||||||
fn_def,
|
fn_def,
|
||||||
@ -1933,7 +1949,7 @@ impl Engine {
|
|||||||
/// # use std::sync::Arc;
|
/// # use std::sync::Arc;
|
||||||
/// use rhai::Engine;
|
/// use rhai::Engine;
|
||||||
///
|
///
|
||||||
/// let result = Arc::new(RwLock::new(String::from("")));
|
/// let result = Arc::new(RwLock::new(String::new()));
|
||||||
///
|
///
|
||||||
/// let mut engine = Engine::new();
|
/// let mut engine = Engine::new();
|
||||||
///
|
///
|
||||||
@ -1962,7 +1978,7 @@ impl Engine {
|
|||||||
/// # use std::sync::Arc;
|
/// # use std::sync::Arc;
|
||||||
/// use rhai::Engine;
|
/// use rhai::Engine;
|
||||||
///
|
///
|
||||||
/// let result = Arc::new(RwLock::new(String::from("")));
|
/// let result = Arc::new(RwLock::new(String::new()));
|
||||||
///
|
///
|
||||||
/// let mut engine = Engine::new();
|
/// let mut engine = Engine::new();
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user