Deprecate Module::set_fn_XXX API.
This commit is contained in:
parent
d0922adb5b
commit
e9f280f917
@ -9,6 +9,7 @@ Breaking changes
|
||||
|
||||
* The traits `RegisterFn` and `RegisterResultFn` are removed. `Engine::register_fn` and `Engine::register_result_fn` are now implemented directly on `Engine`.
|
||||
* `FnPtr::call_dynamic` now takes `&NativeCallContext` instead of consuming it.
|
||||
* All `Module::set_fn_XXX` methods are removed, in favor of `Module::set_native_fn`.
|
||||
|
||||
|
||||
Version 0.19.14
|
||||
|
@ -51,8 +51,18 @@ impl Engine {
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn register_fn<A>(&mut self, name: &str, func: impl RegisterNativeFunction<A, ()>) -> &mut Self {
|
||||
func.register_into(self, name);
|
||||
pub fn register_fn<A, F>(&mut self, name: &str, func: F) -> &mut Self
|
||||
where
|
||||
F: RegisterNativeFunction<A, ()>,
|
||||
{
|
||||
self.global_namespace.set_fn(
|
||||
name,
|
||||
FnNamespace::Global,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&F::param_types(),
|
||||
func.into_callable_function(),
|
||||
);
|
||||
self
|
||||
}
|
||||
/// Register a custom fallible function with the [`Engine`].
|
||||
@ -79,12 +89,18 @@ impl Engine {
|
||||
/// engine.eval::<i64>("div(42, 0)")
|
||||
/// .expect_err("expecting division by zero error!");
|
||||
/// ```
|
||||
pub fn register_result_fn<A>(
|
||||
&mut self,
|
||||
name: &str,
|
||||
func: impl RegisterNativeFunction<A, RhaiResult>,
|
||||
) -> &mut Self {
|
||||
func.register_into(self, name);
|
||||
pub fn register_result_fn<A, F>(&mut self, name: &str, func: F) -> &mut Self
|
||||
where
|
||||
F: RegisterNativeFunction<A, RhaiResult>,
|
||||
{
|
||||
self.global_namespace.set_fn(
|
||||
name,
|
||||
FnNamespace::Global,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&F::param_types(),
|
||||
func.into_callable_function(),
|
||||
);
|
||||
self
|
||||
}
|
||||
/// Register a function of the [`Engine`].
|
||||
@ -803,8 +819,7 @@ impl Engine {
|
||||
pub fn load_package(&mut self, module: impl Into<Shared<Module>>) -> &mut Self {
|
||||
self.register_global_module(module.into())
|
||||
}
|
||||
/// Register a shared [`Module`] as a static module namespace with the
|
||||
/// [`Engine`].
|
||||
/// Register a shared [`Module`] as a static module namespace with the [`Engine`].
|
||||
///
|
||||
/// Functions marked [`FnNamespace::Global`] and type iterators are exposed to scripts without
|
||||
/// namespace qualifications.
|
||||
@ -819,7 +834,7 @@ impl Engine {
|
||||
///
|
||||
/// // Create the module
|
||||
/// let mut module = Module::new();
|
||||
/// module.set_fn_1("calc", |x: i64| Ok(x + 1));
|
||||
/// module.set_native_fn("calc", |x: i64| Ok(x + 1));
|
||||
///
|
||||
/// let module: Shared<Module> = module.into();
|
||||
///
|
||||
|
@ -5,8 +5,8 @@
|
||||
use crate::dynamic::{DynamicWriteLock, Variant};
|
||||
use crate::fn_native::{CallableFunction, FnAny, FnCallArgs, SendSync};
|
||||
use crate::r#unsafe::unsafe_try_cast;
|
||||
use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String};
|
||||
use crate::{Dynamic, Engine, FnAccess, FnNamespace, NativeCallContext, RhaiResult};
|
||||
use crate::stdlib::{any::TypeId, boxed::Box, mem, string::String, vec};
|
||||
use crate::{Dynamic, EvalAltResult, NativeCallContext};
|
||||
|
||||
// These types are used to build a unique _marker_ tuple type for each combination
|
||||
// of function parameter types in order to make each trait implementation unique.
|
||||
@ -53,10 +53,12 @@ pub fn by_value<T: Variant + Clone>(data: &mut Dynamic) -> T {
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait to register custom functions with an [`Engine`].
|
||||
/// Trait to register custom Rust functions.
|
||||
pub trait RegisterNativeFunction<Args, Result> {
|
||||
/// Register the function with an [`Engine`].
|
||||
fn register_into(self, engine: &mut Engine, name: &str);
|
||||
/// Get the types of this function's parameters.
|
||||
fn param_types() -> Box<[TypeId]>;
|
||||
/// Convert this function into a [`CallableFunction`].
|
||||
fn into_callable_function(self) -> CallableFunction;
|
||||
}
|
||||
|
||||
macro_rules! def_register {
|
||||
@ -77,21 +79,20 @@ macro_rules! def_register {
|
||||
RET: Variant + Clone
|
||||
> RegisterNativeFunction<($($mark,)*), ()> for FN {
|
||||
#[inline(always)]
|
||||
fn register_into(self, engine: &mut Engine, name: &str) {
|
||||
engine.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
// The arguments are assumed to be of the correct number and types!
|
||||
let mut _drain = args.iter_mut();
|
||||
$($let $par = ($clone)(_drain.next().unwrap()); )*
|
||||
fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||
#[inline(always)]
|
||||
fn into_callable_function(self) -> CallableFunction {
|
||||
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
// The arguments are assumed to be of the correct number and types!
|
||||
let mut _drain = args.iter_mut();
|
||||
$($let $par = ($clone)(_drain.next().unwrap()); )*
|
||||
|
||||
// Call the function with each argument value
|
||||
let r = self($($arg),*);
|
||||
// Call the function with each argument value
|
||||
let r = self($($arg),*);
|
||||
|
||||
// Map the result
|
||||
Ok(r.into_dynamic())
|
||||
}) as Box<FnAny>)
|
||||
);
|
||||
// Map the result
|
||||
Ok(r.into_dynamic())
|
||||
}) as Box<FnAny>)
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,61 +102,60 @@ macro_rules! def_register {
|
||||
RET: Variant + Clone
|
||||
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), ()> for FN {
|
||||
#[inline(always)]
|
||||
fn register_into(self, engine: &mut Engine, name: &str) {
|
||||
engine.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
||||
// The arguments are assumed to be of the correct number and types!
|
||||
let mut _drain = args.iter_mut();
|
||||
$($let $par = ($clone)(_drain.next().unwrap()); )*
|
||||
fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||
#[inline(always)]
|
||||
fn into_callable_function(self) -> CallableFunction {
|
||||
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
||||
// The arguments are assumed to be of the correct number and types!
|
||||
let mut _drain = args.iter_mut();
|
||||
$($let $par = ($clone)(_drain.next().unwrap()); )*
|
||||
|
||||
// Call the function with each argument value
|
||||
let r = self(ctx, $($arg),*);
|
||||
// Call the function with each argument value
|
||||
let r = self(ctx, $($arg),*);
|
||||
|
||||
// Map the result
|
||||
Ok(r.into_dynamic())
|
||||
}) as Box<FnAny>)
|
||||
);
|
||||
// Map the result
|
||||
Ok(r.into_dynamic())
|
||||
}) as Box<FnAny>)
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
FN: Fn($($param),*) -> RhaiResult + SendSync + 'static,
|
||||
FN: Fn($($param),*) -> Result<RET, Box<EvalAltResult>> + SendSync + 'static,
|
||||
$($par: Variant + Clone,)*
|
||||
> RegisterNativeFunction<($($mark,)*), RhaiResult> for FN {
|
||||
RET: Variant + Clone
|
||||
> RegisterNativeFunction<($($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
|
||||
#[inline(always)]
|
||||
fn register_into(self, engine: &mut Engine, name: &str) {
|
||||
engine.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
// The arguments are assumed to be of the correct number and types!
|
||||
let mut _drain = args.iter_mut();
|
||||
$($let $par = ($clone)(_drain.next().unwrap()); )*
|
||||
fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||
#[inline(always)]
|
||||
fn into_callable_function(self) -> CallableFunction {
|
||||
CallableFunction::$abi(Box::new(move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
// The arguments are assumed to be of the correct number and types!
|
||||
let mut _drain = args.iter_mut();
|
||||
$($let $par = ($clone)(_drain.next().unwrap()); )*
|
||||
|
||||
// Call the function with each argument value
|
||||
self($($arg),*)
|
||||
}) as Box<FnAny>)
|
||||
);
|
||||
// Call the function with each argument value
|
||||
self($($arg),*).map(Dynamic::from)
|
||||
}) as Box<FnAny>)
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
FN: for<'a> Fn(NativeCallContext<'a>, $($param),*) -> RhaiResult + SendSync + 'static,
|
||||
FN: for<'a> Fn(NativeCallContext<'a>, $($param),*) -> Result<RET, Box<EvalAltResult>> + SendSync + 'static,
|
||||
$($par: Variant + Clone,)*
|
||||
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), RhaiResult> for FN {
|
||||
RET: Variant + Clone
|
||||
> RegisterNativeFunction<(NativeCallContext<'static>, $($mark,)*), Result<RET, Box<EvalAltResult>>> for FN {
|
||||
#[inline(always)]
|
||||
fn register_into(self, engine: &mut Engine, name: &str) {
|
||||
engine.global_namespace.set_fn(name, FnNamespace::Global, FnAccess::Public, None,
|
||||
&[$(TypeId::of::<$par>()),*],
|
||||
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
||||
// The arguments are assumed to be of the correct number and types!
|
||||
let mut _drain = args.iter_mut();
|
||||
$($let $par = ($clone)(_drain.next().unwrap()); )*
|
||||
fn param_types() -> Box<[TypeId]> { vec![$(TypeId::of::<$par>()),*].into_boxed_slice() }
|
||||
#[inline(always)]
|
||||
fn into_callable_function(self) -> CallableFunction {
|
||||
CallableFunction::$abi(Box::new(move |ctx: NativeCallContext, args: &mut FnCallArgs| {
|
||||
// The arguments are assumed to be of the correct number and types!
|
||||
let mut _drain = args.iter_mut();
|
||||
$($let $par = ($clone)(_drain.next().unwrap()); )*
|
||||
|
||||
// Call the function with each argument value
|
||||
self(ctx, $($arg),*)
|
||||
}) as Box<FnAny>)
|
||||
);
|
||||
// Call the function with each argument value
|
||||
self(ctx, $($arg),*).map(Dynamic::from)
|
||||
}) as Box<FnAny>)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
use crate::ast::{FnAccess, Ident};
|
||||
use crate::dynamic::Variant;
|
||||
use crate::fn_native::{shared_take_or_clone, CallableFunction, FnCallArgs, IteratorFn, SendSync};
|
||||
use crate::fn_register::by_value as cast_arg;
|
||||
use crate::fn_register::RegisterNativeFunction;
|
||||
use crate::stdlib::{
|
||||
any::TypeId,
|
||||
boxed::Box,
|
||||
@ -607,7 +607,7 @@ impl Module {
|
||||
|
||||
/// Does the particular Rust function exist in the [`Module`]?
|
||||
///
|
||||
/// The [`u64`] hash is returned by the `set_fn_XXX` calls.
|
||||
/// The [`u64`] hash is returned by the [`set_native_fn`][Module::set_native_fn] call.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@ -615,7 +615,7 @@ impl Module {
|
||||
/// use rhai::Module;
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let hash = module.set_fn_0("calc", || Ok(42_i64));
|
||||
/// let hash = module.set_native_fn("calc", || Ok(42_i64));
|
||||
/// assert!(module.contains_fn(hash, true));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
@ -634,7 +634,7 @@ impl Module {
|
||||
|
||||
/// Update the metadata (parameter names/types and return type) of a registered function.
|
||||
///
|
||||
/// The [`u64`] hash is returned by the `set_fn_XXX` calls.
|
||||
/// The [`u64`] hash is returned by the [`set_native_fn`][Module::set_native_fn] call.
|
||||
///
|
||||
/// ## Parameter Names and Types
|
||||
///
|
||||
@ -654,7 +654,7 @@ impl Module {
|
||||
|
||||
/// Update the namespace of a registered function.
|
||||
///
|
||||
/// The [`u64`] hash is returned by the `set_fn_XXX` calls.
|
||||
/// The [`u64`] hash is returned by the [`set_native_fn`][Module::set_native_fn] call.
|
||||
#[inline(always)]
|
||||
pub fn update_fn_namespace(&mut self, hash_fn: u64, namespace: FnNamespace) -> &mut Self {
|
||||
if let Some(f) = self.functions.get_mut(&hash_fn) {
|
||||
@ -822,13 +822,19 @@ impl Module {
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking no parameters into the [`Module`], returning a hash key.
|
||||
/// Set a Rust function into the [`Module`], returning a hash key.
|
||||
///
|
||||
/// If there is a similar existing Rust function, it is replaced.
|
||||
///
|
||||
/// # Function Namespace
|
||||
///
|
||||
/// The default function namespace is [`FnNamespace::Internal`].
|
||||
/// Use [`update_fn_namespace`][Module::update_fn_namespace] to change it.
|
||||
///
|
||||
/// # Function Metadata
|
||||
///
|
||||
/// No metadata for the function is registered. Use `update_fn_metadata` to add metadata.
|
||||
/// No metadata for the function is registered.
|
||||
/// Use [`update_fn_metadata`][Module::update_fn_metadata] to add metadata.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@ -836,101 +842,22 @@ impl Module {
|
||||
/// use rhai::Module;
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let hash = module.set_fn_0("calc", || Ok(42_i64));
|
||||
/// let hash = module.set_native_fn("calc", || Ok(42_i64));
|
||||
/// assert!(module.contains_fn(hash, true));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_fn_0<T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
func: impl Fn() -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: NativeCallContext, _: &mut FnCallArgs| func().map(Dynamic::from);
|
||||
let arg_types = [];
|
||||
pub fn set_native_fn<ARGS, T, F>(&mut self, name: impl Into<String>, func: F) -> u64
|
||||
where
|
||||
T: Variant + Clone,
|
||||
F: RegisterNativeFunction<ARGS, Result<T, Box<EvalAltResult>>>,
|
||||
{
|
||||
self.set_fn(
|
||||
name,
|
||||
FnNamespace::Internal,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking one parameter into the [`Module`], returning a hash key.
|
||||
///
|
||||
/// If there is a similar existing Rust function, it is replaced.
|
||||
///
|
||||
/// # Function Metadata
|
||||
///
|
||||
/// No metadata for the function is registered. Use `update_fn_metadata` to add metadata.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::Module;
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let hash = module.set_fn_1("calc", |x: i64| Ok(x + 1));
|
||||
/// assert!(module.contains_fn(hash, true));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_fn_1<A: Variant + Clone, T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
func: impl Fn(A) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
func(cast_arg::<A>(&mut args[0])).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>()];
|
||||
self.set_fn(
|
||||
name,
|
||||
FnNamespace::Internal,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking one mutable parameter into the [`Module`], returning a hash key.
|
||||
///
|
||||
/// If there is a similar existing Rust function, it is replaced.
|
||||
///
|
||||
/// # Function Metadata
|
||||
///
|
||||
/// No metadata for the function is registered. Use `update_fn_metadata` to add metadata.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::{Module, FnNamespace};
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let hash = module.set_fn_1_mut("calc", FnNamespace::Internal,
|
||||
/// |x: &mut i64| { *x += 1; Ok(*x) }
|
||||
/// );
|
||||
/// assert!(module.contains_fn(hash, true));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_fn_1_mut<A: Variant + Clone, T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
namespace: FnNamespace,
|
||||
func: impl Fn(&mut A) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
func(&mut args[0].write_lock::<A>().unwrap()).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>()];
|
||||
self.set_fn(
|
||||
name,
|
||||
namespace,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
&F::param_types(),
|
||||
func.into_callable_function(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -954,104 +881,20 @@ impl Module {
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
#[inline(always)]
|
||||
pub fn set_getter_fn<A: Variant + Clone, T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
func: impl Fn(&mut A) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
self.set_fn_1_mut(
|
||||
pub fn set_getter_fn<ARGS, A, T, F>(&mut self, name: impl Into<String>, func: F) -> u64
|
||||
where
|
||||
A: Variant + Clone,
|
||||
T: Variant + Clone,
|
||||
F: RegisterNativeFunction<ARGS, Result<T, Box<EvalAltResult>>>,
|
||||
F: Fn(&mut A) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
{
|
||||
self.set_fn(
|
||||
crate::engine::make_getter(&name.into()),
|
||||
FnNamespace::Global,
|
||||
func,
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking two parameters into the [`Module`], returning a hash key.
|
||||
///
|
||||
/// If there is a similar existing Rust function, it is replaced.
|
||||
///
|
||||
/// # Function Metadata
|
||||
///
|
||||
/// No metadata for the function is registered. Use `update_fn_metadata` to add metadata.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::{Module, ImmutableString};
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let hash = module.set_fn_2("calc", |x: i64, y: ImmutableString| {
|
||||
/// Ok(x + y.len() as i64)
|
||||
/// });
|
||||
/// assert!(module.contains_fn(hash, true));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_fn_2<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
func: impl Fn(A, B) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
let a = cast_arg::<A>(&mut args[0]);
|
||||
let b = cast_arg::<B>(&mut args[1]);
|
||||
|
||||
func(a, b).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>()];
|
||||
self.set_fn(
|
||||
name,
|
||||
FnNamespace::Internal,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking two parameters (the first one mutable) into the [`Module`],
|
||||
/// returning a hash key.
|
||||
///
|
||||
/// If there is a similar existing Rust function, it is replaced.
|
||||
///
|
||||
/// # Function Metadata
|
||||
///
|
||||
/// No metadata for the function is registered. Use `update_fn_metadata` to add metadata.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::{Module, FnNamespace, ImmutableString};
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let hash = module.set_fn_2_mut("calc", FnNamespace::Internal,
|
||||
/// |x: &mut i64, y: ImmutableString| {
|
||||
/// *x += y.len() as i64;
|
||||
/// Ok(*x)
|
||||
/// }
|
||||
/// );
|
||||
/// assert!(module.contains_fn(hash, true));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_fn_2_mut<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
namespace: FnNamespace,
|
||||
func: impl Fn(&mut A, B) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
let b = cast_arg::<B>(&mut args[1]);
|
||||
let a = &mut args[0].write_lock::<A>().unwrap();
|
||||
|
||||
func(a, b).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>()];
|
||||
self.set_fn(
|
||||
name,
|
||||
namespace,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
&F::param_types(),
|
||||
func.into_callable_function(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1079,15 +922,20 @@ impl Module {
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
#[inline(always)]
|
||||
pub fn set_setter_fn<A: Variant + Clone, B: Variant + Clone>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
func: impl Fn(&mut A, B) -> Result<(), Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
self.set_fn_2_mut(
|
||||
pub fn set_setter_fn<ARGS, A, B, F>(&mut self, name: impl Into<String>, func: F) -> u64
|
||||
where
|
||||
A: Variant + Clone,
|
||||
B: Variant + Clone,
|
||||
F: RegisterNativeFunction<ARGS, Result<(), Box<EvalAltResult>>>,
|
||||
F: Fn(&mut A, B) -> Result<(), Box<EvalAltResult>> + SendSync + 'static,
|
||||
{
|
||||
self.set_fn(
|
||||
crate::engine::make_setter(&name.into()),
|
||||
FnNamespace::Global,
|
||||
func,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&F::param_types(),
|
||||
func.into_callable_function(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1119,10 +967,14 @@ impl Module {
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
#[inline(always)]
|
||||
pub fn set_indexer_get_fn<A: Variant + Clone, B: Variant + Clone, T: Variant + Clone>(
|
||||
&mut self,
|
||||
func: impl Fn(&mut A, B) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
pub fn set_indexer_get_fn<ARGS, A, B, T, F>(&mut self, func: F) -> u64
|
||||
where
|
||||
A: Variant + Clone,
|
||||
B: Variant + Clone,
|
||||
T: Variant + Clone,
|
||||
F: RegisterNativeFunction<ARGS, Result<T, Box<EvalAltResult>>>,
|
||||
F: Fn(&mut A, B) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
{
|
||||
if TypeId::of::<A>() == TypeId::of::<Array>() {
|
||||
panic!("Cannot register indexer for arrays.");
|
||||
}
|
||||
@ -1137,107 +989,13 @@ impl Module {
|
||||
panic!("Cannot register indexer for strings.");
|
||||
}
|
||||
|
||||
self.set_fn_2_mut(crate::engine::FN_IDX_GET, FnNamespace::Global, func)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking three parameters into the [`Module`], returning a hash key.
|
||||
///
|
||||
/// If there is a similar existing Rust function, it is replaced.
|
||||
///
|
||||
/// # Function Metadata
|
||||
///
|
||||
/// No metadata for the function is registered. Use `update_fn_metadata` to add metadata.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::{Module, ImmutableString};
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let hash = module.set_fn_3("calc", |x: i64, y: ImmutableString, z: i64| {
|
||||
/// Ok(x + y.len() as i64 + z)
|
||||
/// });
|
||||
/// assert!(module.contains_fn(hash, true));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_fn_3<
|
||||
A: Variant + Clone,
|
||||
B: Variant + Clone,
|
||||
C: Variant + Clone,
|
||||
T: Variant + Clone,
|
||||
>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
func: impl Fn(A, B, C) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
let a = cast_arg::<A>(&mut args[0]);
|
||||
let b = cast_arg::<B>(&mut args[1]);
|
||||
let c = cast_arg::<C>(&mut args[2]);
|
||||
|
||||
func(a, b, c).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||
self.set_fn(
|
||||
name,
|
||||
FnNamespace::Internal,
|
||||
crate::engine::FN_IDX_GET,
|
||||
FnNamespace::Global,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking three parameters (the first one mutable) into the [`Module`],
|
||||
/// returning a hash key.
|
||||
///
|
||||
/// If there is a similar existing Rust function, it is replaced.
|
||||
///
|
||||
/// # Function Metadata
|
||||
///
|
||||
/// No metadata for the function is registered. Use `update_fn_metadata` to add metadata.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::{Module, FnNamespace, ImmutableString};
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let hash = module.set_fn_3_mut("calc", FnNamespace::Internal,
|
||||
/// |x: &mut i64, y: ImmutableString, z: i64| {
|
||||
/// *x += y.len() as i64 + z;
|
||||
/// Ok(*x)
|
||||
/// }
|
||||
/// );
|
||||
/// assert!(module.contains_fn(hash, true));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_fn_3_mut<
|
||||
A: Variant + Clone,
|
||||
B: Variant + Clone,
|
||||
C: Variant + Clone,
|
||||
T: Variant + Clone,
|
||||
>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
namespace: FnNamespace,
|
||||
func: impl Fn(&mut A, B, C) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
let b = cast_arg::<B>(&mut args[2]);
|
||||
let c = cast_arg::<C>(&mut args[3]);
|
||||
let a = &mut args[0].write_lock::<A>().unwrap();
|
||||
|
||||
func(a, b, c).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||
self.set_fn(
|
||||
name,
|
||||
namespace,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
&F::param_types(),
|
||||
func.into_callable_function(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1270,10 +1028,14 @@ impl Module {
|
||||
/// ```
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
#[inline(always)]
|
||||
pub fn set_indexer_set_fn<A: Variant + Clone, B: Variant + Clone, C: Variant + Clone>(
|
||||
&mut self,
|
||||
func: impl Fn(&mut A, B, C) -> Result<(), Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
pub fn set_indexer_set_fn<ARGS, A, B, C, F>(&mut self, func: F) -> u64
|
||||
where
|
||||
A: Variant + Clone,
|
||||
B: Variant + Clone,
|
||||
C: Variant + Clone,
|
||||
F: RegisterNativeFunction<ARGS, Result<(), Box<EvalAltResult>>>,
|
||||
F: Fn(&mut A, B, C) -> Result<(), Box<EvalAltResult>> + SendSync + 'static,
|
||||
{
|
||||
if TypeId::of::<A>() == TypeId::of::<Array>() {
|
||||
panic!("Cannot register indexer for arrays.");
|
||||
}
|
||||
@ -1288,21 +1050,13 @@ impl Module {
|
||||
panic!("Cannot register indexer for strings.");
|
||||
}
|
||||
|
||||
let f = move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
let b = cast_arg::<B>(&mut args[1]);
|
||||
let c = cast_arg::<C>(&mut args[2]);
|
||||
let a = &mut args[0].write_lock::<A>().unwrap();
|
||||
|
||||
func(a, b, c).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
|
||||
self.set_fn(
|
||||
crate::engine::FN_IDX_SET,
|
||||
FnNamespace::Internal,
|
||||
FnNamespace::Global,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
&F::param_types(),
|
||||
func.into_callable_function(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1352,124 +1106,9 @@ impl Module {
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking four parameters into the [`Module`], returning a hash key.
|
||||
///
|
||||
/// If there is a similar existing Rust function, it is replaced.
|
||||
///
|
||||
/// # Function Metadata
|
||||
///
|
||||
/// No metadata for the function is registered. Use `update_fn_metadata` to add metadata.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::{Module, ImmutableString};
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let hash = module.set_fn_4("calc", |x: i64, y: ImmutableString, z: i64, _w: ()| {
|
||||
/// Ok(x + y.len() as i64 + z)
|
||||
/// });
|
||||
/// assert!(module.contains_fn(hash, true));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_fn_4<
|
||||
A: Variant + Clone,
|
||||
B: Variant + Clone,
|
||||
C: Variant + Clone,
|
||||
D: Variant + Clone,
|
||||
T: Variant + Clone,
|
||||
>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
func: impl Fn(A, B, C, D) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
let a = cast_arg::<A>(&mut args[0]);
|
||||
let b = cast_arg::<B>(&mut args[1]);
|
||||
let c = cast_arg::<C>(&mut args[2]);
|
||||
let d = cast_arg::<D>(&mut args[3]);
|
||||
|
||||
func(a, b, c, d).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [
|
||||
TypeId::of::<A>(),
|
||||
TypeId::of::<B>(),
|
||||
TypeId::of::<C>(),
|
||||
TypeId::of::<D>(),
|
||||
];
|
||||
self.set_fn(
|
||||
name,
|
||||
FnNamespace::Internal,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_pure(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Set a Rust function taking four parameters (the first one mutable) into the [`Module`],
|
||||
/// returning a hash key.
|
||||
///
|
||||
/// If there is a similar existing Rust function, it is replaced.
|
||||
///
|
||||
/// # Function Metadata
|
||||
///
|
||||
/// No metadata for the function is registered. Use `update_fn_metadata` to add metadata.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::{Module, FnNamespace, ImmutableString};
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// let hash = module.set_fn_4_mut("calc", FnNamespace::Internal,
|
||||
/// |x: &mut i64, y: ImmutableString, z: i64, _w: ()| {
|
||||
/// *x += y.len() as i64 + z;
|
||||
/// Ok(*x)
|
||||
/// }
|
||||
/// );
|
||||
/// assert!(module.contains_fn(hash, true));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_fn_4_mut<
|
||||
A: Variant + Clone,
|
||||
B: Variant + Clone,
|
||||
C: Variant + Clone,
|
||||
D: Variant + Clone,
|
||||
T: Variant + Clone,
|
||||
>(
|
||||
&mut self,
|
||||
name: impl Into<String>,
|
||||
namespace: FnNamespace,
|
||||
func: impl Fn(&mut A, B, C, D) -> Result<T, Box<EvalAltResult>> + SendSync + 'static,
|
||||
) -> u64 {
|
||||
let f = move |_: NativeCallContext, args: &mut FnCallArgs| {
|
||||
let b = cast_arg::<B>(&mut args[1]);
|
||||
let c = cast_arg::<C>(&mut args[2]);
|
||||
let d = cast_arg::<D>(&mut args[3]);
|
||||
let a = &mut args[0].write_lock::<A>().unwrap();
|
||||
|
||||
func(a, b, c, d).map(Dynamic::from)
|
||||
};
|
||||
let arg_types = [
|
||||
TypeId::of::<A>(),
|
||||
TypeId::of::<B>(),
|
||||
TypeId::of::<C>(),
|
||||
TypeId::of::<D>(),
|
||||
];
|
||||
self.set_fn(
|
||||
name,
|
||||
namespace,
|
||||
FnAccess::Public,
|
||||
None,
|
||||
&arg_types,
|
||||
CallableFunction::from_method(Box::new(f)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Get a Rust function.
|
||||
///
|
||||
/// The [`u64`] hash is returned by the `set_fn_XXX` calls.
|
||||
/// The [`u64`] hash is returned by the [`set_native_fn`][Module::set_native_fn] call.
|
||||
#[inline(always)]
|
||||
pub(crate) fn get_fn(&self, hash_fn: u64, public_only: bool) -> Option<&CallableFunction> {
|
||||
self.functions.get(&hash_fn).and_then(|f| match f.access {
|
||||
|
@ -141,7 +141,7 @@ macro_rules! reg_range {
|
||||
($lib:ident | $x:expr => $( $y:ty ),*) => {
|
||||
$(
|
||||
$lib.set_iterator::<Range<$y>>();
|
||||
let hash = $lib.set_fn_2($x, get_range::<$y>);
|
||||
let hash = $lib.set_native_fn($x, get_range::<$y>);
|
||||
$lib.update_fn_metadata(hash, &[
|
||||
concat!("from: ", stringify!($y)),
|
||||
concat!("to: ", stringify!($y)),
|
||||
@ -152,7 +152,7 @@ macro_rules! reg_range {
|
||||
($lib:ident | step $x:expr => $( $y:ty ),*) => {
|
||||
$(
|
||||
$lib.set_iterator::<StepRange<$y>>();
|
||||
let hash = $lib.set_fn_3($x, get_step_range::<$y>);
|
||||
let hash = $lib.set_native_fn($x, get_step_range::<$y>);
|
||||
$lib.update_fn_metadata(hash, &[
|
||||
concat!("from: ", stringify!($y)),
|
||||
concat!("to: ", stringify!($y)),
|
||||
@ -248,10 +248,10 @@ def_package!(crate:BasicIteratorPackage:"Basic range iterators.", lib, {
|
||||
|
||||
lib.set_iterator::<StepDecimalRange>();
|
||||
|
||||
let hash = lib.set_fn_2("range", |from, to| StepDecimalRange::new(from, to, Decimal::one()));
|
||||
let hash = lib.set_native_fn("range", |from, to| StepDecimalRange::new(from, to, Decimal::one()));
|
||||
lib.update_fn_metadata(hash, &["from: Decimal", "to: Decimal", "Iterator<Item=Decimal>"]);
|
||||
|
||||
let hash = lib.set_fn_3("range", |from, to, step| StepDecimalRange::new(from, to, step));
|
||||
let hash = lib.set_native_fn("range", |from, to, step| StepDecimalRange::new(from, to, step));
|
||||
lib.update_fn_metadata(hash, &["from: Decimal", "to: Decimal", "step: Decimal", "Iterator<Item=Decimal>"]);
|
||||
}
|
||||
});
|
||||
|
@ -53,8 +53,7 @@ pub trait Package {
|
||||
/// Macro that makes it easy to define a _package_ (which is basically a shared [module][Module])
|
||||
/// and register functions into it.
|
||||
///
|
||||
/// Functions can be added to the package using the standard module methods such as
|
||||
/// [`set_fn_2`][Module::set_fn_2], [`set_fn_3_mut`][Module::set_fn_3_mut], [`set_fn_0`][Module::set_fn_0] etc.
|
||||
/// Functions can be added to the package using [`Module::set_native_fn`].
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@ -69,7 +68,7 @@ pub trait Package {
|
||||
/// def_package!(rhai:MyPackage:"My super-duper package", lib,
|
||||
/// {
|
||||
/// // Load a binary function with all value parameters.
|
||||
/// lib.set_fn_2("my_add", add);
|
||||
/// lib.set_native_fn("my_add", add);
|
||||
/// });
|
||||
/// ```
|
||||
#[macro_export]
|
||||
|
@ -171,7 +171,7 @@ fn test_for_module_iterator() -> Result<(), Box<EvalAltResult>> {
|
||||
// Set a type iterator deep inside a nested module chain
|
||||
let mut sub_module = Module::new();
|
||||
sub_module.set_iterable::<MyIterableType>();
|
||||
sub_module.set_fn_0("new_ts", || Ok(MyIterableType("hello".to_string())));
|
||||
sub_module.set_native_fn("new_ts", || Ok(MyIterableType("hello".to_string())));
|
||||
|
||||
let mut module = Module::new();
|
||||
module.set_sub_module("inner", sub_module);
|
||||
|
@ -75,7 +75,7 @@ fn test_functions_namespaces() -> Result<(), Box<EvalAltResult>> {
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
{
|
||||
let mut m = Module::new();
|
||||
let hash = m.set_fn_0("test", || Ok(999 as INT));
|
||||
let hash = m.set_native_fn("test", || Ok(999 as INT));
|
||||
m.update_fn_namespace(hash, FnNamespace::Global);
|
||||
|
||||
engine.register_static_module("hello", m.into());
|
||||
|
@ -23,11 +23,12 @@ fn test_module_sub_module() -> Result<(), Box<EvalAltResult>> {
|
||||
let mut sub_module2 = Module::new();
|
||||
sub_module2.set_var("answer", 41 as INT);
|
||||
|
||||
let hash_inc = sub_module2.set_fn_1_mut("inc", FnNamespace::Internal, |x: &mut INT| Ok(*x + 1));
|
||||
let hash_inc = sub_module2.set_native_fn("inc", |x: &mut INT| Ok(*x + 1));
|
||||
sub_module2.build_index();
|
||||
assert!(!sub_module2.contains_indexed_global_functions());
|
||||
|
||||
sub_module2.set_fn_1_mut("super_inc", FnNamespace::Global, |x: &mut INT| Ok(*x + 1));
|
||||
let super_hash = sub_module2.set_native_fn("super_inc", |x: &mut INT| Ok(*x + 1));
|
||||
sub_module2.update_fn_namespace(super_hash, FnNamespace::Global);
|
||||
sub_module2.build_index();
|
||||
assert!(sub_module2.contains_indexed_global_functions());
|
||||
|
||||
@ -91,16 +92,16 @@ fn test_module_resolver() -> Result<(), Box<EvalAltResult>> {
|
||||
let mut module = Module::new();
|
||||
|
||||
module.set_var("answer", 42 as INT);
|
||||
module.set_fn_4("sum", |x: INT, y: INT, z: INT, w: INT| Ok(x + y + z + w));
|
||||
module.set_fn_1_mut("double", FnNamespace::Global, |x: &mut INT| {
|
||||
module.set_native_fn("sum", |x: INT, y: INT, z: INT, w: INT| Ok(x + y + z + w));
|
||||
let double_hash = module.set_native_fn("double", |x: &mut INT| {
|
||||
*x *= 2;
|
||||
Ok(())
|
||||
});
|
||||
module.update_fn_namespace(double_hash, FnNamespace::Global);
|
||||
|
||||
#[cfg(not(feature = "no_float"))]
|
||||
module.set_fn_4_mut(
|
||||
module.set_native_fn(
|
||||
"sum_of_three_args",
|
||||
FnNamespace::Internal,
|
||||
|target: &mut INT, a: INT, b: INT, c: rhai::FLOAT| {
|
||||
*target = a + b + c as INT;
|
||||
Ok(())
|
||||
@ -407,9 +408,9 @@ fn test_module_str() -> Result<(), Box<EvalAltResult>> {
|
||||
|
||||
let mut engine = rhai::Engine::new();
|
||||
let mut module = Module::new();
|
||||
module.set_fn_1("test", test_fn);
|
||||
module.set_fn_1("test2", test_fn2);
|
||||
module.set_fn_1("test3", test_fn3);
|
||||
module.set_native_fn("test", test_fn);
|
||||
module.set_native_fn("test2", test_fn2);
|
||||
module.set_native_fn("test3", test_fn3);
|
||||
|
||||
let mut static_modules = rhai::module_resolvers::StaticModuleResolver::new();
|
||||
static_modules.insert("test", module);
|
||||
|
Loading…
Reference in New Issue
Block a user