Book updates for Plugins
This commit is contained in:
parent
91b4f8a6bc
commit
c5b2debf4a
@ -1,5 +1,5 @@
|
|||||||
Create a Plugin Function
|
Exporting a Rust Function to Rhai
|
||||||
========================
|
=================================
|
||||||
|
|
||||||
{{#include ../links.md}}
|
{{#include ../links.md}}
|
||||||
|
|
||||||
@ -13,10 +13,9 @@ Macros
|
|||||||
|
|
||||||
| Macro | Apply to | Behavior |
|
| Macro | Apply to | Behavior |
|
||||||
| ------------------------ | ------------------------------------------------------------- | --------------------------------------------------------- |
|
| ------------------------ | ------------------------------------------------------------- | --------------------------------------------------------- |
|
||||||
| `#[export_fn]` | Rust function defined in module | Export the function |
|
| `#[export_fn]` | Rust function defined in a Rust module | Export the function |
|
||||||
| `#[rhai_fn(return_raw)]` | Rust function returning `Result<Dynamic, Box<EvalAltResult>>` | Specify that this is a [fallible function] |
|
| `register_exported_fn!` | [`Engine`] instance, register name string, use path to function | Register function into an [`Engine`] under specific name |
|
||||||
| `register_exported_fn!` | [`Engine`] instance, register name, function name | Register function into the [`Engine`] under specific name |
|
| `set_exported_fn!` | [`Module`] instance, register name string, use path to function | Register function into an [`Module`] under specific name |
|
||||||
| `set_exported_fn!` | [`Module`], register name, function name | Register function into the [`Module`] under specific name |
|
|
||||||
|
|
||||||
|
|
||||||
`#[export_fn]` and `register_exported_fn!`
|
`#[export_fn]` and `register_exported_fn!`
|
||||||
|
@ -3,9 +3,11 @@ Plugins
|
|||||||
|
|
||||||
{{#include ../links.md}}
|
{{#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,
|
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 multiple functions into an [`Engine`].
|
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.
|
||||||
|
@ -1,43 +1,26 @@
|
|||||||
Create a Plugin Module
|
Exporting a Rust Module to Rhai
|
||||||
======================
|
===============================
|
||||||
|
|
||||||
{{#include ../links.md}}
|
{{#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
|
This Rust module can then either be loaded into an [`Engine`] as a normal [module] or
|
||||||
functions from all `pub` functions defined within.
|
registered as a [custom package]. This is done by using the `exported_module!` macro.
|
||||||
|
|
||||||
The resulting module can then be loaded into an [`Engine`] as a normal [module],
|
|
||||||
or as a [custom package].
|
|
||||||
|
|
||||||
|
|
||||||
Macros
|
Using`#[export_module]` and `exported_module!`
|
||||||
------
|
|
||||||
|
|
||||||
| 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<Dynamic, Box<EvalAltResult>>` | 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!`
|
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
Apply `#[export_module]` onto a standard module to convert all `pub` functions
|
Apply `#[export_module]` onto a Rust module to convert all `pub` functions into Rhai plugin
|
||||||
into Rhai plugin functions.
|
functions.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rhai::plugins::*; // import macros
|
use rhai::plugins::*; // a "prelude" import for macros
|
||||||
|
|
||||||
#[export_module]
|
#[export_module]
|
||||||
mod my_module {
|
mod my_module {
|
||||||
@ -58,22 +41,24 @@ mod my_module {
|
|||||||
42
|
42
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In order to load this into an [`Engine`], use the `load_package` method on the exported module:
|
||||||
|
|
||||||
|
```rust
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
// 'exported_module!' creates the plugin module.
|
// The macro call creates the Rhai module.
|
||||||
let module = exported_module!(my_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);
|
engine.load_package(module);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The above automatically defines a plugin module named `my_module` which can be converted into
|
The functions contained within the module definition (i.e. `greet`, `get_num` and `increment`)
|
||||||
a Rhai [module] via `exported_module!`. The functions contained within the module definition
|
are automatically registered into the [`Engine`] when `Engine::load_package` is called.
|
||||||
(i.e. `greet`, `get_num` and `increment`) are automatically registered into the [`Engine`] when
|
|
||||||
`Engine::load_package` is called.
|
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
let x = greet("world");
|
let x = greet("world");
|
||||||
@ -89,6 +74,47 @@ increment(x);
|
|||||||
x == 43;
|
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
|
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.
|
attribute, which is applied on a function level.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rhai::plugins::*; // import macros
|
use rhai::plugins::*; // a "prelude" import for macros
|
||||||
|
|
||||||
#[export_module]
|
#[export_module]
|
||||||
mod my_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
|
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.
|
have the appropriate return type.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rhai::plugins::*; // import macros
|
use rhai::plugins::*; // a "prelude" import for macros
|
||||||
|
|
||||||
#[export_module]
|
#[export_module]
|
||||||
mod my_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<Dynamic, Box<EvalAltResult>>` | Mark this as a [fallible function] |
|
||||||
|
Loading…
Reference in New Issue
Block a user