Add FnPtr::call_within_context.
This commit is contained in:
parent
0ab86ac623
commit
ba0a6c667e
@ -13,7 +13,7 @@ Enhancements
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
* Added `into_array` and `into_typed_array` for `Dynamic`.
|
* Added `into_array` and `into_typed_array` for `Dynamic`.
|
||||||
* Added `FnPtr::call` to simplify calling a function pointer.
|
* Added `FnPtr::call` and `FnPtr::call_within_context` to simplify calling a function pointer.
|
||||||
|
|
||||||
Deprecated and Gated API's
|
Deprecated and Gated API's
|
||||||
--------------------------
|
--------------------------
|
||||||
@ -21,6 +21,7 @@ Deprecated and Gated API's
|
|||||||
* `NativeCallContext::new` is deprecated because it is simpler to call a function pointer via `FnPtr::call`.
|
* `NativeCallContext::new` is deprecated because it is simpler to call a function pointer via `FnPtr::call`.
|
||||||
* `AST::merge_filtered` and `AST::combine_filtered` are no longer exported under `no_function`.
|
* `AST::merge_filtered` and `AST::combine_filtered` are no longer exported under `no_function`.
|
||||||
* `AST::new` and `AST::new_with_source` are moved under `internals`.
|
* `AST::new` and `AST::new_with_source` are moved under `internals`.
|
||||||
|
* `FnPtr::call_dynamic` is deprecated in favor of `FnPtr::call_raw`.
|
||||||
|
|
||||||
|
|
||||||
Version 1.2.1
|
Version 1.2.1
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
//! Module containing all deprecated API that will be removed in the next major version.
|
//! Module containing all deprecated API that will be removed in the next major version.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
Dynamic, Engine, EvalAltResult, ImmutableString, NativeCallContext, RhaiResult, Scope, AST,
|
Dynamic, Engine, EvalAltResult, FnPtr, ImmutableString, NativeCallContext, RhaiResult, Scope,
|
||||||
|
AST,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
@ -256,3 +257,39 @@ impl<T> From<EvalAltResult> for Result<T, Box<EvalAltResult>> {
|
|||||||
Err(err.into())
|
Err(err.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FnPtr {
|
||||||
|
/// Call the function pointer with curried arguments (if any).
|
||||||
|
/// The function may be script-defined (not available under `no_function`) or native Rust.
|
||||||
|
///
|
||||||
|
/// This method is intended for calling a function pointer that is passed into a native Rust
|
||||||
|
/// function as an argument. Therefore, the [`AST`] is _NOT_ evaluated before calling the
|
||||||
|
/// function.
|
||||||
|
///
|
||||||
|
/// # Deprecated
|
||||||
|
///
|
||||||
|
/// This method is deprecated. Use [`call_within_context`][FnPtr::call_within_context] or
|
||||||
|
/// [`call_raw`][FnPtr::call_raw] instead.
|
||||||
|
///
|
||||||
|
/// This method will be removed in the next major version.
|
||||||
|
///
|
||||||
|
/// # WARNING
|
||||||
|
///
|
||||||
|
/// All the arguments are _consumed_, meaning that they're replaced by `()`.
|
||||||
|
/// This is to avoid unnecessarily cloning the arguments.
|
||||||
|
/// Do not use the arguments after this call. If they are needed afterwards,
|
||||||
|
/// clone them _before_ calling this function.
|
||||||
|
#[deprecated(
|
||||||
|
since = "1.3.0",
|
||||||
|
note = "use `call_within_context` or `call_raw` instead"
|
||||||
|
)]
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn call_dynamic(
|
||||||
|
&self,
|
||||||
|
context: &NativeCallContext,
|
||||||
|
this_ptr: Option<&mut Dynamic>,
|
||||||
|
arg_values: impl AsMut<[Dynamic]>,
|
||||||
|
) -> RhaiResult {
|
||||||
|
self.call_raw(context, this_ptr, arg_values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -154,6 +154,8 @@ impl Engine {
|
|||||||
///
|
///
|
||||||
/// This function is very low level. It takes a list of [`TypeId`][std::any::TypeId]'s indicating the actual types of the parameters.
|
/// This function is very low level. It takes a list of [`TypeId`][std::any::TypeId]'s indicating the actual types of the parameters.
|
||||||
///
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
/// Arguments are simply passed in as a mutable array of [`&mut Dynamic`][crate::Dynamic],
|
/// Arguments are simply passed in as a mutable array of [`&mut Dynamic`][crate::Dynamic],
|
||||||
/// The arguments are guaranteed to be of the correct types matching the [`TypeId`][std::any::TypeId]'s.
|
/// The arguments are guaranteed to be of the correct types matching the [`TypeId`][std::any::TypeId]'s.
|
||||||
///
|
///
|
||||||
|
@ -261,12 +261,12 @@ mod array_functions {
|
|||||||
for (i, item) in array.iter().enumerate() {
|
for (i, item) in array.iter().enumerate() {
|
||||||
ar.push(
|
ar.push(
|
||||||
mapper
|
mapper
|
||||||
.call_dynamic(&ctx, None, [item.clone()])
|
.call_raw(&ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(mapper.fn_name()) =>
|
if fn_sig.starts_with(mapper.fn_name()) =>
|
||||||
{
|
{
|
||||||
mapper.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
|
mapper.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -306,12 +306,12 @@ mod array_functions {
|
|||||||
|
|
||||||
for (i, item) in array.iter().enumerate() {
|
for (i, item) in array.iter().enumerate() {
|
||||||
if filter
|
if filter
|
||||||
.call_dynamic(&ctx, None, [item.clone()])
|
.call_raw(&ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -478,12 +478,12 @@ mod array_functions {
|
|||||||
|
|
||||||
for (i, item) in array.iter().enumerate().skip(start) {
|
for (i, item) in array.iter().enumerate().skip(start) {
|
||||||
if filter
|
if filter
|
||||||
.call_dynamic(&ctx, None, [item.clone()])
|
.call_raw(&ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -525,12 +525,12 @@ mod array_functions {
|
|||||||
|
|
||||||
for (i, item) in array.iter().enumerate() {
|
for (i, item) in array.iter().enumerate() {
|
||||||
if filter
|
if filter
|
||||||
.call_dynamic(&ctx, None, [item.clone()])
|
.call_raw(&ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -571,12 +571,12 @@ mod array_functions {
|
|||||||
|
|
||||||
for (i, item) in array.iter().enumerate() {
|
for (i, item) in array.iter().enumerate() {
|
||||||
if !filter
|
if !filter
|
||||||
.call_dynamic(&ctx, None, [item.clone()])
|
.call_raw(&ctx, None, [item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(&ctx, None, [item.clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [item.clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -621,7 +621,7 @@ mod array_functions {
|
|||||||
|
|
||||||
array.dedup_by(|x, y| {
|
array.dedup_by(|x, y| {
|
||||||
comparer
|
comparer
|
||||||
.call_dynamic(&ctx, None, [x.clone(), y.clone()])
|
.call_raw(&ctx, None, [x.clone(), y.clone()])
|
||||||
.unwrap_or_else(|_| Dynamic::FALSE)
|
.unwrap_or_else(|_| Dynamic::FALSE)
|
||||||
.as_bool()
|
.as_bool()
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
@ -670,12 +670,12 @@ mod array_functions {
|
|||||||
let item = item.clone();
|
let item = item.clone();
|
||||||
|
|
||||||
result = reducer
|
result = reducer
|
||||||
.call_dynamic(&ctx, None, [result.clone(), item.clone()])
|
.call_raw(&ctx, None, [result.clone(), item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(reducer.fn_name()) =>
|
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||||
{
|
{
|
||||||
reducer.call_dynamic(&ctx, None, [result, item, (i as INT).into()])
|
reducer.call_raw(&ctx, None, [result, item, (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -734,16 +734,12 @@ mod array_functions {
|
|||||||
let item = item.clone();
|
let item = item.clone();
|
||||||
|
|
||||||
result = reducer
|
result = reducer
|
||||||
.call_dynamic(&ctx, None, [result.clone(), item.clone()])
|
.call_raw(&ctx, None, [result.clone(), item.clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(reducer.fn_name()) =>
|
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||||
{
|
{
|
||||||
reducer.call_dynamic(
|
reducer.call_raw(&ctx, None, [result, item, ((len - 1 - i) as INT).into()])
|
||||||
&ctx,
|
|
||||||
None,
|
|
||||||
[result, item, ((len - 1 - i) as INT).into()],
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -788,7 +784,7 @@ mod array_functions {
|
|||||||
|
|
||||||
array.sort_by(|x, y| {
|
array.sort_by(|x, y| {
|
||||||
comparer
|
comparer
|
||||||
.call_dynamic(&ctx, None, [x.clone(), y.clone()])
|
.call_raw(&ctx, None, [x.clone(), y.clone()])
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|v| v.as_int().ok())
|
.and_then(|v| v.as_int().ok())
|
||||||
.map(|v| match v {
|
.map(|v| match v {
|
||||||
@ -891,12 +887,12 @@ mod array_functions {
|
|||||||
|
|
||||||
while x < array.len() {
|
while x < array.len() {
|
||||||
if filter
|
if filter
|
||||||
.call_dynamic(&ctx, None, [array[x].clone()])
|
.call_raw(&ctx, None, [array[x].clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(&ctx, None, [array[x].clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [array[x].clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
@ -973,12 +969,12 @@ mod array_functions {
|
|||||||
|
|
||||||
while x < array.len() {
|
while x < array.len() {
|
||||||
if !filter
|
if !filter
|
||||||
.call_dynamic(&ctx, None, [array[x].clone()])
|
.call_raw(&ctx, None, [array[x].clone()])
|
||||||
.or_else(|err| match *err {
|
.or_else(|err| match *err {
|
||||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||||
if fn_sig.starts_with(filter.fn_name()) =>
|
if fn_sig.starts_with(filter.fn_name()) =>
|
||||||
{
|
{
|
||||||
filter.call_dynamic(&ctx, None, [array[x].clone(), (i as INT).into()])
|
filter.call_raw(&ctx, None, [array[x].clone(), (i as INT).into()])
|
||||||
}
|
}
|
||||||
_ => Err(err),
|
_ => Err(err),
|
||||||
})
|
})
|
||||||
|
@ -101,9 +101,8 @@ impl FnPtr {
|
|||||||
/// Call the function pointer with curried arguments (if any).
|
/// Call the function pointer with curried arguments (if any).
|
||||||
/// The function may be script-defined (not available under `no_function`) or native Rust.
|
/// The function may be script-defined (not available under `no_function`) or native Rust.
|
||||||
///
|
///
|
||||||
/// This method is intended for calling a function pointer that is passed into a native Rust
|
/// This method is intended for calling a function pointer directly, possibly on another [`Engine`].
|
||||||
/// function as an argument. Therefore, the [`AST`] is _NOT_ evaluated before calling the
|
/// Therefore, the [`AST`] is _NOT_ evaluated before calling the function.
|
||||||
/// function.
|
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
@ -153,7 +152,7 @@ impl FnPtr {
|
|||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let ctx = NativeCallContext::new(engine, self.fn_name(), lib);
|
let ctx = NativeCallContext::new(engine, self.fn_name(), lib);
|
||||||
|
|
||||||
let result = self.call_dynamic(&ctx, None, arg_values)?;
|
let result = self.call_raw(&ctx, None, arg_values)?;
|
||||||
|
|
||||||
let typ = engine.map_type_name(result.type_name());
|
let typ = engine.map_type_name(result.type_name());
|
||||||
|
|
||||||
@ -172,17 +171,49 @@ impl FnPtr {
|
|||||||
/// This method is intended for calling a function pointer that is passed into a native Rust
|
/// This method is intended for calling a function pointer that is passed into a native Rust
|
||||||
/// function as an argument. Therefore, the [`AST`] is _NOT_ evaluated before calling the
|
/// function as an argument. Therefore, the [`AST`] is _NOT_ evaluated before calling the
|
||||||
/// function.
|
/// function.
|
||||||
|
#[inline]
|
||||||
|
pub fn call_within_context<T: Variant + Clone>(
|
||||||
|
&self,
|
||||||
|
context: &NativeCallContext,
|
||||||
|
args: impl FuncArgs,
|
||||||
|
) -> Result<T, Box<EvalAltResult>> {
|
||||||
|
let mut arg_values = crate::StaticVec::new_const();
|
||||||
|
args.parse(&mut arg_values);
|
||||||
|
|
||||||
|
let result = self.call_raw(&context, None, arg_values)?;
|
||||||
|
|
||||||
|
let typ = context.engine().map_type_name(result.type_name());
|
||||||
|
|
||||||
|
result.try_cast().ok_or_else(|| {
|
||||||
|
EvalAltResult::ErrorMismatchOutputType(
|
||||||
|
context.engine().map_type_name(type_name::<T>()).into(),
|
||||||
|
typ.into(),
|
||||||
|
Position::NONE,
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/// Call the function pointer with curried arguments (if any).
|
||||||
|
/// The function may be script-defined (not available under `no_function`) or native Rust.
|
||||||
///
|
///
|
||||||
/// # WARNING
|
/// This method is intended for calling a function pointer that is passed into a native Rust
|
||||||
|
/// function as an argument. Therefore, the [`AST`] is _NOT_ evaluated before calling the
|
||||||
|
/// function.
|
||||||
|
///
|
||||||
|
/// # WARNING - Low Level API
|
||||||
|
///
|
||||||
|
/// This function is very low level.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// All the arguments are _consumed_, meaning that they're replaced by `()`.
|
/// All the arguments are _consumed_, meaning that they're replaced by `()`.
|
||||||
/// This is to avoid unnecessarily cloning the arguments.
|
/// This is to avoid unnecessarily cloning the arguments.
|
||||||
/// Do not use the arguments after this call. If they are needed afterwards,
|
/// Do not use the arguments after this call. If they are needed afterwards,
|
||||||
/// clone them _before_ calling this function.
|
/// clone them _before_ calling this function.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn call_dynamic(
|
pub fn call_raw(
|
||||||
&self,
|
&self,
|
||||||
ctx: &NativeCallContext,
|
context: &NativeCallContext,
|
||||||
this_ptr: Option<&mut Dynamic>,
|
this_ptr: Option<&mut Dynamic>,
|
||||||
arg_values: impl AsMut<[Dynamic]>,
|
arg_values: impl AsMut<[Dynamic]>,
|
||||||
) -> RhaiResult {
|
) -> RhaiResult {
|
||||||
@ -205,7 +236,7 @@ impl FnPtr {
|
|||||||
}
|
}
|
||||||
args.extend(arg_values.iter_mut());
|
args.extend(arg_values.iter_mut());
|
||||||
|
|
||||||
ctx.call_fn_raw(self.fn_name(), is_method, is_method, &mut args)
|
context.call_fn_raw(self.fn_name(), is_method, is_method, &mut args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ fn test_fn_ptr_raw() -> Result<(), Box<EvalAltResult>> {
|
|||||||
let value = args[2].clone();
|
let value = args[2].clone();
|
||||||
let this_ptr = args.get_mut(0).unwrap();
|
let this_ptr = args.get_mut(0).unwrap();
|
||||||
|
|
||||||
fp.call_dynamic(&context, Some(this_ptr), [value])
|
fp.call_raw(&context, Some(this_ptr), [value])
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ fn test_fn_ptr_curry_call() -> Result<(), Box<EvalAltResult>> {
|
|||||||
&[TypeId::of::<FnPtr>(), TypeId::of::<INT>()],
|
&[TypeId::of::<FnPtr>(), TypeId::of::<INT>()],
|
||||||
|context, args| {
|
|context, args| {
|
||||||
let fn_ptr = std::mem::take(args[0]).cast::<FnPtr>();
|
let fn_ptr = std::mem::take(args[0]).cast::<FnPtr>();
|
||||||
fn_ptr.call_dynamic(&context, None, [std::mem::take(args[1])])
|
fn_ptr.call_raw(&context, None, [std::mem::take(args[1])])
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ fn test_closures() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|context, args| {
|
|context, args| {
|
||||||
let func = take(args[1]).cast::<FnPtr>();
|
let func = take(args[1]).cast::<FnPtr>();
|
||||||
|
|
||||||
func.call_dynamic(&context, None, [])
|
func.call_raw(&context, None, [])
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -98,8 +98,8 @@ fn test_functions_global_module() -> Result<(), Box<EvalAltResult>> {
|
|||||||
|
|
||||||
engine.register_result_fn(
|
engine.register_result_fn(
|
||||||
"do_stuff",
|
"do_stuff",
|
||||||
|context: NativeCallContext, callback: rhai::FnPtr| {
|
|context: NativeCallContext, callback: rhai::FnPtr| -> Result<INT, _> {
|
||||||
callback.call_dynamic(&context, None, [])
|
callback.call_within_context(&context, ())
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user