Revise docs.

This commit is contained in:
Stephen Chung 2020-10-12 23:17:22 +08:00
parent a0d5249c4d
commit e6667a3996
8 changed files with 46 additions and 22 deletions

View File

@ -4,6 +4,8 @@ Rhai Release Notes
Version 0.20.0 Version 0.20.0
============== ==============
This version adds a variable resolver with the ability to short-circuit variable access.
Breaking changes Breaking changes
---------------- ----------------
@ -17,6 +19,7 @@ Breaking changes
* `rhai::ser` and `rhai::de` namespaces are merged into `rhai::serde`. * `rhai::ser` and `rhai::de` namespaces are merged into `rhai::serde`.
* New reserved symbols: `++`, `--`, `..`, `...`. * New reserved symbols: `++`, `--`, `..`, `...`.
* Callback signature for custom syntax implementation function is changed to allow for more flexibility. * Callback signature for custom syntax implementation function is changed to allow for more flexibility.
* Default call stack depth for `debug` builds is reduced to 12 (from 16).
New features New features
------------ ------------
@ -24,15 +27,15 @@ New features
* New `Engine::on_var` to register a _variable resolver_. * New `Engine::on_var` to register a _variable resolver_.
* `const` statements can now take any expression (or none at all) instead of only constant values. * `const` statements can now take any expression (or none at all) instead of only constant values.
* `OptimizationLevel::Simple` now eagerly evaluates built-in binary operators of primary types (if not overloaded). * `OptimizationLevel::Simple` now eagerly evaluates built-in binary operators of primary types (if not overloaded).
* Added `is_def_var()` to detect if variable is defined, and `is_def_fn()` to detect if script function is defined. * `is_def_var()` to detect if variable is defined, and `is_def_fn()` to detect if script function is defined.
* `Dynamic::from(&str)` now constructs a `Dynamic` with a copy of the string as value. * `Dynamic::from(&str)` now constructs a `Dynamic` with a copy of the string as value.
* `AST::combine` and `AST::combine_filtered` allows combining two `AST`'s without creating a new one. * `AST::combine` and `AST::combine_filtered` allows combining two `AST`'s without creating a new one.
* `map`, `filter` and `reduce` functions for arrays.
Enhancements Enhancements
------------ ------------
* Many one-liners and few-liners are now marked `#[inline]` or `[inline(always)]`, just in case it helps when LTO is not turned on. * Many one-liners and few-liners are now marked `#[inline]` or `[inline(always)]`, just in case it helps when LTO is not turned on.
* Default call stack depth for `debug` builds is reduced to 12 (from 16).
Version 0.19.0 Version 0.19.0

View File

