Refine docs.
This commit is contained in:
parent
b795ce9f45
commit
2ff3a1fde5
@ -52,7 +52,7 @@ The Rhai Scripting Language
|
|||||||
1. [Comments](language/comments.md)
|
1. [Comments](language/comments.md)
|
||||||
2. [Values and Types](language/values-and-types.md)
|
2. [Values and Types](language/values-and-types.md)
|
||||||
1. [Dynamic Values](language/dynamic.md)
|
1. [Dynamic Values](language/dynamic.md)
|
||||||
2. [type-of()](language/type-of.md)
|
2. [type_of()](language/type-of.md)
|
||||||
3. [Numbers](language/numbers.md)
|
3. [Numbers](language/numbers.md)
|
||||||
1. [Operators](language/num-op.md)
|
1. [Operators](language/num-op.md)
|
||||||
2. [Functions](language/num-fn.md)
|
2. [Functions](language/num-fn.md)
|
||||||
|
@ -69,12 +69,12 @@ For example, the following is a SQL-like syntax for some obscure DSL operation:
|
|||||||
```rust
|
```rust
|
||||||
let table = [..., ..., ..., ...];
|
let table = [..., ..., ..., ...];
|
||||||
|
|
||||||
// Syntax = calculate $ident$ $ident$ from $expr$ -> $ident$ : $expr$
|
// Syntax = calculate $ident$ ( $expr$ -> $ident$ ) => $ident$ : $expr$
|
||||||
let total = calculate sum price from table -> row : row.weight > 50;
|
let total = calculate sum(table->price) => row : row.weight > 50;
|
||||||
|
|
||||||
// Note: There is nothing special about those symbols; to make it look exactly like SQL:
|
// Note: There is nothing special about those symbols; to make it look exactly like SQL:
|
||||||
// Syntax = SELECT $ident$ ( $ident$ ) FROM $expr$ AS $ident$ WHERE $expr$
|
// Syntax = SELECT $ident$ ( $ident$ ) AS $ident$ FROM $expr$ WHERE $expr$
|
||||||
let total = SELECT sum(price) FROM table AS row WHERE row.weight > 50;
|
let total = SELECT sum(price) AS row FROM table WHERE row.weight > 50;
|
||||||
```
|
```
|
||||||
|
|
||||||
After registering this custom syntax with Rhai, it can be used anywhere inside a script as
|
After registering this custom syntax with Rhai, it can be used anywhere inside a script as
|
||||||
@ -84,9 +84,9 @@ For its evaluation, the callback function will receive the following list of inp
|
|||||||
|
|
||||||
* `inputs[0] = "sum"` - math operator
|
* `inputs[0] = "sum"` - math operator
|
||||||
* `inputs[1] = "price"` - field name
|
* `inputs[1] = "price"` - field name
|
||||||
* `inputs[2] = Expression(table)` - data source
|
* `inputs[2] = "row"` - loop variable name
|
||||||
* `inputs[3] = "row"` - loop variable name
|
* `inputs[3] = Expression(table)` - data source
|
||||||
* `inputs[4] = Expression(row.wright > 50)` - filter predicate
|
* `inputs[4] = Expression(row.wright > 50)` - filter predicate
|
||||||
|
|
||||||
Other identifiers, such as `"calculate"`, `"from"`, as well as symbols such as `->` and `:`,
|
Other identifiers, such as `"calculate"`, `"FROM"`, as well as symbols such as `->` and `:` etc.,
|
||||||
are parsed in the order defined within the custom syntax.
|
are parsed in the order defined within the custom syntax.
|
||||||
|
@ -6,8 +6,8 @@ Dynamic Values
|
|||||||
A `Dynamic` value can be _any_ type. However, under [`sync`], all types must be `Send + Sync`.
|
A `Dynamic` value can be _any_ type. However, under [`sync`], all types must be `Send + Sync`.
|
||||||
|
|
||||||
|
|
||||||
Use [`type_of()`] to Get Value Type
|
Use `type_of()` to Get Value Type
|
||||||
----------------------------------
|
--------------------------------
|
||||||
|
|
||||||
Because [`type_of()`] a `Dynamic` value returns the type of the actual value,
|
Because [`type_of()`] a `Dynamic` value returns the type of the actual value,
|
||||||
it is usually used to perform type-specific actions based on the actual value's type.
|
it is usually used to perform type-specific actions based on the actual value's type.
|
||||||
|
@ -65,17 +65,15 @@ disable `eval` by overloading it, probably with something that throws.
|
|||||||
```rust
|
```rust
|
||||||
fn eval(script) { throw "eval is evil! I refuse to run " + script }
|
fn eval(script) { throw "eval is evil! I refuse to run " + script }
|
||||||
|
|
||||||
let x = eval("40 + 2"); // 'eval' here throws "eval is evil! I refuse to run 40 + 2"
|
let x = eval("40 + 2"); // throws "eval is evil! I refuse to run 40 + 2"
|
||||||
```
|
```
|
||||||
|
|
||||||
Or overload it from Rust:
|
Or overload it from Rust:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn alt_eval(script: String) -> Result<(), Box<EvalAltResult>> {
|
engine.register_result_fn("eval", |script: String| -> Result<(), Box<EvalAltResult>> {
|
||||||
Err(format!("eval is evil! I refuse to run {}", script).into())
|
Err(format!("eval is evil! I refuse to run {}", script).into())
|
||||||
}
|
});
|
||||||
|
|
||||||
engine.register_result_fn("eval", alt_eval);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,6 +9,9 @@ is provided by the `for` ... `in` loop.
|
|||||||
Like C, `continue` can be used to skip to the next iteration, by-passing all following statements;
|
Like C, `continue` can be used to skip to the next iteration, by-passing all following statements;
|
||||||
`break` can be used to break out of the loop unconditionally.
|
`break` can be used to break out of the loop unconditionally.
|
||||||
|
|
||||||
|
To loop through a number sequence (with or without steps), use the `range` function to
|
||||||
|
return a numeric iterator.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// Iterate through string, yielding characters
|
// Iterate through string, yielding characters
|
||||||
let s = "hello, world!";
|
let s = "hello, world!";
|
||||||
|
@ -20,14 +20,15 @@ Global Variables
|
|||||||
|
|
||||||
The `export` statement, which can only be at global level, exposes selected variables as members of a module.
|
The `export` statement, which can only be at global level, exposes selected variables as members of a module.
|
||||||
|
|
||||||
Variables not exported are _private_ and hidden to the outside.
|
Variables not exported are _private_ and hidden. They are merely used to initialize the module,
|
||||||
|
but cannot be accessed from outside.
|
||||||
|
|
||||||
Everything exported from a module is **constant** (**read-only**).
|
Everything exported from a module is **constant** (**read-only**).
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// This is a module script.
|
// This is a module script.
|
||||||
|
|
||||||
let private = 123; // variable not exported - default hidden
|
let hidden = 123; // variable not exported - default hidden
|
||||||
let x = 42; // this will be exported below
|
let x = 42; // this will be exported below
|
||||||
|
|
||||||
export x; // the variable 'x' is exported under its own name
|
export x; // the variable 'x' is exported under its own name
|
||||||
@ -43,9 +44,6 @@ export x as answer; // the variable 'x' is exported under the alias 'answer'
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
[`private`] variables are used to initialize the module.
|
|
||||||
They cannot be used apart from this.
|
|
||||||
|
|
||||||
|
|
||||||
Functions
|
Functions
|
||||||
---------
|
---------
|
||||||
|
@ -10,7 +10,7 @@ Unary Operators
|
|||||||
|
|
||||||
| Operator | Description |
|
| Operator | Description |
|
||||||
| -------- | ----------- |
|
| -------- | ----------- |
|
||||||
| `+` | Plus |
|
| `+` | Positive |
|
||||||
| `-` | Negative |
|
| `-` | Negative |
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
`timestamp`'s
|
`timestamp`
|
||||||
=============
|
===========
|
||||||
|
|
||||||
{{#include ../links.md}}
|
{{#include ../links.md}}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
`type_of`
|
`type_of()`
|
||||||
=========
|
===========
|
||||||
|
|
||||||
{{#include ../links.md}}
|
{{#include ../links.md}}
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ For example, the above configuration example may be expressed by this custom syn
|
|||||||
id "hello";
|
id "hello";
|
||||||
|
|
||||||
// Add to list
|
// Add to list
|
||||||
list +"foo"
|
list + "foo";
|
||||||
|
|
||||||
// Add to map
|
// Add to map
|
||||||
map "bar" => true;
|
map "bar" => true;
|
||||||
|
@ -6,8 +6,8 @@ Object-Oriented Programming (OOP)
|
|||||||
Rhai does not have _objects_ per se, but it is possible to _simulate_ object-oriented programming.
|
Rhai does not have _objects_ per se, but it is possible to _simulate_ object-oriented programming.
|
||||||
|
|
||||||
|
|
||||||
Use [Object Maps] to Simulate OOP
|
Use Object Maps to Simulate OOP
|
||||||
--------------------------------
|
------------------------------
|
||||||
|
|
||||||
Rhai's [object maps] has [special support for OOP]({{rootUrl}}/language/object-maps-oop.md).
|
Rhai's [object maps] has [special support for OOP]({{rootUrl}}/language/object-maps-oop.md).
|
||||||
|
|
||||||
@ -22,8 +22,8 @@ a valid [function pointer] (perhaps defined via an [anonymous function] or more
|
|||||||
then the call will be dispatched to the actual function with `this` binding to the [object map] itself.
|
then the call will be dispatched to the actual function with `this` binding to the [object map] itself.
|
||||||
|
|
||||||
|
|
||||||
Use Anonymous Functions to Define Methods
|
Use Closures to Define Methods
|
||||||
----------------------------------------
|
-----------------------------
|
||||||
|
|
||||||
[Anonymous functions] or [closures] defined as values for [object map] properties take on
|
[Anonymous functions] or [closures] defined as values for [object map] properties take on
|
||||||
a syntactic shape that resembles very closely that of class methods in an OOP language.
|
a syntactic shape that resembles very closely that of class methods in an OOP language.
|
||||||
|
@ -5,9 +5,11 @@ Export a Rust Module to Rhai
|
|||||||
|
|
||||||
|
|
||||||
When applied to a Rust module, the `#[export_module]` attribute generates the necessary
|
When applied to a Rust module, the `#[export_module]` attribute generates the necessary
|
||||||
code and metadata to allow Rhai access to its public (i.e. marked `pub`) functions. This code
|
code and metadata to allow Rhai access to its public (i.e. marked `pub`) functions, constants
|
||||||
is exactly what would need to be written by hand to achieve the same goal, and is custom fit
|
and sub-modules.
|
||||||
to each exported item.
|
|
||||||
|
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.
|
||||||
|
|
||||||
This Rust module can then either be loaded into an [`Engine`] as a normal [module] or
|
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.
|
registered as a [custom package]. This is done by using the `exported_module!` macro.
|
||||||
@ -16,15 +18,19 @@ registered as a [custom package]. This is done by using the `exported_module!` m
|
|||||||
`#[export_module]` and `exported_module!`
|
`#[export_module]` and `exported_module!`
|
||||||
----------------------------------------
|
----------------------------------------
|
||||||
|
|
||||||
Apply `#[export_module]` onto a Rust module to convert all `pub` functions into Rhai plugin
|
Apply `#[export_module]` onto a Rust module to register automatically construct a Rhai [module],
|
||||||
functions.
|
which can then be loaded into an [`Engine`].
|
||||||
|
|
||||||
|
All `pub` functions become registered functions, all `pub` constants become [module] constant variables,
|
||||||
|
and all sub-modules become Rhai sub-modules.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use rhai::plugins::*; // a "prelude" import for macros
|
use rhai::plugins::*; // a "prelude" import for macros
|
||||||
|
|
||||||
#[export_module]
|
#[export_module]
|
||||||
mod my_module {
|
mod my_module {
|
||||||
// This constant will be registered as a the constant variable 'SOME_NUMBER'.
|
// This constant will be registered as the constant variable 'SOME_NUMBER'.
|
||||||
|
// Ignored when loaded as a package.
|
||||||
pub const SOME_NUMBER: i64 = 42;
|
pub const SOME_NUMBER: i64 = 42;
|
||||||
|
|
||||||
// This function will be registered as 'greet'.
|
// This function will be registered as 'greet'.
|
||||||
@ -39,14 +45,23 @@ mod my_module {
|
|||||||
pub fn increment(num: &mut i64) {
|
pub fn increment(num: &mut i64) {
|
||||||
*num += 1;
|
*num += 1;
|
||||||
}
|
}
|
||||||
// This function is NOT registered.
|
// This function is not 'pub', so NOT registered.
|
||||||
fn mystic_number() -> i64 {
|
fn mystic_number() -> i64 {
|
||||||
42
|
42
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This sub-module is ignored when loaded as a package.
|
||||||
|
pub mod my_sub_module {
|
||||||
|
// This function is ignored when loaded as a package.
|
||||||
|
// Otherwise it is a valid registered function under a sub-module.
|
||||||
|
pub fn get_info() -> String {
|
||||||
|
"hello".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
In order to load this into an [`Engine`], use the `load_package` method on the exported module:
|
The simplest way to load this into an [`Engine`] is to use the `load_package` method on the exported module:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -55,7 +70,7 @@ fn main() {
|
|||||||
// The macro call creates the Rhai 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, registering all public its contents.
|
// A module can simply be loaded, registering all public functions.
|
||||||
engine.load_package(module);
|
engine.load_package(module);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -77,9 +92,12 @@ increment(x);
|
|||||||
x == 43;
|
x == 43;
|
||||||
```
|
```
|
||||||
|
|
||||||
Registering this as a custom package is almost the same, except that a module resolver must
|
Notice that, when using a [module] as a [package], only functions registered at the _top level_
|
||||||
point to the module, rather than being loaded directly. See the [module] section for more
|
can be accessed. Variables as well as sub-modules are ignored.
|
||||||
information.
|
|
||||||
|
Using this directly as a Rhai module is almost the same, except that a [module resolver] must
|
||||||
|
be used to serve the module, and the module is loaded via `import` statements.
|
||||||
|
See the [module] section for more information.
|
||||||
|
|
||||||
|
|
||||||
Function Overloading and Operators
|
Function Overloading and Operators
|
||||||
@ -91,7 +109,8 @@ attribute to individual functions.
|
|||||||
The text string given as the `name` parameter to `#[rhai_fn]` is used to register the function with
|
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.
|
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.
|
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.
|
Operators (which require function names that are not valid for Rust) can also be registered this way.
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@ Create a Module from Rust
|
|||||||
Create via Plugin
|
Create via Plugin
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
By far the simplest way to create a [module] is via a [plugin module].
|
By far the simplest way to create a [module] is via a [plugin module]
|
||||||
|
which converts a normal Rust module into a Rhai [module] via procedural macros.
|
||||||
|
|
||||||
|
|
||||||
Create via `Module` API
|
Create via `Module` API
|
||||||
@ -21,7 +22,8 @@ For the complete `Module` API, refer to the [documentation](https://docs.rs/rhai
|
|||||||
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].
|
In order to _use_ a custom module, there must be a [module resolver], which serves the module when
|
||||||
|
loaded via `import` statements.
|
||||||
|
|
||||||
The easiest way is to use, for example, the [`StaticModuleResolver`][module resolver] to hold such
|
The easiest way is to use, for example, the [`StaticModuleResolver`][module resolver] to hold such
|
||||||
a custom module.
|
a custom module.
|
||||||
|
@ -58,16 +58,16 @@ def_package!(rhai:MyPackage:"My own personal super package", module, {
|
|||||||
Create a Custom Package from a Plugin 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
|
By far the easiest way to create a custom module is to call `rhai::plugins::combine_with_exported_module!`
|
||||||
`rhai::def_package!` which simply merges in all the functions defined within a [plugin module].
|
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.
|
In fact, this exactly is how Rhai's built-in packages, such as `BasicMathPackage`, are implemented.
|
||||||
|
|
||||||
`rhai::plugins::combine_with_exported_module!` adds all functions and constants from the
|
Because of the specific requirements of a [package], all sub-modules are _flattened_
|
||||||
[plugins][plugin module] definition into the package itself.
|
(i.e. all functions defined within sub-modules are pulled up and registered at the top level instead)
|
||||||
|
and so there will not be any sub-modules added to the package.
|
||||||
|
|
||||||
All sub-modules are _flattened_ (i.e. all functions and constants defined within sub-modules are registered
|
Variables in the [plugin module] are ignored.
|
||||||
at the top level) and so there will not be any sub-modules added to the package.
|
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
// Import necessary types and traits.
|
// Import necessary types and traits.
|
||||||
@ -81,6 +81,8 @@ use rhai::plugin::*;
|
|||||||
// Define plugin module.
|
// Define plugin module.
|
||||||
#[export_module]
|
#[export_module]
|
||||||
mod my_module {
|
mod my_module {
|
||||||
|
pub const MY_NUMBER: i64 = 42;
|
||||||
|
|
||||||
pub fn greet(name: &str) -> String {
|
pub fn greet(name: &str) -> String {
|
||||||
format!("hello, {}!", name)
|
format!("hello, {}!", name)
|
||||||
}
|
}
|
||||||
@ -107,16 +109,17 @@ def_package!(rhai:MyPackage:"My own personal super package", module, {
|
|||||||
|
|
||||||
// Merge all registered functions and constants from the plugin module into the custom package.
|
// Merge all registered functions and constants from the plugin module into the custom package.
|
||||||
//
|
//
|
||||||
// Functions in the sub-module 'my_sub_module' are flattened and registered at the top level
|
// The sub-module 'my_sub_module' is flattened and its functions registered at the top level.
|
||||||
// instead of in a sub-module.
|
|
||||||
//
|
//
|
||||||
// The text string name in the middle parameter can be anything and is reserved for future use;
|
// The text string name in the middle parameter can be anything and is reserved for future use;
|
||||||
// it is recommended to be an ID string that uniquely identifies the module.
|
// it is recommended to be an ID string that uniquely identifies the module.
|
||||||
//
|
//
|
||||||
|
// The constant variable, 'MY_NUMBER', is ignored.
|
||||||
|
//
|
||||||
// This call ends up registering three functions at the top level of the package:
|
// This call ends up registering three functions at the top level of the package:
|
||||||
// 1) greet
|
// 1) greet
|
||||||
// 2) get_num
|
// 2) get_num
|
||||||
// 3) get_sub_num (flattened from sub-module 'my_sub_module')
|
// 3) get_sub_num (pulled up from 'my_sub_module')
|
||||||
//
|
//
|
||||||
combine_with_exported_module!(module, "my-functions", my_module));
|
combine_with_exported_module!(module, "my-functions", my_module));
|
||||||
});
|
});
|
||||||
|
@ -37,7 +37,7 @@ 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
|
A package is _static_ (i.e. pre-loaded into an [`Engine`]), while a module is _dynamic_ (i.e. loaded with
|
||||||
the `import` statement).
|
the `import` statement).
|
||||||
|
|
||||||
Functions in a package are _flattened_, meaning that functions from sub-modules must be pulled up to the root level.
|
Sub-modules in a package are _flattened_, meaning that functions from them must be pulled up to the root level.
|
||||||
In other words, there can be no sub-modules in a package, and everything should reside in one, flat namespace.
|
In other words, there can be no sub-modules in a package, and everything should reside in one, flat namespace.
|
||||||
|
|
||||||
Only functions matter for a package. Constant variables registered in a package are ignored.
|
Only functions matter for a package. Constant variables registered in a package are ignored.
|
||||||
|
@ -13,23 +13,26 @@ If only a single integer type is needed in scripts - most of the time this is th
|
|||||||
lots of functions related to other integer types that will never be used. As a result, [`Engine`] creation will be faster
|
lots of functions related to other integer types that will never be used. As a result, [`Engine`] creation will be faster
|
||||||
because fewer functions need to be loaded.
|
because fewer functions need to be loaded.
|
||||||
|
|
||||||
|
The [`only_i32`] and [`only_i64`] features disable all integer types except `i32` or `i64` respectively.
|
||||||
|
|
||||||
|
|
||||||
Use Only 32-Bit Numbers
|
Use Only 32-Bit Numbers
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
If only 32-bit integers are needed - again, most of the time this is the case - using [`only_i32`] disables also `i64`.
|
If only 32-bit integers are needed - again, most of the time this is the case - turn on [`only_i32`].
|
||||||
|
Under this feature, only `i32` is supported as a built-in integer type and no others.
|
||||||
|
|
||||||
On 64-bit targets this may not gain much, but on some 32-bit targets this improves performance due to 64-bit arithmetic
|
On 64-bit targets this may not gain much, but on certain 32-bit targets this improves performance
|
||||||
requiring more CPU cycles to complete.
|
due to 64-bit arithmetic requiring more CPU cycles to complete.
|
||||||
|
|
||||||
|
|
||||||
Minimize Size of `Dynamic`
|
Minimize Size of `Dynamic`
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Turning on [`no_float`], and [`only_i32`] makes the key [`Dynamic`] data type only 8 bytes small on 32-bit targets
|
Turning on [`no_float`] and [`only_i32`] on 32-bit targets makes the critical [`Dynamic`] data type only 8 bytes long.
|
||||||
while normally it can be up to 16 bytes (e.g. on x86/x64 CPU's) in order to hold an `i64` or `f64`.
|
Normally [`Dynamic`] can be up to 16 bytes (e.g. on x86/x64 CPU's) in order to hold an `i64` or `f64`.
|
||||||
|
|
||||||
Making [`Dynamic`] small helps performance due to better cache efficiency.
|
A small [`Dynamic`] helps performance due to better cache efficiency.
|
||||||
|
|
||||||
|
|
||||||
Use `ImmutableString`
|
Use `ImmutableString`
|
||||||
@ -41,17 +44,17 @@ cloning when passing function arguments.
|
|||||||
Rhai's internal string type is `ImmutableString` (basically `Rc<String>` or `Arc<String>` depending on the [`sync`] feature).
|
Rhai's internal string type is `ImmutableString` (basically `Rc<String>` or `Arc<String>` depending on the [`sync`] feature).
|
||||||
It is cheap to clone, but expensive to modify (a new copy of the string must be made in order to change it).
|
It is cheap to clone, but expensive to modify (a new copy of the string must be made in order to change it).
|
||||||
|
|
||||||
Therefore, functions taking `String` parameters should use `ImmutableString` or `&str` (which maps to `ImmutableString`)
|
Therefore, functions taking `String` parameters should use `ImmutableString` or `&str` (both map to `ImmutableString`)
|
||||||
for the best performance with Rhai.
|
for the best performance with Rhai.
|
||||||
|
|
||||||
|
|
||||||
Disable Closures
|
Disable Closures
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
Support for [closures], including capturing shared values, adds material overhead to script evaluation.
|
Support for [closures] that capture shared variables adds material overhead to script evaluation.
|
||||||
|
|
||||||
This is because every data access must be checked whether it is a shared value, and if so, take a read
|
This is because every data access must be checked whether it is a shared value and, if so, take a read
|
||||||
or write lock before reading it.
|
lock before reading it.
|
||||||
|
|
||||||
Use [`no_closure`] to disable closure and capturing support and optimize the hot path
|
Use [`no_closure`] to disable closure and capturing support to optimize the hot path
|
||||||
because there is no need to take locks for shared data.
|
because there is no need to take locks for shared data.
|
||||||
|
@ -11,23 +11,23 @@ Notice that this deviates from Rust norm where features are _additive_.
|
|||||||
Excluding unneeded functionalities can result in smaller, faster builds as well as
|
Excluding unneeded functionalities can result in smaller, faster builds as well as
|
||||||
more control over what a script can (or cannot) do.
|
more control over what a script can (or cannot) do.
|
||||||
|
|
||||||
| Feature | Description |
|
| Feature | Additive? | Description |
|
||||||
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------------------- | :-------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `unchecked` | Disable arithmetic checking (such as over-flows and division by zero), call stack depth limit, operations count limit and modules loading limit.<br/>Beware that a bad script may panic the entire system! |
|
| `unchecked` | No | Disable arithmetic checking (such as over-flows and division by zero), call stack depth limit, operations count limit and modules loading limit.<br/>Beware that a bad script may panic the entire system! |
|
||||||
| `sync` | Restrict all values types to those that are `Send + Sync`. Under this feature, all Rhai types, including [`Engine`], [`Scope`] and [`AST`], are all `Send + Sync`. |
|
| `sync` | No | Restrict all values types to those that are `Send + Sync`. Under this feature, all Rhai types, including [`Engine`], [`Scope`] and [`AST`], are all `Send + Sync`. |
|
||||||
| `no_optimize` | Disable [script optimization]. |
|
| `no_optimize` | No | Disable [script optimization]. |
|
||||||
| `no_float` | Disable floating-point numbers and math. |
|
| `no_float` | No | Disable floating-point numbers and math. |
|
||||||
| `only_i32` | Set the system integer type to `i32` and disable all other integer types. `INT` is set to `i32`. |
|
| `only_i32` | No | Set the system integer type to `i32` and disable all other integer types. `INT` is set to `i32`. |
|
||||||
| `only_i64` | Set the system integer type to `i64` and disable all other integer types. `INT` is set to `i64`. |
|
| `only_i64` | No | Set the system integer type to `i64` and disable all other integer types. `INT` is set to `i64`. |
|
||||||
| `no_index` | Disable [arrays] and indexing features. |
|
| `no_index` | No | Disable [arrays] and indexing features. |
|
||||||
| `no_object` | Disable support for [custom types] and [object maps]. |
|
| `no_object` | No | Disable support for [custom types] and [object maps]. |
|
||||||
| `no_function` | Disable script-defined [functions]. |
|
| `no_function` | No | Disable script-defined [functions]. |
|
||||||
| `no_module` | Disable loading external [modules]. |
|
| `no_module` | No | Disable loading external [modules]. |
|
||||||
| `no_closure` | Disable [capturing][automatic currying] external variables in [anonymous functions] to simulate _closures_, or [capturing the calling scope]({{rootUrl}}/language/fn-capture.md) in function calls. |
|
| `no_closure` | No | Disable [capturing][automatic currying] external variables in [anonymous functions] to simulate _closures_, or [capturing the calling scope]({{rootUrl}}/language/fn-capture.md) in function calls. |
|
||||||
| `no_std` | Build for `no-std` (implies `no_closure`). Notice that additional dependencies will be pulled in to replace `std` features. |
|
| `no_std` | No | Build for `no-std` (implies `no_closure`). Notice that additional dependencies will be pulled in to replace `std` features. |
|
||||||
| `serde` | Enable serialization/deserialization via `serde`. Notice that the [`serde`](https://crates.io/crates/serde) crate will be pulled in together with its dependencies. |
|
| `serde` | Yes | Enable serialization/deserialization via `serde`. Notice that the [`serde`](https://crates.io/crates/serde) crate will be pulled in together with its dependencies. |
|
||||||
| `internals` | Expose internal data structures (e.g. [`AST`] nodes). Beware that Rhai internals are volatile and may change from version to version. |
|
| `internals` | Yes | Expose internal data structures (e.g. [`AST`] nodes). Beware that Rhai internals are volatile and may change from version to version. |
|
||||||
| `unicode-xid-ident` | Allow [Unicode Standard Annex #31](http://www.unicode.org/reports/tr31/) as identifiers. |
|
| `unicode-xid-ident` | No | Allow [Unicode Standard Annex #31](http://www.unicode.org/reports/tr31/) as identifiers. |
|
||||||
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
@ -57,7 +57,7 @@ This configuration is perfect for an expression parser in a 32-bit embedded syst
|
|||||||
Caveat - Features Are Not Additive
|
Caveat - Features Are Not Additive
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
Rhai features are not strictly _additive_ - i.e. they do not only add optional functionalities.
|
Most Rhai features are not strictly _additive_ - i.e. they do not only add optional functionalities.
|
||||||
|
|
||||||
In fact, most features are _subtractive_ - i.e. they _remove_ functionalities.
|
In fact, most features are _subtractive_ - i.e. they _remove_ functionalities.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user