2020-06-20 06:06:17 +02:00
|
|
|
`Scope` - Initializing and Maintaining State
|
2020-11-13 11:32:18 +01:00
|
|
|
=================================================
|
2020-06-20 06:06:17 +02:00
|
|
|
|
|
|
|
{{#include ../links.md}}
|
|
|
|
|
|
|
|
By default, Rhai treats each [`Engine`] invocation as a fresh one, persisting only the functions that have been defined
|
|
|
|
but no global state. This gives each evaluation a clean starting slate.
|
|
|
|
|
|
|
|
In order to continue using the same global state from one invocation to the next,
|
|
|
|
such a state must be manually created and passed in.
|
|
|
|
|
|
|
|
All `Scope` variables are [`Dynamic`], meaning they can store values of any type.
|
|
|
|
|
|
|
|
Under [`sync`], however, only types that are `Send + Sync` are supported, and the entire `Scope` itself
|
|
|
|
will also be `Send + Sync`. This is extremely useful in multi-threaded applications.
|
|
|
|
|
|
|
|
In this example, a global state object (a `Scope`) is created with a few initialized variables,
|
|
|
|
then the same state is threaded through multiple invocations:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
use rhai::{Engine, Scope, EvalAltResult};
|
|
|
|
|
2020-06-22 16:02:49 +02:00
|
|
|
let engine = Engine::new();
|
2020-06-20 06:06:17 +02:00
|
|
|
|
2020-06-22 16:02:49 +02:00
|
|
|
// First create the state
|
|
|
|
let mut scope = Scope::new();
|
2020-06-20 06:06:17 +02:00
|
|
|
|
2020-06-22 16:02:49 +02:00
|
|
|
// Then push (i.e. add) some initialized variables into the state.
|
|
|
|
// Remember the system number types in Rhai are i64 (i32 if 'only_i32') ond f64.
|
|
|
|
// Better stick to them or it gets hard working with the script.
|
2020-07-12 05:46:53 +02:00
|
|
|
scope
|
|
|
|
.push("y", 42_i64)
|
|
|
|
.push("z", 999_i64)
|
2020-09-28 16:14:19 +02:00
|
|
|
.push_constant("MY_NUMBER", 123_i64) // constants can also be added
|
2020-07-12 05:46:53 +02:00
|
|
|
.set_value("s", "hello, world!".to_string()); //'set_value' adds a variable when one doesn't exist
|
2020-09-28 16:14:19 +02:00
|
|
|
// remember to use 'String', not '&str'
|
2020-06-20 06:06:17 +02:00
|
|
|
|
2020-06-22 16:02:49 +02:00
|
|
|
// First invocation
|
|
|
|
engine.eval_with_scope::<()>(&mut scope, r"
|
2020-09-28 16:14:19 +02:00
|
|
|
let x = 4 + 5 - y + z + MY_NUMBER + s.len;
|
2020-06-22 16:02:49 +02:00
|
|
|
y = 1;
|
|
|
|
")?;
|
2020-06-20 06:06:17 +02:00
|
|
|
|
2020-06-22 16:02:49 +02:00
|
|
|
// Second invocation using the same state
|
|
|
|
let result = engine.eval_with_scope::<i64>(&mut scope, "x")?;
|
2020-06-20 06:06:17 +02:00
|
|
|
|
2020-09-28 16:14:19 +02:00
|
|
|
println!("result: {}", result); // prints 1102
|
2020-06-20 06:06:17 +02:00
|
|
|
|
2020-06-22 16:02:49 +02:00
|
|
|
// Variable y is changed in the script - read it with 'get_value'
|
|
|
|
assert_eq!(scope.get_value::<i64>("y").expect("variable y should exist"), 1);
|
2020-06-20 06:06:17 +02:00
|
|
|
|
2020-06-22 16:02:49 +02:00
|
|
|
// We can modify scope variables directly with 'set_value'
|
|
|
|
scope.set_value("y", 42_i64);
|
|
|
|
assert_eq!(scope.get_value::<i64>("y").expect("variable y should exist"), 42);
|
2020-06-20 06:06:17 +02:00
|
|
|
```
|