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 `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
|
||||
--------------------------
|
||||
@ -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`.
|
||||
* `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`.
|
||||
* `FnPtr::call_dynamic` is deprecated in favor of `FnPtr::call_raw`.
|
||||
|
||||
|
||||
Version 1.2.1
|
||||
|
@ -1,7 +1,8 @@
|
||||
//! Module containing all deprecated API that will be removed in the next major version.
|
||||
|
||||
use crate::{
|
||||
Dynamic, Engine, EvalAltResult, ImmutableString, NativeCallContext, RhaiResult, Scope, AST,
|
||||
Dynamic, Engine, EvalAltResult, FnPtr, ImmutableString, NativeCallContext, RhaiResult, Scope,
|
||||
AST,
|
||||
};
|
||||
|
||||
#[cfg(feature = "no_std")]
|
||||
@ -256,3 +257,39 @@ impl<T> From<EvalAltResult> for Result<T, Box<EvalAltResult>> {
|
||||
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.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
|
@ -261,12 +261,12 @@ mod array_functions {
|
||||
for (i, item) in array.iter().enumerate() {
|
||||
ar.push(
|
||||
mapper
|
||||
.call_dynamic(&ctx, None, [item.clone()])
|
||||
.call_raw(&ctx, None, [item.clone()])
|
||||
.or_else(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||
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),
|
||||
})
|
||||
@ -306,12 +306,12 @@ mod array_functions {
|
||||
|
||||
for (i, item) in array.iter().enumerate() {
|
||||
if filter
|
||||
.call_dynamic(&ctx, None, [item.clone()])
|
||||
.call_raw(&ctx, None, [item.clone()])
|
||||
.or_else(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||
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),
|
||||
})
|
||||
@ -478,12 +478,12 @@ mod array_functions {
|
||||
|
||||
for (i, item) in array.iter().enumerate().skip(start) {
|
||||
if filter
|
||||
.call_dynamic(&ctx, None, [item.clone()])
|
||||
.call_raw(&ctx, None, [item.clone()])
|
||||
.or_else(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||
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),
|
||||
})
|
||||
@ -525,12 +525,12 @@ mod array_functions {
|
||||
|
||||
for (i, item) in array.iter().enumerate() {
|
||||
if filter
|
||||
.call_dynamic(&ctx, None, [item.clone()])
|
||||
.call_raw(&ctx, None, [item.clone()])
|
||||
.or_else(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||
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),
|
||||
})
|
||||
@ -571,12 +571,12 @@ mod array_functions {
|
||||
|
||||
for (i, item) in array.iter().enumerate() {
|
||||
if !filter
|
||||
.call_dynamic(&ctx, None, [item.clone()])
|
||||
.call_raw(&ctx, None, [item.clone()])
|
||||
.or_else(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||
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),
|
||||
})
|
||||
@ -621,7 +621,7 @@ mod array_functions {
|
||||
|
||||
array.dedup_by(|x, y| {
|
||||
comparer
|
||||
.call_dynamic(&ctx, None, [x.clone(), y.clone()])
|
||||
.call_raw(&ctx, None, [x.clone(), y.clone()])
|
||||
.unwrap_or_else(|_| Dynamic::FALSE)
|
||||
.as_bool()
|
||||
.unwrap_or(false)
|
||||
@ -670,12 +670,12 @@ mod array_functions {
|
||||
let item = item.clone();
|
||||
|
||||
result = reducer
|
||||
.call_dynamic(&ctx, None, [result.clone(), item.clone()])
|
||||
.call_raw(&ctx, None, [result.clone(), item.clone()])
|
||||
.or_else(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||
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),
|
||||
})
|
||||
@ -734,16 +734,12 @@ mod array_functions {
|
||||
let item = item.clone();
|
||||
|
||||
result = reducer
|
||||
.call_dynamic(&ctx, None, [result.clone(), item.clone()])
|
||||
.call_raw(&ctx, None, [result.clone(), item.clone()])
|
||||
.or_else(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||
if fn_sig.starts_with(reducer.fn_name()) =>
|
||||
{
|
||||
reducer.call_dynamic(
|
||||
&ctx,
|
||||
None,
|
||||
[result, item, ((len - 1 - i) as INT).into()],
|
||||
)
|
||||
reducer.call_raw(&ctx, None, [result, item, ((len - 1 - i) as INT).into()])
|
||||
}
|
||||
_ => Err(err),
|
||||
})
|
||||
@ -788,7 +784,7 @@ mod array_functions {
|
||||
|
||||
array.sort_by(|x, y| {
|
||||
comparer
|
||||
.call_dynamic(&ctx, None, [x.clone(), y.clone()])
|
||||
.call_raw(&ctx, None, [x.clone(), y.clone()])
|
||||
.ok()
|
||||
.and_then(|v| v.as_int().ok())
|
||||
.map(|v| match v {
|
||||
@ -891,12 +887,12 @@ mod array_functions {
|
||||
|
||||
while x < array.len() {
|
||||
if filter
|
||||
.call_dynamic(&ctx, None, [array[x].clone()])
|
||||
.call_raw(&ctx, None, [array[x].clone()])
|
||||
.or_else(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||
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),
|
||||
})
|
||||
@ -973,12 +969,12 @@ mod array_functions {
|
||||
|
||||
while x < array.len() {
|
||||
if !filter
|
||||
.call_dynamic(&ctx, None, [array[x].clone()])
|
||||
.call_raw(&ctx, None, [array[x].clone()])
|
||||
.or_else(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||
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),
|
||||
})
|
||||
|
@ -101,9 +101,8 @@ 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.
|
||||
/// This method is intended for calling a function pointer directly, possibly on another [`Engine`].
|
||||
/// Therefore, the [`AST`] is _NOT_ evaluated before calling the function.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@ -153,7 +152,7 @@ impl FnPtr {
|
||||
#[allow(deprecated)]
|
||||
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());
|
||||
|
||||
@ -172,17 +171,49 @@ impl FnPtr {
|
||||
/// 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.
|
||||
#[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 `()`.
|
||||
/// 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.
|
||||
#[inline]
|
||||
pub fn call_dynamic(
|
||||
pub fn call_raw(
|
||||
&self,
|
||||
ctx: &NativeCallContext,
|
||||
context: &NativeCallContext,
|
||||
this_ptr: Option<&mut Dynamic>,
|
||||
arg_values: impl AsMut<[Dynamic]>,
|
||||
) -> RhaiResult {
|
||||
@ -205,7 +236,7 @@ impl FnPtr {
|
||||
}
|
||||
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 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>()],
|
||||
|context, args| {
|
||||
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| {
|
||||
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(
|
||||
"do_stuff",
|
||||
|context: NativeCallContext, callback: rhai::FnPtr| {
|
||||
callback.call_dynamic(&context, None, [])
|
||||
|context: NativeCallContext, callback: rhai::FnPtr| -> Result<INT, _> {
|
||||
callback.call_within_context(&context, ())
|
||||
},
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user