Add writeup on plugins.

This commit is contained in:
Stephen Chung
2020-08-30 23:13:47 +08:00
parent 512951cceb
commit 4d9aad816c
9 changed files with 416 additions and 9 deletions

View File

@@ -3,13 +3,23 @@ Create a Module from Rust
{{#include ../../links.md}}
Manually creating a [`Module`] is possible via the `Module` API.
Create via Plugin
-----------------
By far the simplest way to create a [module] is via a [plugin module].
Create via `Module` API
-----------------------
Manually creating a [module] is possible via the `Module` API.
For the complete `Module` API, refer to the [documentation](https://docs.rs/rhai/{{version}}/rhai/struct.Module.html) online.
Make the Module Available to the Engine
--------------------------------------
Make the `Module` Available to the `Engine`
------------------------------------------
In order to _use_ a custom module, there must be a [module resolver].

View File

@@ -1,5 +1,5 @@
Create a Custom Package
======================
Manually Create a Custom Package
===============================
{{#include ../../links.md}}
@@ -13,7 +13,7 @@ Loading a package into an [`Engine`] is functionally equivalent to calling `Engi
on _each_ of the functions inside the package. But because packages are _shared_, loading an existing
package is _much_ cheaper than registering all the functions one by one.
The macro `rhai::def_package!` is used to create a new custom package.
The macro `rhai::def_package!` can be used to create a new custom package.
Macro Parameters
@@ -53,3 +53,48 @@ def_package!(rhai:MyPackage:"My own personal super package", module, {
});
});
```
Create a Custom Package from a Plugin Module
-------------------------------------------
By far the easiest way to create a custom module is to call `Module::merge_flatten` from within
`rhai::def_package!` which simply merges in all the functions defined within a [plugin module].
In fact, this exactly is how Rhai's built-in packages, such as `BasicMathPackage`, are implemented.
`rhai::plugins::exported_module!` generates a module from the [plugins][plugin module] definition,
and `Module::merge_flatten` consumes its, adding all its registered functions into the package itself.
```rust
// Import necessary types and traits.
use rhai::{
def_package,
packages::Package,
packages::{ArithmeticPackage, BasicArrayPackage, BasicMapPackage, LogicPackage}
};
use rhai::plugin::*;
// Define plugin module.
#[export_module]
mod my_module {
pub fn greet(name: &str) -> String {
format!("hello, {}!", name)
}
pub fn get_num() -> i64 {
42
}
}
// Define the package 'MyPackage'.
def_package!(rhai:MyPackage:"My own personal super package", module, {
// Aggregate existing packages simply by calling 'init' on each.
ArithmeticPackage::init(module);
LogicPackage::init(module);
BasicArrayPackage::init(module);
BasicMapPackage::init(module);
// Merge the plugin module into the custom package.
module.merge_flatten(exported_module!(my_module));
});
```

View File

@@ -11,7 +11,7 @@ packages to be used.
Packages typically contain Rust functions that are callable within a Rhai script.
All functions registered in a package is loaded under the _global namespace_ (i.e. they're available without module qualifiers).
Once a package is created (e.g. via `new`), it can be _shared_ (via `get`) among multiple instances of [`Engine`],
Once a package is created (e.g. via `Package::new`), it can be _shared_ (via `Package::get`) among multiple instances of [`Engine`],
even across threads (under [`sync`]). Therefore, a package only has to be created _once_.
```rust
@@ -36,3 +36,21 @@ namespace alias specified in an [`import`] statement (see also [modules]).
A package is _static_ (i.e. pre-loaded into an [`Engine`]), while a module is _dynamic_ (i.e. loaded with
the `import` statement).
Load a Module as a Package
--------------------------
Stand-alone [modules] can be loaded directly into an [`Engine`] as a package via the same `Engine::load_package` API.
```rust
let mut module = Module::new();
:
// add functions into module
:
engine.load_package(module);
```
[Modules], however, are not _shared_, so use a [custom package] if it must be shared among multiple
instances of [`Engine`].

View File

@@ -0,0 +1,41 @@
Load a Plugin Module as a Package
================================
{{#include ../../links.md}}
[Plugin modules] can be loaded as a package just like a normal [module].
```rust
use rhai::Engine;
use rhai::plugin::*;
// Define plugin module.
#[export_module]
mod my_module {
pub fn greet(name: &str) -> String {
format!("hello, {}!", name)
}
pub fn get_num() -> i64 {
42
}
}
fn main() {
let mut engine = Engine::new();
// Create plugin module.
let module = exported_module!(my_module);
// Make the 'greet' and 'get_num' functions available to scripts.
engine.load_package(module);
}
```
Share a Package Among `Engine`s
------------------------------
Loading a [module] via `Engine::load_package` consumes the module and it cannot be used again.
If the functions are needed for multiple instances of [`Engine`], create a [custom package] from the
[plugin module], which can then be shared with `Package::get`.