Merge branch 'master' into plugins
This commit is contained in:
commit
6475e4e20e
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
|||||||
- "--features sync"
|
- "--features sync"
|
||||||
- "--features no_optimize"
|
- "--features no_optimize"
|
||||||
- "--features no_float"
|
- "--features no_float"
|
||||||
- "--features only_i32"
|
- "--tests --features only_i32"
|
||||||
- "--features only_i64"
|
- "--features only_i64"
|
||||||
- "--features no_index"
|
- "--features no_index"
|
||||||
- "--features no_object"
|
- "--features no_object"
|
||||||
|
@ -36,6 +36,8 @@ update(array[0]); // <- 'array[0]' is an expression returning a calculated val
|
|||||||
array[0].update(); // <- call in method-call style will update 'a'
|
array[0].update(); // <- call in method-call style will update 'a'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**IMPORTANT: Rhai does NOT support normal references (i.e. `&T`) as parameters.**
|
||||||
|
|
||||||
|
|
||||||
Number of Parameters
|
Number of Parameters
|
||||||
--------------------
|
--------------------
|
||||||
@ -51,8 +53,8 @@ The following table illustrates the differences:
|
|||||||
| Rhai script | _n_ | `this` | `fn method(x, y) {}` |
|
| Rhai script | _n_ | `this` | `fn method(x, y) {}` |
|
||||||
|
|
||||||
|
|
||||||
`&mut` is Efficient (Except for `ImmutableString`)
|
`&mut` is Efficient, Except for `ImmutableString`
|
||||||
------------------------------------------------
|
-----------------------------------------------
|
||||||
|
|
||||||
Using a `&mut` first parameter is highly encouraged when using types that are expensive to clone,
|
Using a `&mut` first parameter is highly encouraged when using types that are expensive to clone,
|
||||||
even when the intention is not to mutate that argument, because it avoids cloning that argument value.
|
even when the intention is not to mutate that argument, because it avoids cloning that argument value.
|
||||||
|
@ -83,6 +83,8 @@ engine
|
|||||||
***Note**: Rhai follows the convention that methods of custom types take a `&mut` first parameter
|
***Note**: Rhai follows the convention that methods of custom types take a `&mut` first parameter
|
||||||
so that invoking methods can update the types. All other parameters in Rhai are passed by value (i.e. clones).*
|
so that invoking methods can update the types. All other parameters in Rhai are passed by value (i.e. clones).*
|
||||||
|
|
||||||
|
**IMPORTANT: Rhai does NOT support normal references (i.e. `&T`) as parameters.**
|
||||||
|
|
||||||
Use the Custom Type in Scripts
|
Use the Custom Type in Scripts
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
@ -125,8 +127,8 @@ Under [`no_object`], however, the _method_ style of function calls
|
|||||||
let result = engine.eval::<()>("let x = [1, 2, 3]; x.clear()")?;
|
let result = engine.eval::<()>("let x = [1, 2, 3]; x.clear()")?;
|
||||||
```
|
```
|
||||||
|
|
||||||
[`type_of()`]
|
`type_of()` a Custom Type
|
||||||
-------------
|
-------------------------
|
||||||
|
|
||||||
[`type_of()`] works fine with custom types and returns the name of the type.
|
[`type_of()`] works fine with custom types and returns the name of the type.
|
||||||
|
|
||||||
|
@ -42,3 +42,5 @@ let result = engine.eval::<String>(r#"let a = new_ts(); a.xyz = "42"; a.xyz"#)?;
|
|||||||
|
|
||||||
println!("Answer: {}", result); // prints 42
|
println!("Answer: {}", result); // prints 42
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**IMPORTANT: Rhai does NOT support normal references (i.e. `&T`) as parameters.**
|
||||||
|
@ -95,10 +95,11 @@ When there is a mutable reference to the `this` object (i.e. the first argument)
|
|||||||
there can be no other immutable references to `args`, otherwise the Rust borrow checker will complain.
|
there can be no other immutable references to `args`, otherwise the Rust borrow checker will complain.
|
||||||
|
|
||||||
|
|
||||||
Example - Passing a Function Pointer to a Rust Function
|
Example - Passing a Callback to a Rust Function
|
||||||
------------------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
The low-level API is useful when there is a need to interact with the scripting [`Engine`] within a function.
|
The low-level API is useful when there is a need to interact with the scripting [`Engine`]
|
||||||
|
within a function.
|
||||||
|
|
||||||
The following example registers a function that takes a [function pointer] as an argument,
|
The following example registers a function that takes a [function pointer] as an argument,
|
||||||
then calls it within the same [`Engine`]. This way, a _callback_ function can be provided
|
then calls it within the same [`Engine`]. This way, a _callback_ function can be provided
|
||||||
@ -140,6 +141,24 @@ let result = engine.eval::<i64>(r#"
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
TL;DR - Why `read_lock` and `write_lock`
|
||||||
|
---------------------------------------
|
||||||
|
|
||||||
|
The `Dynamic` API that casts it to a reference to a particular data type is `read_lock`
|
||||||
|
(for an immutable reference) and `write_lock` (for a mutable reference).
|
||||||
|
|
||||||
|
As the naming shows, something is _locked_ in order to allow this access, and that something
|
||||||
|
is a _shared value_ created by [capturing][automatic currying] variables from [closures].
|
||||||
|
|
||||||
|
Shared values are implemented as `Rc<RefCell<Dynamic>>` (`Arc<RwLock<Dynamic>>` under [`sync`]).
|
||||||
|
|
||||||
|
If the value is _not_ a shared value, or if running under [`no_closure`] where there is
|
||||||
|
no [capturing][automatic currying], this API de-sugars to a simple `downcast_ref` and `downcast_mut`.
|
||||||
|
|
||||||
|
If the value is a shared value, then it is first locked and the returned lock guard
|
||||||
|
then allows access to the underlying value in the specified type.
|
||||||
|
|
||||||
|
|
||||||
Hold Multiple References
|
Hold Multiple References
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
@ -152,9 +171,9 @@ to partition the slice:
|
|||||||
let (first, rest) = args.split_at_mut(1);
|
let (first, rest) = args.split_at_mut(1);
|
||||||
|
|
||||||
// Mutable reference to the first parameter
|
// Mutable reference to the first parameter
|
||||||
let this_ptr = first[0].write_lock::<A>().unwrap();
|
let this_ptr: &mut Dynamic = &mut *first[0].write_lock::<A>().unwrap();
|
||||||
|
|
||||||
// Immutable reference to the second value parameter
|
// Immutable reference to the second value parameter
|
||||||
// This can be mutable but there is no point because the parameter is passed by value
|
// This can be mutable but there is no point because the parameter is passed by value
|
||||||
let value_ref = rest[0].read_lock::<B>().unwrap();
|
let value_ref: &Dynamic = &*rest[0].read_lock::<B>().unwrap();
|
||||||
```
|
```
|
||||||
|
@ -136,6 +136,7 @@ pub fn from_dynamic<'de, T: Deserialize<'de>>(
|
|||||||
impl Error for Box<EvalAltResult> {
|
impl Error for Box<EvalAltResult> {
|
||||||
fn custom<T: fmt::Display>(err: T) -> Self {
|
fn custom<T: fmt::Display>(err: T) -> Self {
|
||||||
EvalAltResult::ErrorParsing(ParseErrorType::BadInput(err.to_string()), Position::none())
|
EvalAltResult::ErrorParsing(ParseErrorType::BadInput(err.to_string()), Position::none())
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,9 +85,9 @@ impl DynamicSerializer {
|
|||||||
/// assert!(value.is::<Map>());
|
/// assert!(value.is::<Map>());
|
||||||
///
|
///
|
||||||
/// let map = value.cast::<Map>();
|
/// let map = value.cast::<Map>();
|
||||||
/// let point = map.get("d").unwrap().downcast_ref::<Map>().unwrap();
|
/// let point = map["d"].read_lock::<Map>().unwrap();
|
||||||
/// assert_eq!(*point.get("x").unwrap().downcast_ref::<f64>().unwrap(), 123.456);
|
/// assert_eq!(*point["x"].read_lock::<f64>().unwrap(), 123.456);
|
||||||
/// assert_eq!(*point.get("y").unwrap().downcast_ref::<f64>().unwrap(), 999.0);
|
/// assert_eq!(*point["y"].read_lock::<f64>().unwrap(), 999.0);
|
||||||
/// # }
|
/// # }
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
@ -99,7 +99,7 @@ pub fn to_dynamic<T: Serialize>(value: T) -> Result<Dynamic, Box<EvalAltResult>>
|
|||||||
|
|
||||||
impl Error for Box<EvalAltResult> {
|
impl Error for Box<EvalAltResult> {
|
||||||
fn custom<T: fmt::Display>(err: T) -> Self {
|
fn custom<T: fmt::Display>(err: T) -> Self {
|
||||||
EvalAltResult::ErrorRuntime(err.to_string(), Position::none())
|
EvalAltResult::ErrorRuntime(err.to_string(), Position::none()).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user