@ -17,6 +17,8 @@ Easy
* Very few additional dependencies - right now only [`smallvec`](https://crates.io/crates/smallvec/) plus crates for procedural macros; * Very few additional dependencies - right now only [`smallvec`](https://crates.io/crates/smallvec/) plus crates for procedural macros;
for [`no-std`] and `WASM` builds, a number of additional dependencies are pulled in to provide for missing functionalities. for [`no-std`] and `WASM` builds, a number of additional dependencies are pulled in to provide for missing functionalities.
* [Plugins] system powered by procedural macros simplifies custom API development.
Fast Fast
---- ----
@ -41,6 +43,8 @@ Dynamic
* Some support for [object-oriented programming (OOP)][OOP]. * Some support for [object-oriented programming (OOP)][OOP].
* Hook into variables access via [variable resolver].
Safe Safe
---- ----
@ -66,9 +70,6 @@ Flexible
* Supports [most build targets](targets.md) including `no-std` and [WASM]. * Supports [most build targets](targets.md) including `no-std` and [WASM].
* [Plugins] system powered by procedural macros simplifies custom API development.
* Surgically [disable keywords and operators] to restrict the language. * Surgically [disable keywords and operators] to restrict the language.
* Use as a [DSL] by [disabling keywords/operators][disable keywords and operators], [custom operators] * Use as a [DSL] by defining [custom operators] and/or extending the language with [custom syntax].
and extending the language with [custom syntax].

View File

@ -10,7 +10,7 @@ It doesn't attempt to be a new language. For example:
* No traits... so it is also not Rust. Do your Rusty stuff in Rust. * No traits... so it is also not Rust. Do your Rusty stuff in Rust.
* No structures/records - define your types in Rust instead; Rhai can seamlessly work with _any Rust type_. * No structures/records/tuples - define your types in Rust instead; Rhai can seamlessly work with _any Rust type_.
There is, however, a built-in [object map] type which is adequate for most uses. There is, however, a built-in [object map] type which is adequate for most uses.
It is possible to simulate [object-oriented programming (OOP)][OOP] by storing [function pointers] It is possible to simulate [object-oriented programming (OOP)][OOP] by storing [function pointers]
@ -32,7 +32,7 @@ It doesn't attempt to be a new language. For example:
integrate with native Rust applications. integrate with native Rust applications.
* No formal language grammar - Rhai uses a hand-coded lexer, a hand-coded top-down recursive-descent parser * No formal language grammar - Rhai uses a hand-coded lexer, a hand-coded top-down recursive-descent parser
for statements and a Pratt parser for expressions. for statements, and a hand-coded Pratt parser for expressions.
This lack of formalism allows the parser itself to be exposed as a service in order to support This lack of formalism allows the parser itself to be exposed as a service in order to support
[disabling keywords/operators][disable keywords and operators], adding [custom operators], [disabling keywords/operators][disable keywords and operators], adding [custom operators],
@ -43,8 +43,8 @@ Do Not Write The Next 4D VR Game in Rhai
--------------------------------------- ---------------------------------------
Due to this intended usage, Rhai deliberately keeps the language simple and small by omitting Due to this intended usage, Rhai deliberately keeps the language simple and small by omitting
advanced language features such as classes, inheritance, first-class functions, closures, advanced language features such as classes, inheritance, interfaces, generics,
concurrency, byte-codes VM, JIT etc. first-class functions/closures, pattern matching, concurrency, byte-codes VM, JIT etc.
Avoid the temptation to write full-fledge application logic entirely in Rhai - Avoid the temptation to write full-fledge application logic entirely in Rhai -
that use case is best fulfilled by more complete languages such as JavaScript or Lua. that use case is best fulfilled by more complete languages such as JavaScript or Lua.

View File

@ -10,7 +10,7 @@ searches the [`Scope`] that is passed into the `Engine::eval` call.
There is a built-in facility for advanced users to _hook_ into the variable There is a built-in facility for advanced users to _hook_ into the variable
resolution service and to override its default behavior. resolution service and to override its default behavior.
To do so, provide a closure to the [`Engine`] via the [`Engine::on_var`] method: To do so, provide a closure to the [`Engine`] via the `Engine::on_var` method:
```rust ```rust
let mut engine = Engine::new(); let mut engine = Engine::new();
@ -45,6 +45,18 @@ a variable resolver. Then these variables can be assigned to and their updated v
the script is evaluated. the script is evaluated.
Benefits of Using a Variable Resolver
------------------------------------
1. Avoid having to maintain a custom [`Scope`] with all variables regardless of need (because a script may not use them all).
2. _Short-circuit_ variable access, essentially overriding standard behavior.
3. _Lazy-load_ variables when they are accessed, not up-front. This benefits when the number of variables is very large, when they are timing-dependent, or when they are expensive to load.
4. Rename system variables on a script-by-script basis without having to construct different [`Scope`]'s.
Function Signature Function Signature
------------------ ------------------
@ -61,12 +73,20 @@ where:
If `index` is zero, then there is no pre-calculated offset position and a search through the current [`Scope`] must be performed. If `index` is zero, then there is no pre-calculated offset position and a search through the current [`Scope`] must be performed.
* `scope : &Scope` - reference to the current [`Scope`] containing all variables up to the current evaluation position. * `scope: &Scope` - reference to the current [`Scope`] containing all variables up to the current evaluation position.
* `context: &EvalContext` - reference to the current evaluation _context_, which exposes the following fields: * `context: &EvalContext` - reference to the current evaluation _context_, which exposes the following fields:
* `context.engine(): &Engine` - reference to the current [`Engine`]. * `context.engine(): &Engine` - reference to the current [`Engine`].
* `context.namespace(): &Module` - reference to the current _global namespace_ (as a [module]) containing all script-defined functions. * `context.namespace(): &Module` - reference to the current _global namespace_ (as a [module]) containing all script-defined functions.
* `context.call_level(): usize` - the current nesting level of function calls. * `context.call_level(): usize` - the current nesting level of function calls.
The return value is `Result<Option<Dynamic>, Box<EvalAltResult>>` where `Ok(None)` indicates that the normal ### Return Value
variable resolution process should continue.
The return value is `Result<Option<Dynamic>, Box<EvalAltResult>>` where:
* `Ok(None)` - normal variable resolution process should continue, meaning to continue searching through the [`Scope`].
* `Ok(Some(Dynamic))` - wrapped [`Dynamic`] is taken as the value of the variable, which is treated as a constant.
* `Err(Box<EvalAltResult>)` - error is reflected back to the [`Engine`].
Normally this is `EvalAltResult::ErrorVariableNotFound` to indicate that the variable does not exist, but it can be any error.

View File

@ -40,7 +40,7 @@ The following methods (mostly defined in the [`BasicArrayPackage`][packages] but
| `insert` | 1) element to insert<br/>2) position (beginning if <= 0, end if >= length) | inserts an element at a certain index | | `insert` | 1) element to insert<br/>2) position (beginning if <= 0, end if >= length) | inserts an element at a certain index |
| `pop` | _none_ | removes the last element and returns it ([`()`] if empty) | | `pop` | _none_ | removes the last element and returns it ([`()`] if empty) |
| `shift` | _none_ | removes the first element and returns it ([`()`] if empty) | | `shift` | _none_ | removes the first element and returns it ([`()`] if empty) |
| `remove` | index | removes an element at a particular index and returns it, or returns [`()`] if the index is not valid | | `remove` | index | removes an element at a particular index and returns it ([`()`] if the index is not valid) |
| `reverse` | _none_ | reverses the array | | `reverse` | _none_ | reverses the array |
| `len` method and property | _none_ | returns the number of elements | | `len` method and property | _none_ | returns the number of elements |
| `pad` | 1) target length<br/>2) element to pad | pads the array with an element to at least a specified length | | `pad` | 1) target length<br/>2) element to pad | pads the array with an element to at least a specified length |

