diff --git a/RELEASES.md b/RELEASES.md index 22aae65d..520a2bf1 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,24 +6,32 @@ Version 0.18.0 This version adds: -* Anonymous functions (in closure syntax). Simplifies creation of ad hoc functions. +* Binding the `this` pointer in a function pointer `call`. +* Anonymous functions (in Rust closure syntax). Simplifies creation of single-use ad-hoc functions. * Currying of function pointers. New features ------------ * `call` can now be called function-call style for function pointers - this is to handle builds with `no_object`. -* Disallow many keywords as variables, such as `print`, `eval`, `call`, `this` etc. +* Reserve language keywords, such as `print`, `eval`, `call`, `this` etc. * `x.call(f, ...)` allows binding `x` to `this` for the function referenced by the function pointer `f`. -* Anonymous functions in the syntax of a closure, e.g. `|x, y, z| x + y - z`. +* Anonymous functions are supported in the syntax of a Rust closure, e.g. `|x, y, z| x + y - z`. * Custom syntax now works even without the `internals` feature. -* Currying of function pointers is supported via the `curry` keyword. +* Currying of function pointers is supported via the new `curry` keyword. * `Module::set_indexer_get_set_fn` is added as a shorthand of both `Module::set_indexer_get_fn` and `Module::set_indexer_set_fn`. Breaking changes ---------------- +* Language keywords are now _reserved_ (even when disabled) and they can no longer be used as variable names. * Function signature for defining custom syntax is simplified. +* `Engine::register_raw_fn_XXX` API shortcuts are removed. + +Housekeeping +------------ + +* Most compilation warnings are eliminated via feature gates. Version 0.17.0 @@ -57,7 +65,7 @@ New features * `Engine::disable_symbol` to surgically disable keywords and/or operators. * `Engine::register_custom_operator` to define a custom operator. * `Engine::register_custom_syntax` to define a custom syntax. -* New low-level API `Engine::register_raw_fn` and `Engine::register_raw_fn_XXX`. +* New low-level API `Engine::register_raw_fn`. * New low-level API `Module::set_raw_fn` mirroring `Engine::register_raw_fn`. * `AST::clone_functions_only`, `AST::clone_functions_only_filtered` and `AST::clone_statements_only` to clone only part of an `AST`. * The boolean `^` (XOR) operator is added. diff --git a/doc/src/engine/custom-syntax.md b/doc/src/engine/custom-syntax.md index 89fdf792..8f308106 100644 --- a/doc/src/engine/custom-syntax.md +++ b/doc/src/engine/custom-syntax.md @@ -114,10 +114,7 @@ Any custom syntax must include an _implementation_ of it. The function signature of an implementation is: -```rust -Fn(engine: &Engine, context: &mut EvalContext, scope: &mut Scope, inputs: &[Expression]) - -> Result> -``` +> `Fn(engine: &Engine, context: &mut EvalContext, scope: &mut Scope, inputs: &[Expression]) -> Result>` where: diff --git a/doc/src/rust/register-raw.md b/doc/src/rust/register-raw.md index 6d3f22c5..76866249 100644 --- a/doc/src/rust/register-raw.md +++ b/doc/src/rust/register-raw.md @@ -55,27 +55,12 @@ engine.register_fn("increment_by", |x: &mut i64, y: i64| x += y); ``` -Shortcuts ---------- +Function Signature +------------------ -As usual with Rhai, there are shortcuts. For functions of zero to four parameters, which should be -the majority, use one of the `Engine::register_raw_fn_n` (where `n = 0..4`) methods: +The function signature passed to `Engine::register_raw_fn` takes the following form: -```rust -// Specify parameter types as generics -engine.register_raw_fn_2::( - "increment_by", - |engine: &Engine, lib: &Module, args: &mut [&mut Dynamic]| { ... } -); -``` - - -Closure Signature ------------------ - -The closure passed to `Engine::register_raw_fn` takes the following form: - -`Fn(engine: &Engine, lib: &Module, args: &mut [&mut Dynamic]) -> Result> + 'static` +> `Fn(engine: &Engine, lib: &Module, args: &mut [&mut Dynamic]) -> Result> + 'static` where: @@ -113,6 +98,12 @@ there can be no other immutable references to `args`, otherwise the Rust borrow Example - Passing a Function Pointer to a Rust Function ------------------------------------------------------ +The low-level API is useful when there is a need to interact with the scripting [`Engine`] within a function. + +The following example registers a function that takes a [function pointer] as an argument, +then calls it within the same [`Engine`]. This way, a _callback_ function can be provided +to a native Rust function. + ```rust use rhai::{Engine, Module, Dynamic, FnPtr}; @@ -133,11 +124,10 @@ engine.register_raw_fn( let value = args[2].clone(); // 3rd argument - function argument let this_ptr = args.get_mut(0).unwrap(); // 1st argument - this pointer - // Use 'call_fn_dynamic' to call the function name. - // Pass 'lib' as the current global library of functions. - engine.call_fn_dynamic(&mut Scope::new(), lib, fp.fn_name(), Some(this_ptr), [value])?; - - Ok(()) + // Use 'FnPtr::call_dynamic' to call the function pointer. + // Beware, only script-defined functions are supported by 'FnPtr::call_dynamic'. + // If it is a native Rust function, directly call it here in Rust instead! + fp.call_dynamic(engine, lib, Some(this_ptr), [value]) }, ); diff --git a/src/api.rs b/src/api.rs index b7a1bb74..573a3366 100644 --- a/src/api.rs +++ b/src/api.rs @@ -62,147 +62,6 @@ impl Engine { self } - /// Register a function of no parameters with the `Engine`. - /// - /// ## WARNING - Low Level API - /// - /// This function is very low level. - #[deprecated(note = "this function is volatile and may change")] - pub fn register_raw_fn_0( - &mut self, - name: &str, - func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn + SendSync + 'static, - ) -> &mut Self { - self.global_module.set_raw_fn(name, &[], func); - self - } - - /// Register a function of one parameter with the `Engine`. - /// - /// ## WARNING - Low Level API - /// - /// This function is very low level. - /// - /// Arguments are simply passed in as a mutable array of `&mut Dynamic`, - /// which is guaranteed to contain enough arguments of the correct types. - /// - /// To access a primary parameter value (i.e. cloning is cheap), use: `args[n].clone().cast::()` - /// - /// To access a parameter value and avoid cloning, use `std::mem::take(args[n]).cast::()`. - /// Notice that this will _consume_ the argument, replacing it with `()`. - /// - /// To access the first mutable parameter, use `args.get_mut(0).unwrap()` - #[deprecated(note = "this function is volatile and may change")] - pub fn register_raw_fn_1( - &mut self, - name: &str, - func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn + SendSync + 'static, - ) -> &mut Self { - self.global_module - .set_raw_fn(name, &[TypeId::of::()], func); - self - } - - /// Register a function of two parameters with the `Engine`. - /// - /// ## WARNING - Low Level API - /// - /// This function is very low level. - /// - /// Arguments are simply passed in as a mutable array of `&mut Dynamic`, - /// which is guaranteed to contain enough arguments of the correct types. - /// - /// To access a primary parameter value (i.e. cloning is cheap), use: `args[n].clone().cast::()` - /// - /// To access a parameter value and avoid cloning, use `std::mem::take(args[n]).cast::()`. - /// Notice that this will _consume_ the argument, replacing it with `()`. - /// - /// To access the first mutable parameter, use `args.get_mut(0).unwrap()` - #[deprecated(note = "this function is volatile and may change")] - pub fn register_raw_fn_2( - &mut self, - name: &str, - func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn + SendSync + 'static, - ) -> &mut Self { - self.global_module - .set_raw_fn(name, &[TypeId::of::(), TypeId::of::()], func); - self - } - - /// Register a function of three parameters with the `Engine`. - /// - /// ## WARNING - Low Level API - /// - /// This function is very low level. - /// - /// Arguments are simply passed in as a mutable array of `&mut Dynamic`, - /// which is guaranteed to contain enough arguments of the correct types. - /// - /// To access a primary parameter value (i.e. cloning is cheap), use: `args[n].clone().cast::()` - /// - /// To access a parameter value and avoid cloning, use `std::mem::take(args[n]).cast::()`. - /// Notice that this will _consume_ the argument, replacing it with `()`. - /// - /// To access the first mutable parameter, use `args.get_mut(0).unwrap()` - #[deprecated(note = "this function is volatile and may change")] - pub fn register_raw_fn_3< - A: Variant + Clone, - B: Variant + Clone, - C: Variant + Clone, - T: Variant + Clone, - >( - &mut self, - name: &str, - func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn + SendSync + 'static, - ) -> &mut Self { - self.global_module.set_raw_fn( - name, - &[TypeId::of::(), TypeId::of::(), TypeId::of::()], - func, - ); - self - } - - /// Register a function of four parameters with the `Engine`. - /// - /// ## WARNING - Low Level API - /// - /// This function is very low level. - /// - /// Arguments are simply passed in as a mutable array of `&mut Dynamic`, - /// which is guaranteed to contain enough arguments of the correct types. - /// - /// To access a primary parameter value (i.e. cloning is cheap), use: `args[n].clone().cast::()` - /// - /// To access a parameter value and avoid cloning, use `std::mem::take(args[n]).cast::()`. - /// Notice that this will _consume_ the argument, replacing it with `()`. - /// - /// To access the first mutable parameter, use `args.get_mut(0).unwrap()` - #[deprecated(note = "this function is volatile and may change")] - pub fn register_raw_fn_4< - A: Variant + Clone, - B: Variant + Clone, - C: Variant + Clone, - D: Variant + Clone, - T: Variant + Clone, - >( - &mut self, - name: &str, - func: impl Fn(&Engine, &Module, &mut [&mut Dynamic]) -> FuncReturn + SendSync + 'static, - ) -> &mut Self { - self.global_module.set_raw_fn( - name, - &[ - TypeId::of::(), - TypeId::of::(), - TypeId::of::(), - TypeId::of::(), - ], - func, - ); - self - } - /// Register a custom type for use with the `Engine`. /// The type must implement `Clone`. /// diff --git a/tests/call_fn.rs b/tests/call_fn.rs index 9808ff70..3b93d520 100644 --- a/tests/call_fn.rs +++ b/tests/call_fn.rs @@ -131,15 +131,7 @@ fn test_fn_ptr_raw() -> Result<(), Box> { let value = args[2].clone(); let this_ptr = args.get_mut(0).unwrap(); - engine.call_fn_dynamic( - &mut Scope::new(), - lib, - fp.fn_name(), - Some(this_ptr), - [value], - )?; - - Ok(()) + fp.call_dynamic(engine, lib, Some(this_ptr), [value]) }, );