From 95b8dcc6231b67e74d5c465699113e03650ddd6e Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Wed, 16 Dec 2020 14:57:28 +0800 Subject: [PATCH] Update docs. --- codegen/src/test/function.rs | 6 +- doc/src/appendix/operators.md | 14 ++-- doc/src/engine/compile.md | 8 +- doc/src/engine/custom-syntax.md | 112 +++++++++++++++++++-------- doc/src/engine/raw.md | 2 +- doc/src/engine/var.md | 24 +++--- doc/src/language/constants.md | 12 ++- doc/src/language/dynamic.md | 2 +- doc/src/patterns/events.md | 30 +++---- doc/src/plugins/module.md | 22 +++--- doc/src/rust/custom.md | 4 +- doc/src/rust/modules/imp-resolver.md | 4 +- doc/src/rust/register-raw.md | 16 ++-- doc/src/safety/progress.md | 6 +- tests/closures.rs | 16 ++-- 15 files changed, 169 insertions(+), 109 deletions(-) diff --git a/codegen/src/test/function.rs b/codegen/src/test/function.rs index 7a750123..1df6e6a2 100644 --- a/codegen/src/test/function.rs +++ b/codegen/src/test/function.rs @@ -489,7 +489,7 @@ mod generate_tests { }; let expected_tokens = quote! { - impl PluginFunction for MyType { + impl PluginFunction for TestStruct { fn call(&self, context: NativeCallContext, args: &mut [&mut Dynamic]) -> Result> { debug_assert_eq!(args.len(), 1usize, "wrong arg count: {} != {}", args.len(), 1usize); @@ -499,7 +499,7 @@ mod generate_tests { fn is_method_call(&self) -> bool { false } fn is_variadic(&self) -> bool { false } - fn clone_boxed(&self) -> Box { Box::new(MyType()) } + fn clone_boxed(&self) -> Box { Box::new(TestStruct()) } fn input_names(&self) -> Box<[&'static str]> { new_vec!["x: usize"].into_boxed_slice() } @@ -513,7 +513,7 @@ mod generate_tests { }; let item_fn = syn::parse2::(input_tokens).unwrap(); - assert_streams_eq(item_fn.generate_impl("MyType"), expected_tokens); + assert_streams_eq(item_fn.generate_impl("TestStruct"), expected_tokens); } #[test] diff --git a/doc/src/appendix/operators.md b/doc/src/appendix/operators.md index 0ca26be5..71e94965 100644 --- a/doc/src/appendix/operators.md +++ b/doc/src/appendix/operators.md @@ -10,16 +10,16 @@ Operators | Operator | Description | Binary? | Binding direction | | :-----------------------------------------------------------------------------------------: | -------------------------------------- | :--------: | :---------------: | | `+` | add | yes | left | -| `-` | 1) subtract
2) negative | yes
no | left
right | +| `-` | 1) subtract
2) negative (prefix) | yes
no | left
right | | `*` | multiply | yes | left | | `/` | divide | yes | left | | `%` | modulo | yes | left | | `~` | power | yes | left | | `>>` | right bit-shift | yes | left | | `<<` | left bit-shift | yes | left | -| `&` | 1) bit-wise _And_
2) boolean _And_ | yes | left | -| \| | 1) bit-wise _Or_
2) boolean _Or_ | yes | left | -| `^` | 1) bit-wise _Xor_
2) boolean _Xor_ | yes | left | +| `&` | 1) bit-wise _AND_
2) boolean _AND_ | yes | left | +| \| | 1) bit-wise _OR_
2) boolean _OR_ | yes | left | +| `^` | 1) bit-wise _XOR_
2) boolean _XOR_ | yes | left | | `=`, `+=`, `-=`, `*=`, `/=`,
`~=`, `%=`, `<<=`, `>>=`, `&=`,
\|=, `^=` | assignments | yes | right | | `==` | equals to | yes | left | | `~=` | not equals to | yes | left | @@ -27,9 +27,9 @@ Operators | `>=` | greater than or equals to | yes | left | | `<` | less than | yes | left | | `<=` | less than or equals to | yes | left | -| `&&` | boolean _And_ (short-circuits) | yes | left | -| \|\| | boolean _Or_ (short-circuits) | yes | left | -| `!` | boolean _Not_ | no | left | +| `&&` | boolean _AND_ (short-circuits) | yes | left | +| \|\| | boolean _OR_ (short-circuits) | yes | left | +| `!` | boolean _NOT_ | no | left | | `[` .. `]` | indexing | yes | right | | `.` | 1) property access
2) method call | yes | right | diff --git a/doc/src/engine/compile.md b/doc/src/engine/compile.md index f4ee0e65..07c172c1 100644 --- a/doc/src/engine/compile.md +++ b/doc/src/engine/compile.md @@ -3,7 +3,10 @@ Compile a Script (to AST) {{#include ../links.md}} -To repeatedly evaluate a script, _compile_ it first into an `AST` (abstract syntax tree) form: +To repeatedly evaluate a script, _compile_ it first with `Engine::compile` into an `AST` +(abstract syntax tree) form. + +`Engine::eval_ast` evaluates a pre-compiled `AST`. ```rust // Compile to an AST and store it for later evaluations @@ -16,7 +19,8 @@ for _ in 0..42 { } ``` -Compiling a script file is also supported (not available under [`no_std`] or in [WASM] builds): +Compiling a script file is also supported with `Engine::compile_file` +(not available under [`no_std`] or in [WASM] builds): ```rust let ast = engine.compile_file("hello_world.rhai".into())?; diff --git a/doc/src/engine/custom-syntax.md b/doc/src/engine/custom-syntax.md index 85d385aa..876e18a3 100644 --- a/doc/src/engine/custom-syntax.md +++ b/doc/src/engine/custom-syntax.md @@ -116,16 +116,17 @@ The function signature of an implementation is: where: -| Parameter | Type | Description | -| ----------------------------- | :-----------------------------: | ------------------------------------------------------------------------------------- | -| `context` | `&mut EvalContext` | mutable reference to the current evaluation _context_ | -| - `context.scope` | `&mut Scope` | mutable reference to the current [`Scope`]; variables can be added to/removed from it | -| - `context.engine()` | `&Engine` | reference to the current [`Engine`] | -| - `context.imports()` | `&Imports` | reference to the current stack of [modules] imported via `import` statements | -| - `context.iter_namespaces()` | `impl Iterator` | iterator of the namespaces (as [modules]) containing all script-defined functions | -| - `context.this_ptr()` | `Option<&Dynamic>` | reference to the current bound [`this`] pointer, if any | -| - `context.call_level()` | `usize` | the current nesting level of function calls | -| `inputs` | `&[Expression]` | a list of input expression trees | +| Parameter | Type | Description | +| -------------------------- | :-----------------------------: | ------------------------------------------------------------------------------------- | +| `context` | `&mut EvalContext` | mutable reference to the current evaluation _context_ | +| • `scope()` | `&Scope` | reference to the current [`Scope`] | +| • `scope_mut()` | `&mut Scope` | mutable reference to the current [`Scope`]; variables can be added to/removed from it | +| • `engine()` | `&Engine` | reference to the current [`Engine`] | +| • `imports()` | `&Imports` | reference to the current stack of [modules] imported via `import` statements | +| • `iter_namespaces()` | `impl Iterator` | iterator of the namespaces (as [modules]) containing all script-defined functions | +| • `this_ptr()` | `Option<&Dynamic>` | reference to the current bound [`this`] pointer, if any | +| • `call_level()` | `usize` | the current nesting level of function calls | +| `inputs` | `&[Expression]` | a list of input expression trees | ### Return Value @@ -168,7 +169,7 @@ In other words, any [`Scope`] calls that change the list of must come _before_ a let var_name = inputs[0].get_variable_name().unwrap(); let expression = inputs.get(1).unwrap(); -context.scope.push(var_name, 0 as INT); // do this BEFORE 'context.eval_expression_tree'! +context.scope_mut().push(var_name, 0 as INT); // do this BEFORE 'context.eval_expression_tree'! let result = context.eval_expression_tree(expression)?; ``` @@ -195,7 +196,7 @@ fn implementation_func( let condition = inputs.get(2).unwrap(); // Push one new variable into the scope BEFORE 'context.eval_expression_tree' - context.scope.push(var_name, 0 as INT); + context.scope_mut().push(var_name, 0 as INT); loop { // Evaluate the statement block @@ -258,8 +259,8 @@ Step Six - Profit! ------------------ -Really Advanced - Low Level Custom Syntax API --------------------------------------------- +Really Advanced - Custom Parsers +------------------------------- Sometimes it is desirable to have multiple custom syntax starting with the same symbol. This is especially common for _command-style_ syntax where the @@ -276,30 +277,67 @@ perform add something; // Add something to the system perform remove something; // Delete something from the system ``` -For even more flexibility, there is a _low level_ API for custom syntax that -allows the registration of an entire mini-parser. +Alternatively, a custom syntax may have variable length, with a termination symbol: + +```rust +// The following is a variable-length list terminated by '>' +tags < "foo", "bar", 123, ... , x+y, true > +``` + +For even more flexibility in order to handle these advanced use cases, there is a +_low level_ API for custom syntax that allows the registration of an entire mini-parser. Use `Engine::register_custom_syntax_raw` to register a custom syntax _parser_ -together with the implementation function: +together with the implementation function. + +### How Custom Parsers Work + +A custom parser takes as input parameters two pieces of information: + +* The symbols parsed so far; `$ident$` is replaced with the actual identifier parsed, + while `$expr$` and `$block$` stay as they were. + + The custom parser can inspect this symbols stream to determine the next symbol to parse. + +* The _look-ahead_ symbol, which is the symbol that will be parsed _next_. + + If the look-ahead is an expected symbol, the customer parser just returns it to continue parsing, + or it can return `$ident$` to parse it as an identifier, or even `$expr$` to start parsing + an expression. + + If the look-ahead is '`{`', then the custom parser may also return `$block$` to start parsing a + statements block. + + If the look-ahead is unexpected, the custom parser should then return the symbol expected + and Rhai will fail with a parse error containing information about the expected symbol. + +A custom parser always returns the _next_ symbol expected, which can also be `$ident$`, +`$expr$` or `$block$`, or `None` if parsing should terminate (_without_ reading the +look-ahead symbol). + + +### Example ```rust engine.register_custom_syntax_raw( "perform", - |stream| match stream.len() { + // The custom parser implementation - always returns the next symbol expected + // 'look_ahead' is the next symbol about to be read + |symbols, look_ahead| match symbols.len() { // perform ... 1 => Ok(Some("$ident$".to_string())), // perform command ... - 2 => match stream[1].as_str() { - "action" => Ok(Some("$expr$".to_string())), - "hello" => Ok(Some("world".to_string())), - "update" | "check" | "add" | "remove" => Ok(Some("$ident$".to_string())), + 2 => match symbols[1].as_str() { + "action" => Ok(Some("$expr$".into())), + "hello" => Ok(Some("world".into())), + "update" | "check" | "add" | "remove" => Ok(Some("$ident$".into())), "cleanup" => Ok(None), cmd => Err(ParseError(Box::new(ParseErrorType::BadInput( LexError::ImproperSymbol(format!("Improper command: {}", cmd)) )), Position::NONE)), }, // perform command arg ... - 3 => match (stream[1].as_str(), stream[2].as_str()) { + 3 => match (symbols[1].as_str(), symbols[2].as_str()) { ("action", _) => Ok(None), ("hello", "world") => Ok(None), ("update", arg) if arg == "system" => Ok(None), @@ -315,7 +353,9 @@ engine.register_custom_syntax_raw( }, _ => unreachable!(), }, - 0, // the number of new variables declared within this custom syntax + // Number of new variables declared by this custom syntax + 0, + // Implementation function implementation_func ); ``` @@ -324,20 +364,24 @@ engine.register_custom_syntax_raw( The custom syntax parser has the following signature: -> `Fn(stream: &[String]) -> Result, ParseError>` +> `Fn(symbols: &[ImmutableString], look_ahead: &str) -> Result, ParseError>` where: -| Parameter | Type | Description | -| --------- | :---------: | -------------------------------------------------------------------------------------------------- | -| `stream` | `&[String]` | a slice of symbols that have been parsed so far, possibly containing `"$expr$"` and/or `"$block$"` | +| Parameter | Type | Description | +| ------------ | :------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| `symbols` | `&[ImmutableString]` | a slice of symbols that have been parsed so far, possibly containing `$expr$` and/or `$block$`; `$ident$` is replaced by the actual identifier | +| `look_ahead` | `&str` | a string slice containing the next symbol that is about to be read | + +Most strings are [`ImmutableString`][string]'s so it is usually more efficient to just `clone` the appropriate one +(if any matches, or keep an internal cache for commonly-used symbols) as the return value. ### Return Value -The return value is `Result, ParseError>` where: +The return value is `Result, ParseError>` where: -| Value | Description | -| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `Ok(None)` | parsing complete and there are no more symbols to match | -| `Ok(Some(symbol))` | next symbol to match, which can also be `"$expr$"`, `"$ident$"` or `"$block$"` | -| `Err(ParseError)` | error that is reflected back to the [`Engine`].
Normally this is `ParseError(ParseErrorType::BadInput(LexError::ImproperSymbol(message)), Position::NONE)` to indicate that there is a syntax error, but it can be any `ParseError`. | +| Value | Description | +| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Ok(None)` | parsing complete and there are no more symbols to match | +| `Ok(Some(symbol))` | the next symbol to match, which can also be `$expr$`, `$ident$` or `$block$` | +| `Err(ParseError)` | error that is reflected back to the [`Engine`] - normally `ParseError(ParseErrorType::BadInput(LexError::ImproperSymbol(message)), Position::NONE)` to indicate that there is a syntax error, but it can be any `ParseError`. | diff --git a/doc/src/engine/raw.md b/doc/src/engine/raw.md index e5add617..017814a5 100644 --- a/doc/src/engine/raw.md +++ b/doc/src/engine/raw.md @@ -17,7 +17,7 @@ To add more functionalities to a _raw_ `Engine`, load [packages] into it. Built-in Operators ------------------ -| Operators | Assignment operators | Supported for types (see [standard types]) | +| Operators | Assignment operators | Supported for types
(see [standard types]) | | ------------------------- | ---------------------------- | ----------------------------------------------------------------------------- | | `+`, | `+=` | `INT`, `FLOAT` (if not [`no_float`]), `char`, `ImmutableString` | | `-`, `*`, `/`, `%`, `~`, | `-=`, `*=`, `/=`, `%=`, `~=` | `INT`, `FLOAT` (if not [`no_float`]) | diff --git a/doc/src/engine/var.md b/doc/src/engine/var.md index f21a5754..86226b49 100644 --- a/doc/src/engine/var.md +++ b/doc/src/engine/var.md @@ -24,7 +24,7 @@ engine.on_var(|name, index, context| { EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE) )), // Silently maps 'chameleon' into 'innocent'. - "chameleon" => context.scope.get_value("innocent").map(Some).ok_or_else(|| Box::new( + "chameleon" => context.scope().get_value("innocent").map(Some).ok_or_else(|| Box::new( EvalAltResult::ErrorVariableNotFound(name.to_string(), Position::NONE) )), // Return Ok(None) to continue with the normal variable resolution process. @@ -67,17 +67,17 @@ The function signature passed to `Engine::on_var` takes the following form: where: -| Parameter | Type | Description | -| ----------------------------- | :-----------------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | `&str` | variable name | -| `index` | `usize` | an offset from the bottom of the current [`Scope`] that the variable is supposed to reside.
Offsets start from 1, with 1 meaning the last variable in the current [`Scope`]. Essentially the correct variable is at position `scope.len() - index`.
If `index` is zero, then there is no pre-calculated offset position and a search through the current [`Scope`] must be performed. | -| `context` | `&EvalContext` | reference to the current evaluation _context_ | -| - `context.scope` | `&Scope` | reference to the current [`Scope`] containing all variables up to the current evaluation position | -| - `context.engine()` | `&Engine` | reference to the current [`Engine`] | -| - `context.imports()` | `&Imports` | reference to the current stack of [modules] imported via `import` statements | -| - `context.iter_namespaces()` | `impl Iterator` | iterator of the namespaces (as [modules]) containing all script-defined functions | -| - `context.this_ptr()` | `Option<&Dynamic>` | reference to the current bound [`this`] pointer, if any | -| - `context.call_level()` | `usize` | the current nesting level of function calls | +| Parameter | Type | Description | +| -------------------------- | :-----------------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | `&str` | variable name | +| `index` | `usize` | an offset from the bottom of the current [`Scope`] that the variable is supposed to reside.
Offsets start from 1, with 1 meaning the last variable in the current [`Scope`]. Essentially the correct variable is at position `scope.len() - index`.
If `index` is zero, then there is no pre-calculated offset position and a search through the current [`Scope`] must be performed. | +| `context` | `&EvalContext` | reference to the current evaluation _context_ | +| • `scope()` | `&Scope` | reference to the current [`Scope`] | +| • `engine()` | `&Engine` | reference to the current [`Engine`] | +| • `imports()` | `&Imports` | reference to the current stack of [modules] imported via `import` statements | +| • `iter_namespaces()` | `impl Iterator` | iterator of the namespaces (as [modules]) containing all script-defined functions | +| • `this_ptr()` | `Option<&Dynamic>` | reference to the current bound [`this`] pointer, if any | +| • `call_level()` | `usize` | the current nesting level of function calls | ### Return Value diff --git a/doc/src/language/constants.md b/doc/src/language/constants.md index 3e25d5a0..edda3d4e 100644 --- a/doc/src/language/constants.md +++ b/doc/src/language/constants.md @@ -61,8 +61,8 @@ r" ``` -Constants Can be Modified via Rust ---------------------------------- +Caveat - Constants Can be Modified via Rust +------------------------------------------ A custom type stored as a constant cannot be modified via script, but _can_ be modified via a registered Rust function that takes a first `&mut` parameter - because there is no way for @@ -76,9 +76,15 @@ x.increment(); // call 'increment' defined in Rust with '&mut' first parame x == 43; // value of 'x' is changed! fn double() { - this *= 2; // function squares 'this' + this *= 2; // function doubles 'this' } +let y = 1; // 'y' is not constant and mutable + +y.double(); // double it... + +y == 2; // value of 'y' is changed as expected + x.double(); // <- error: cannot modify constant 'this' x == 43; // value of 'x' is unchanged by script diff --git a/doc/src/language/dynamic.md b/doc/src/language/dynamic.md index a89c9446..a143d519 100644 --- a/doc/src/language/dynamic.md +++ b/doc/src/language/dynamic.md @@ -15,7 +15,7 @@ it is usually used to perform type-specific actions based on the actual value's ```c let mystery = get_some_dynamic_value(); -switch mystery { +switch type_of(mystery) { "i64" => print("Hey, I got an integer here!"), "f64" => print("Hey, I got a float here!"), "string" => print("Hey, I got a string here!"), diff --git a/doc/src/patterns/events.md b/doc/src/patterns/events.md index cdea89c5..e7c5d946 100644 --- a/doc/src/patterns/events.md +++ b/doc/src/patterns/events.md @@ -134,29 +134,33 @@ impl Handler { // Say there are three events: 'start', 'end', 'update'. // In a real application you'd be handling errors... pub fn on_event(&mut self, event_name: &str, event_data: i64) -> Result<(), Error> { + let engine = &self.engine; + let scope = &mut self.scope; + let ast = &self.ast; + match event_name { // The 'start' event maps to function 'start'. // In a real application you'd be handling errors... - "start" => self.engine.call_fn(&mut self.scope, &self.ast, "start", (event_data,))?, + "start" => engine.call_fn(scope, ast, "start", (event_data,))?, // The 'end' event maps to function 'end'. // In a real application you'd be handling errors... - "end" => self.engine.call_fn(&mut self.scope, &self.ast, "end", (event_data,))?, + "end" => engine.call_fn(scope, ast, "end", (event_data,))?, // The 'update' event maps to function 'update'. // This event provides a default implementation when the scripted function // is not found. - "update" => self.engine - .call_fn(&mut self.scope, &self.ast, "update", (event_data,)) - .or_else(|err| match *err { - EvalAltResult::ErrorFunctionNotFound(fn_name, _) if fn_name == "update" => { - // Default implementation of 'update' event handler - self.scope.set_value("state2", SomeType::new(42)); - // Turn function-not-found into a success - Ok(Dynamic::UNIT) - } - _ => Err(err.into()) - })? + "update" => + engine.call_fn(scope, ast, "update", (event_data,)) + .or_else(|err| match *err { + EvalAltResult::ErrorFunctionNotFound(fn_name, _) if fn_name == "update" => { + // Default implementation of 'update' event handler + self.scope.set_value("state2", SomeType::new(42)); + // Turn function-not-found into a success + Ok(Dynamic::UNIT) + } + _ => Err(err.into()) + })? } } } diff --git a/doc/src/plugins/module.md b/doc/src/plugins/module.md index ac0c9f80..f2edc3d2 100644 --- a/doc/src/plugins/module.md +++ b/doc/src/plugins/module.md @@ -271,9 +271,9 @@ use rhai::plugin::*; // a "prelude" import for macros #[export_module] mod my_module { - // This is the '+' operator for 'MyType'. + // This is the '+' operator for 'TestStruct'. #[rhai_fn(name = "+")] - pub fn add(obj: &mut MyType, value: i64) { + pub fn add(obj: &mut TestStruct, value: i64) { obj.prop += value; } // This function is 'calc (i64)'. @@ -305,24 +305,24 @@ mod my_module { pub fn greet(name: &str) -> String { format!("hello, {}!", name) } - // This is a getter for 'MyType::prop'. + // This is a getter for 'TestStruct::prop'. #[rhai_fn(get = "prop")] - pub fn get_prop(obj: &mut MyType) -> i64 { + pub fn get_prop(obj: &mut TestStruct) -> i64 { obj.prop } - // This is a setter for 'MyType::prop'. + // This is a setter for 'TestStruct::prop'. #[rhai_fn(set = "prop")] - pub fn set_prop(obj: &mut MyType, value: i64) { + pub fn set_prop(obj: &mut TestStruct, value: i64) { obj.prop = value; } - // This is an index getter for 'MyType'. + // This is an index getter for 'TestStruct'. #[rhai_fn(index_get)] - pub fn get_index(obj: &mut MyType, index: i64) -> bool { + pub fn get_index(obj: &mut TestStruct, index: i64) -> bool { obj.list[index] } - // This is an index setter for 'MyType'. + // This is an index setter for 'TestStruct'. #[rhai_fn(index_set)] - pub fn get_index(obj: &mut MyType, index: i64, state: bool) { + pub fn get_index(obj: &mut TestStruct, index: i64, state: bool) { obj.list[index] = state; } } @@ -344,7 +344,7 @@ use rhai::plugin::*; // a "prelude" import for macros mod my_module { // This function can be called in five ways #[rhai_fn(name = "get_prop_value", name = "prop", name = "+", set = "prop", index_get)] - pub fn prop_function(obj: &mut MyType, index: i64) -> i64 { + pub fn prop_function(obj: &mut TestStruct, index: i64) -> i64 { obj.prop[index] } } diff --git a/doc/src/rust/custom.md b/doc/src/rust/custom.md index 36394e3a..1b0bec44 100644 --- a/doc/src/rust/custom.md +++ b/doc/src/rust/custom.md @@ -140,14 +140,14 @@ with a special "pretty-print" name, [`type_of()`] will return that name instead. engine .register_type::() .register_fn("new_ts1", TestStruct1::new) - .register_type_with_name::("MyType") + .register_type_with_name::("TestStruct") .register_fn("new_ts2", TestStruct2::new); let ts1_type = engine.eval::(r#"let x = new_ts1(); x.type_of()"#)?; let ts2_type = engine.eval::(r#"let x = new_ts2(); x.type_of()"#)?; println!("{}", ts1_type); // prints 'path::to::TestStruct' -println!("{}", ts1_type); // prints 'MyType' +println!("{}", ts1_type); // prints 'TestStruct' ``` diff --git a/doc/src/rust/modules/imp-resolver.md b/doc/src/rust/modules/imp-resolver.md index 32a4361e..0b8f789c 100644 --- a/doc/src/rust/modules/imp-resolver.md +++ b/doc/src/rust/modules/imp-resolver.md @@ -13,7 +13,7 @@ which contains only one function: `resolve`. When Rhai prepares to load a module, `ModuleResolver::resolve` is called with the name of the _module path_ (i.e. the path specified in the [`import`] statement). -* Upon success, it should return an [`Rc`][module] (or `Arc` under [`sync`]). +* Upon success, it should return an [`Rc`][module] (or [`Arc`][module] under [`sync`]). The module should call `Module::build_index` on the target module before returning. This method flattens the entire module tree and _indexes_ it for fast function name resolution. @@ -66,7 +66,7 @@ engine.set_module_resolver(Some(MyModuleResolver {})); engine.consume(r#" import "hello" as foo; // this 'import' statement will call - // 'MyModuleResolver::resolve' with "hello" as `path` + // 'MyModuleResolver::resolve' with "hello" as 'path' foo:bar(); "#)?; ``` diff --git a/doc/src/rust/register-raw.md b/doc/src/rust/register-raw.md index 4d326e78..78137c30 100644 --- a/doc/src/rust/register-raw.md +++ b/doc/src/rust/register-raw.md @@ -65,14 +65,14 @@ The function signature passed to `Engine::register_raw_fn` takes the following f where: -| Parameter | Type | Description | -| ----------------------------- | :-----------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `T` | `impl Clone` | return type of the function | -| `context` | `NativeCallContext` | the current _native call context_ | -| - `context.engine()` | `&Engine` | the current [`Engine`], with all configurations and settings.
This is sometimes useful for calling a script-defined function within the same evaluation context using [`Engine::call_fn`][`call_fn`], or calling a [function pointer]. | -| - `context.imports()` | `Option<&Imports>` | reference to the current stack of [modules] imported via `import` statements (if any) | -| - `context.iter_namespaces()` | `impl Iterator` | iterator of the namespaces (as [modules]) containing all script-defined functions | -| `args` | `&mut [&mut Dynamic]` | a slice containing `&mut` references to [`Dynamic`] values.
The slice is guaranteed to contain enough arguments _of the correct types_. | +| Parameter | Type | Description | +| -------------------------- | :-----------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `T` | `impl Clone` | return type of the function | +| `context` | `NativeCallContext` | the current _native call context_ | +| • `engine()` | `&Engine` | the current [`Engine`], with all configurations and settings.
This is sometimes useful for calling a script-defined function within the same evaluation context using [`Engine::call_fn`][`call_fn`], or calling a [function pointer]. | +| • `imports()` | `Option<&Imports>` | reference to the current stack of [modules] imported via `import` statements (if any) | +| • `iter_namespaces()` | `impl Iterator` | iterator of the namespaces (as [modules]) containing all script-defined functions | +| `args` | `&mut [&mut Dynamic]` | a slice containing `&mut` references to [`Dynamic`] values.
The slice is guaranteed to contain enough arguments _of the correct types_. | ### Return value diff --git a/doc/src/safety/progress.md b/doc/src/safety/progress.md index ff294976..749ac95b 100644 --- a/doc/src/safety/progress.md +++ b/doc/src/safety/progress.md @@ -46,5 +46,7 @@ Operations Count vs. Progress Percentage Notice that the _operations count_ value passed into the closure does not indicate the _percentage_ of work already done by the script (and thus it is not real _progress_ tracking), because it is impossible to determine -how long a script may run. It is possible, however, to calculate this percentage based on an estimated -total number of operations for a typical run. +how long a script may run. + +It is possible, however, to calculate this percentage based on an estimated total number of operations +for a typical run. diff --git a/tests/closures.rs b/tests/closures.rs index fd5f6c56..aa3db7f4 100644 --- a/tests/closures.rs +++ b/tests/closures.rs @@ -195,7 +195,7 @@ fn test_closures_data_race() -> Result<(), Box> { Ok(()) } -type MyType = Rc>; +type TestStruct = Rc>; #[test] #[cfg(not(feature = "no_object"))] @@ -203,18 +203,18 @@ type MyType = Rc>; fn test_closures_shared_obj() -> Result<(), Box> { let mut engine = Engine::new(); - // Register API on MyType + // Register API on TestStruct engine - .register_type_with_name::("MyType") + .register_type_with_name::("TestStruct") .register_get_set( "data", - |p: &mut MyType| *p.borrow(), - |p: &mut MyType, value: INT| *p.borrow_mut() = value, + |p: &mut TestStruct| *p.borrow(), + |p: &mut TestStruct, value: INT| *p.borrow_mut() = value, ) - .register_fn("+=", |p1: &mut MyType, p2: MyType| { + .register_fn("+=", |p1: &mut TestStruct, p2: TestStruct| { *p1.borrow_mut() += *p2.borrow() }) - .register_fn("-=", |p1: &mut MyType, p2: MyType| { + .register_fn("-=", |p1: &mut TestStruct, p2: TestStruct| { *p1.borrow_mut() -= *p2.borrow() }); @@ -234,7 +234,7 @@ fn test_closures_shared_obj() -> Result<(), Box> { let res = engine.eval_ast::(&ast)?; // Make closure - let f = move |p1: MyType, p2: MyType| -> Result<(), Box> { + let f = move |p1: TestStruct, p2: TestStruct| -> Result<(), Box> { let action_ptr = res["action"].clone().cast::(); let name = action_ptr.fn_name(); engine.call_fn::<_, ()>(&mut Scope::new(), &ast, name, (p1, p2))