View File

@ -35,8 +35,8 @@ Implementation
let mut engine = Engine::new(); let mut engine = Engine::new();
// Create shared data provider. // Create shared data provider.
// Assume that Provider::get(&str) -> Option<value> gets a system constant. // Assume that SystemValuesProvider::get(&str) -> Option<value> gets a value.
let provider: Arc<Provider> = get_data_provider(); let provider = Arc::new(SystemValuesProvider::new());
// Clone the shared provider // Clone the shared provider
let db = provider.clone(); let db = provider.clone();

View File

@ -5,7 +5,7 @@ Printing for Custom Types
To use custom types for [`print`] and [`debug`], or convert its value into a [string], To use custom types for [`print`] and [`debug`], or convert its value into a [string],
it is necessary that the following functions be registered (assuming the custom type it is necessary that the following functions be registered (assuming the custom type
is `T : Display + Debug`): is `T: Display + Debug`):
| Function | Signature | Typical implementation | Usage | | Function | Signature | Typical implementation | Usage |
| ----------- | ---------------------------------------------- | ---------------------------- | -------------------------------------------------------------------- | | ----------- | ---------------------------------------------- | ---------------------------- | -------------------------------------------------------------------- |

View File

@ -63,14 +63,14 @@ The function signature passed to `Engine::register_raw_fn` takes the following f
where: where:
* `T : Variant + Clone` - return type of the function. * `T: Variant + Clone` - return type of the function.
* `engine : &Engine` - the current [`Engine`], with all configurations and settings. * `engine: &Engine` - the current [`Engine`], with all configurations and settings.
* `lib : &Module` - the current global library of script-defined functions, as a [`Module`]. * `lib: &Module` - the current global library of script-defined functions, as a [`Module`].
This is sometimes useful for calling a script-defined function within the same evaluation context using [`Engine::call_fn`][`call_fn`]. This is sometimes useful for calling a script-defined function within the same evaluation context using [`Engine::call_fn`][`call_fn`].
* `args : &mut [&mut Dynamic]` - a slice containing `&mut` references to [`Dynamic`] values. * `args: &mut [&mut Dynamic]` - a slice containing `&mut` references to [`Dynamic`] values.
The slice is guaranteed to contain enough arguments _of the correct types_. The slice is guaranteed to contain enough arguments _of the correct types_.
Remember, in Rhai, all arguments _except_ the _first_ one are always passed by _value_ (i.e. cloned). Remember, in Rhai, all arguments _except_ the _first_ one are always passed by _value_ (i.e. cloned).