From c5b2debf4a7cf0b44db800ffb5f3c268975fa99e Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Mon, 31 Aug 2020 19:03:45 -0500 Subject: [PATCH] Book updates for Plugins --- doc/src/plugins/function.md | 11 ++- doc/src/plugins/index.md | 10 ++- doc/src/plugins/module.md | 155 +++++++++++++++++++----------------- 3 files changed, 92 insertions(+), 84 deletions(-) diff --git a/doc/src/plugins/function.md b/doc/src/plugins/function.md index 43af9e13..888d7220 100644 --- a/doc/src/plugins/function.md +++ b/doc/src/plugins/function.md @@ -1,5 +1,5 @@ -Create a Plugin Function -======================== +Exporting a Rust Function to Rhai +================================= {{#include ../links.md}} @@ -13,10 +13,9 @@ Macros | Macro | Apply to | Behavior | | ------------------------ | ------------------------------------------------------------- | --------------------------------------------------------- | -| `#[export_fn]` | Rust function defined in module | Export the function | -| `#[rhai_fn(return_raw)]` | Rust function returning `Result>` | Specify that this is a [fallible function] | -| `register_exported_fn!` | [`Engine`] instance, register name, function name | Register function into the [`Engine`] under specific name | -| `set_exported_fn!` | [`Module`], register name, function name | Register function into the [`Module`] under specific name | +| `#[export_fn]` | Rust function defined in a Rust module | Export the function | +| `register_exported_fn!` | [`Engine`] instance, register name string, use path to function | Register function into an [`Engine`] under specific name | +| `set_exported_fn!` | [`Module`] instance, register name string, use path to function | Register function into an [`Module`] under specific name | `#[export_fn]` and `register_exported_fn!` diff --git a/doc/src/plugins/index.md b/doc/src/plugins/index.md index 353dedd3..04fb1d35 100644 --- a/doc/src/plugins/index.md +++ b/doc/src/plugins/index.md @@ -3,9 +3,11 @@ Plugins {{#include ../links.md}} -Rhai contains a robust _plugin_ system that greatly simplifies registration of custom functions. +Rhai contains a robust _plugin_ system that greatly simplifies registration of custom +functionality. -Instead of the large `Engine::register_XXX` API, and the parallel `Module::set_fn_XXX` API, -a _plugin_ simplifies the work of creating and registering multiple functions into an [`Engine`]. +Instead of using the large `Engine::register_XXX` API or the parallel `Module::set_fn_XXX` API, +a _plugin_ simplifies the work of creating and registering new functionality in an [`Engine`]. -Plugins are processed via a set of procedural macros under the `rhai::plugins` module. +Plugins are processed via a set of procedural macros under the `rhai::plugins` module. These +allow registering Rust functions directly in the Engine, or adding Rust modules as packages. diff --git a/doc/src/plugins/module.md b/doc/src/plugins/module.md index 22380425..b26eff3d 100644 --- a/doc/src/plugins/module.md +++ b/doc/src/plugins/module.md @@ -1,43 +1,26 @@ -Create a Plugin Module -====================== +Exporting a Rust Module to Rhai +=============================== {{#include ../links.md}} -The core of creating a plugin [module] is the `#[export_module]` attribute. +When applied to a Rust module, the `#[export_module]` attribute will generate the necessary +code and metadata to allow Rhai access to its public (i.e. marked `pub`) functions. This code +is exactly what would need to be written by hand to achieve the same goal, and is custom fit +to each exported item. -When applied on a module definition, `#[export_module]` automatically generates Rhai-acceptable -functions from all `pub` functions defined within. - -The resulting module can then be loaded into an [`Engine`] as a normal [module], -or as a [custom package]. +This Rust module can then either be loaded into an [`Engine`] as a normal [module] or +registered as a [custom package]. This is done by using the `exported_module!` macro. -Macros ------- - -| Macro | Apply to | Behavior | -| --------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------- | -| `#[export_module]` | Rust module | Export all `pub` functions | -| `#[rhai_fn(skip)]` | Function in Rust module | Do not export this function | -| `#[rhai_fn(return_raw)]` | `pub` function in Rust module returning `Result>` | Specify that this is a [fallible function] | -| `#[rhai_fn(name = "...")]` | `pub` function in Rust module | Register function under specific name | -| `#[rhai_fn(get = "...")]` | `pub` function in Rust module (first parameter must be `&mut`) | Register a property getter under specific name | -| `#[rhai_fn(set = "...")]` | `pub` function in Rust module (first parameter must be `&mut`) | Register a property setter under specific name | -| `#[rhai_fn(index_get]` | `pub` function in Rust module (first parameter must be `&mut`) | Register an index getter | -| `#[rhai_fn(index_set)]` | `pub` function in Rust module (first parameter must be `&mut`) | Register an index setter | -| `#[rhai_mod(name = "...")]` | `pub` sub-module in Rust module | Export the sub-module under specific name | -| `exported_module!` | Rust module name | Create a [module] containing exported functions | - - -`#[export_module]` and `exported_module!` +Using`#[export_module]` and `exported_module!` ---------------------------------------- -Apply `#[export_module]` onto a standard module to convert all `pub` functions -into Rhai plugin functions. +Apply `#[export_module]` onto a Rust module to convert all `pub` functions into Rhai plugin +functions. ```rust -use rhai::plugins::*; // import macros +use rhai::plugins::*; // a "prelude" import for macros #[export_module] mod my_module { @@ -58,22 +41,24 @@ mod my_module { 42 } } +``` +In order to load this into an [`Engine`], use the `load_package` method on the exported module: + +```rust fn main() { let mut engine = Engine::new(); - // 'exported_module!' creates the plugin module. + // The macro call creates the Rhai module. let module = exported_module!(my_module); - // A module can simply be loaded as a custom package. + // A module can simply be loaded, registering all public its contents. engine.load_package(module); } ``` -The above automatically defines a plugin module named `my_module` which can be converted into -a Rhai [module] via `exported_module!`. The functions contained within the module definition -(i.e. `greet`, `get_num` and `increment`) are automatically registered into the [`Engine`] when -`Engine::load_package` is called. +The functions contained within the module definition (i.e. `greet`, `get_num` and `increment`) +are automatically registered into the [`Engine`] when `Engine::load_package` is called. ```rust let x = greet("world"); @@ -89,6 +74,47 @@ increment(x); x == 43; ``` +Registering this as a custom package is almost the same, except that a module resolver must +point to the module, rather than being loaded directly. See the [module] section for more +information. + + +Function Overloading and Operators +--------------------------------- + +Operators and overloaded functions can be specified via applying the `#[rhai_fn(name = "...")]` +attribute to individual functions. + +The text string given as the `name` parameter to `#[rhai_fn]` is used to register the function with +the [`Engine`], disregarding the actual name of the function. + +With `#[rhai_fn(name = "...")]`, multiple functions may be registered under the same name in Rhai, so long as they have different parameters. + +Operators (which require function names that are not valid for Rust) can also be registered this way. + +```rust +use rhai::plugins::*; // a "prelude" import for macros + +#[export_module] +mod my_module { + // This is the '+' operator for 'MyType'. + #[rhai_fn(name = "+")] + pub fn add(obj: &mut MyType, value: i64) { + obj.prop += value; + } + // This function is 'calc (i64)'. + #[rhai_fn(name = "calc")] + pub fn calc_with_default(num: i64) -> i64 { + ... + } + // This function is 'calc (i64, bool)'. + #[rhai_fn(name = "calc")] + pub fn calc_with_option(num: i64, option: bool) -> i64 { + ... + } +} +``` + Getters, Setters and Indexers ----------------------------- @@ -97,7 +123,7 @@ Functions can be marked as [getters/setters] and [indexers] for [custom types] v attribute, which is applied on a function level. ```rust -use rhai::plugins::*; // import macros +use rhai::plugins::*; // a "prelude" import for macros #[export_module] mod my_module { @@ -129,43 +155,6 @@ mod my_module { ``` -Function Overloading and Operators ---------------------------------- - -Operators and overloaded functions can be specified via `#[rhai_fn(name = "...")]` applied upon -individual functions. - -The text string given as the `name` parameter to `#[rhai_fn]` is used to register the function with -the [`Engine`], disregarding the actual name of the function. - -With `#[rhai_fn(name = "...")]`, multiple functions may be registered under the same name in Rhai. - -Operators (which require function names that are not valid for Rust) can also be registered this way. - -```rust -use rhai::plugins::*; // import macros - -#[export_module] -mod my_module { - // This is the '+' operator for 'MyType'. - #[rhai_fn(name = "+")] - pub fn add(obj: &mut MyType, value: i64) { - obj.prop += value; - } - // This function is 'calc (i64)'. - #[rhai_fn(name = "calc")] - pub fn calc_with_default(num: i64) -> i64 { - ... - } - // This function is 'calc (i64, bool)'. - #[rhai_fn(name = "calc")] - pub fn calc_with_option(num: i64, option: bool) -> i64 { - ... - } -} -``` - - Fallible Functions ------------------ @@ -176,7 +165,7 @@ A syntax error is generated if the function with `#[rhai_fn(return_raw)]` does n have the appropriate return type. ```rust -use rhai::plugins::*; // import macros +use rhai::plugins::*; // a "prelude" import for macros #[export_module] mod my_module { @@ -192,3 +181,21 @@ mod my_module { } } ``` + + +Inner Attributes +------ + +As shown above, inner attributes can be applied to inner items to tweak the export process. `#[rhai_fn]` is applied to functions, and `#[rhai_mod]` is applied to inner modules. + +Here is the complete list of parameters currently supported: + +| Attribute | Use with | Apply to | Behavior | +| ----------------------------- | ------------ | -------------------------------------------------------------------- | ----------------------------------------------- | +| `skip` | `#[rhai_fn]` `#[rhai_mod]` | Function or submodule| Do not export this item | +| `name = "..."` | `#[rhai_fn]` `#[rhai_mod]` | `pub` item | Register under the specified name | +| `get = "..."` | `#[rhai_fn]` | function with `&mut` first parameter | Register a getter for the named property | +| `set = "..."` | `#[rhai_fn]` | function with `&mut` first parameter | Register a setter for the named property | +| `index_get` | `#[rhai_fn]` | function with `&mut` first parameter | Register an index getter | +| `index_set` | `#[rhai_fn]` | function with `&mut` first parameter | Register an index setter | +| `return_raw` | `#[rhai_fn]` | function returning `Result>` | Mark this as a [fallible function] |