Refine docs.

This commit is contained in:
Stephen Chung
2020-08-07 18:40:31 +08:00
parent 0b21d80641
commit c86a979601
16 changed files with 128 additions and 53 deletions

View File

@@ -9,11 +9,11 @@ Usage Scenario
* A system where settings and configurations are complex and logic-driven.
* Where it is not possible to configure said system via standard configuration file formats such as `TOML` or `YAML`.
* Where said system is too complex to configure via standard configuration file formats such as `JSON`, `TOML` or `YAML`.
* The system configuration is complex enough that it requires a full programming language. Essentially _configuration by code_.
* The system is complex enough to require a full programming language to configure. Essentially _configuration by code_.
* Yet the configurations must be flexible, late-bound and dynamically loadable, just like a configuration file.
* Yet the configuration must be flexible, late-bound and dynamically loadable, just like a configuration file.
Key Concepts
@@ -23,6 +23,8 @@ Key Concepts
* Expose the configuration API. Use separate scripts to configure that API. Dynamically load scripts via the `import` statement.
* Leverage [function overloading] to simplify the API design.
* Since Rhai is _sand-boxed_, it cannot mutate the environment. To modify the external configuration object via an API, it must be wrapped in a `RefCell` (or `RwLock`/`Mutex` for [`sync`]) and shared to the [`Engine`].

View File

@@ -19,12 +19,26 @@ Key Concepts
* Expose a Control API.
* Since Rhai is _sand-boxed_, it cannot mutate the environment. To perform external actions via an API, the actual system must be wrapped in a `RefCell` (or `RwLock`/`Mutex` for [`sync`]) and shared to the [`Engine`].
* Leverage [function overloading] to simplify the API design.
* Since Rhai is _[sand-boxed]_, it cannot mutate the environment. To perform external actions via an API, the actual system must be wrapped in a `RefCell` (or `RwLock`/`Mutex` for [`sync`]) and shared to the [`Engine`].
Implementation
--------------
There are two broad ways for Rhai to control an external system, both of which involve
wrapping the system in a shared, interior-mutated object.
This is one way which does not involve exposing the data structures of the external system,
but only through exposing an abstract API primarily made up of functions.
Use this when the API is relatively simple and clean, and the number of functions is small enough.
For a complex API involving lots of functions, or an API that is object-based,
use the [Singleton Command Object]({{rootUrl}}/patterns/singleton.md) pattern instead.
### Functional API
Assume that a system provides the following functional API:

View File

@@ -4,6 +4,4 @@ Advanced Patterns
{{#include ../links.md}}
Use Rhai in different scenarios other than simply evaluating a user script.
These patterns are useful when Rhai needs to affect/control the external environment.
Leverage the full power and flexibility of Rhai in advanced scenarios.

View File

@@ -18,17 +18,17 @@ Rhai's [object maps] has [special support for OOP]({{rootUrl}}/language/object-m
| [Object map] properties that hold [function pointers] | methods |
When a property of an [object map] is called like a method function, and if it happens to hold
a valid [function pointer] (perhaps defined via an [anonymous function]), then the call will be
dispatched to the actual function with `this` binding to the [object map] itself.
a valid [function pointer] (perhaps defined via an [anonymous function] or more commonly as a [closure]),
then the call will be dispatched to the actual function with `this` binding to the [object map] itself.
Use Anonymous Functions to Define Methods
----------------------------------------
[Anonymous functions] defined as values for [object map] properties take on a syntactic shape
that resembles very closely that of class methods in an OOP language.
[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.
Anonymous functions can also _capture_ variables from the defining environment, which is a very
Closures also _[capture][automatic currying]_ variables from the defining environment, which is a very
common OOP pattern. Capturing is accomplished via a feature called _[automatic currying]_ and
can be turned off via the [`no_closure`] feature.
@@ -40,23 +40,22 @@ Examples
let factor = 1;
// Define the object
let obj =
#{
data: 0,
increment: |x| this.data += x, // 'this' binds to 'obj'
update: |x| this.data = x * factor, // 'this' binds to 'obj', 'factor' is captured
action: || print(this.data) // 'this' binds to 'obj'
};
let obj = #{
data: 0, // object field
increment: |x| this.data += x, // 'this' binds to 'obj'
update: |x| this.data = x * factor, // 'this' binds to 'obj', 'factor' is captured
action: || print(this.data) // 'this' binds to 'obj'
};
// Use the object
obj.increment(1);
obj.action(); // prints 1
obj.action(); // prints 1
obj.update(42);
obj.action(); // prints 42
obj.action(); // prints 42
factor = 2;
obj.update(42);
obj.action(); // prints 84
obj.action(); // prints 84
```

View File

@@ -1,5 +1,5 @@
Singleton Command Objects
========================
Singleton Command Object
=======================
{{#include ../links.md}}
@@ -21,9 +21,11 @@ Usage Scenario
Key Concepts
------------
* Expose a Command type with an API.
* Expose a Command type with an API. The [`no_object`] feature must not be on.
* Since Rhai is _sand-boxed_, it cannot mutate the environment. To perform external actions via an API, the command object type must be wrapped in a `RefCell` (or `RwLock`/`Mutex` for [`sync`]) and shared to the [`Engine`].
* Leverage [function overloading] to simplify the API design.
* Since Rhai is _[sand-boxed]_, it cannot mutate the environment. To perform external actions via an API, the command object type must be wrapped in a `RefCell` (or `RwLock`/`Mutex` for [`sync`]) and shared to the [`Engine`].
* Load each command object into a custom [`Scope`] as constant variables.
@@ -33,6 +35,18 @@ Key Concepts
Implementation
--------------
There are two broad ways for Rhai to control an external system, both of which involve
wrapping the system in a shared, interior-mutated object.
This is the other way which involves directly exposing the data structures of the external system
as a name singleton object in the scripting space.
Use this when the API is complex and clearly object-based.
For a relatively simple API that is action-based and not object-based,
use the [Control Layer]({{rootUrl}}/patterns/control.md) pattern instead.
### Functional API
Assume the following command object type: