reorganize module
This commit is contained in:
		
							
								
								
									
										176
									
								
								_archive/rhai_engine/rhaiexamples/LICENSE-APACHE.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								_archive/rhai_engine/rhaiexamples/LICENSE-APACHE.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,176 @@
 | 
			
		||||
                                 Apache License
 | 
			
		||||
                           Version 2.0, January 2004
 | 
			
		||||
                        http://www.apache.org/licenses/
 | 
			
		||||
 | 
			
		||||
   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 | 
			
		||||
 | 
			
		||||
   1. Definitions.
 | 
			
		||||
 | 
			
		||||
      "License" shall mean the terms and conditions for use, reproduction,
 | 
			
		||||
      and distribution as defined by Sections 1 through 9 of this document.
 | 
			
		||||
 | 
			
		||||
      "Licensor" shall mean the copyright owner or entity authorized by
 | 
			
		||||
      the copyright owner that is granting the License.
 | 
			
		||||
 | 
			
		||||
      "Legal Entity" shall mean the union of the acting entity and all
 | 
			
		||||
      other entities that control, are controlled by, or are under common
 | 
			
		||||
      control with that entity. For the purposes of this definition,
 | 
			
		||||
      "control" means (i) the power, direct or indirect, to cause the
 | 
			
		||||
      direction or management of such entity, whether by contract or
 | 
			
		||||
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
 | 
			
		||||
      outstanding shares, or (iii) beneficial ownership of such entity.
 | 
			
		||||
 | 
			
		||||
      "You" (or "Your") shall mean an individual or Legal Entity
 | 
			
		||||
      exercising permissions granted by this License.
 | 
			
		||||
 | 
			
		||||
      "Source" form shall mean the preferred form for making modifications,
 | 
			
		||||
      including but not limited to software source code, documentation
 | 
			
		||||
      source, and configuration files.
 | 
			
		||||
 | 
			
		||||
      "Object" form shall mean any form resulting from mechanical
 | 
			
		||||
      transformation or translation of a Source form, including but
 | 
			
		||||
      not limited to compiled object code, generated documentation,
 | 
			
		||||
      and conversions to other media types.
 | 
			
		||||
 | 
			
		||||
      "Work" shall mean the work of authorship, whether in Source or
 | 
			
		||||
      Object form, made available under the License, as indicated by a
 | 
			
		||||
      copyright notice that is included in or attached to the work
 | 
			
		||||
      (an example is provided in the Appendix below).
 | 
			
		||||
 | 
			
		||||
      "Derivative Works" shall mean any work, whether in Source or Object
 | 
			
		||||
      form, that is based on (or derived from) the Work and for which the
 | 
			
		||||
      editorial revisions, annotations, elaborations, or other modifications
 | 
			
		||||
      represent, as a whole, an original work of authorship. For the purposes
 | 
			
		||||
      of this License, Derivative Works shall not include works that remain
 | 
			
		||||
      separable from, or merely link (or bind by name) to the interfaces of,
 | 
			
		||||
      the Work and Derivative Works thereof.
 | 
			
		||||
 | 
			
		||||
      "Contribution" shall mean any work of authorship, including
 | 
			
		||||
      the original version of the Work and any modifications or additions
 | 
			
		||||
      to that Work or Derivative Works thereof, that is intentionally
 | 
			
		||||
      submitted to Licensor for inclusion in the Work by the copyright owner
 | 
			
		||||
      or by an individual or Legal Entity authorized to submit on behalf of
 | 
			
		||||
      the copyright owner. For the purposes of this definition, "submitted"
 | 
			
		||||
      means any form of electronic, verbal, or written communication sent
 | 
			
		||||
      to the Licensor or its representatives, including but not limited to
 | 
			
		||||
      communication on electronic mailing lists, source code control systems,
 | 
			
		||||
      and issue tracking systems that are managed by, or on behalf of, the
 | 
			
		||||
      Licensor for the purpose of discussing and improving the Work, but
 | 
			
		||||
      excluding communication that is conspicuously marked or otherwise
 | 
			
		||||
      designated in writing by the copyright owner as "Not a Contribution."
 | 
			
		||||
 | 
			
		||||
      "Contributor" shall mean Licensor and any individual or Legal Entity
 | 
			
		||||
      on behalf of whom a Contribution has been received by Licensor and
 | 
			
		||||
      subsequently incorporated within the Work.
 | 
			
		||||
 | 
			
		||||
   2. Grant of Copyright License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      copyright license to reproduce, prepare Derivative Works of,
 | 
			
		||||
      publicly display, publicly perform, sublicense, and distribute the
 | 
			
		||||
      Work and such Derivative Works in Source or Object form.
 | 
			
		||||
 | 
			
		||||
   3. Grant of Patent License. Subject to the terms and conditions of
 | 
			
		||||
      this License, each Contributor hereby grants to You a perpetual,
 | 
			
		||||
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 | 
			
		||||
      (except as stated in this section) patent license to make, have made,
 | 
			
		||||
      use, offer to sell, sell, import, and otherwise transfer the Work,
 | 
			
		||||
      where such license applies only to those patent claims licensable
 | 
			
		||||
      by such Contributor that are necessarily infringed by their
 | 
			
		||||
      Contribution(s) alone or by combination of their Contribution(s)
 | 
			
		||||
      with the Work to which such Contribution(s) was submitted. If You
 | 
			
		||||
      institute patent litigation against any entity (including a
 | 
			
		||||
      cross-claim or counterclaim in a lawsuit) alleging that the Work
 | 
			
		||||
      or a Contribution incorporated within the Work constitutes direct
 | 
			
		||||
      or contributory patent infringement, then any patent licenses
 | 
			
		||||
      granted to You under this License for that Work shall terminate
 | 
			
		||||
      as of the date such litigation is filed.
 | 
			
		||||
 | 
			
		||||
   4. Redistribution. You may reproduce and distribute copies of the
 | 
			
		||||
      Work or Derivative Works thereof in any medium, with or without
 | 
			
		||||
      modifications, and in Source or Object form, provided that You
 | 
			
		||||
      meet the following conditions:
 | 
			
		||||
 | 
			
		||||
      (a) You must give any other recipients of the Work or
 | 
			
		||||
          Derivative Works a copy of this License; and
 | 
			
		||||
 | 
			
		||||
      (b) You must cause any modified files to carry prominent notices
 | 
			
		||||
          stating that You changed the files; and
 | 
			
		||||
 | 
			
		||||
      (c) You must retain, in the Source form of any Derivative Works
 | 
			
		||||
          that You distribute, all copyright, patent, trademark, and
 | 
			
		||||
          attribution notices from the Source form of the Work,
 | 
			
		||||
          excluding those notices that do not pertain to any part of
 | 
			
		||||
          the Derivative Works; and
 | 
			
		||||
 | 
			
		||||
      (d) If the Work includes a "NOTICE" text file as part of its
 | 
			
		||||
          distribution, then any Derivative Works that You distribute must
 | 
			
		||||
          include a readable copy of the attribution notices contained
 | 
			
		||||
          within such NOTICE file, excluding those notices that do not
 | 
			
		||||
          pertain to any part of the Derivative Works, in at least one
 | 
			
		||||
          of the following places: within a NOTICE text file distributed
 | 
			
		||||
          as part of the Derivative Works; within the Source form or
 | 
			
		||||
          documentation, if provided along with the Derivative Works; or,
 | 
			
		||||
          within a display generated by the Derivative Works, if and
 | 
			
		||||
          wherever such third-party notices normally appear. The contents
 | 
			
		||||
          of the NOTICE file are for informational purposes only and
 | 
			
		||||
          do not modify the License. You may add Your own attribution
 | 
			
		||||
          notices within Derivative Works that You distribute, alongside
 | 
			
		||||
          or as an addendum to the NOTICE text from the Work, provided
 | 
			
		||||
          that such additional attribution notices cannot be construed
 | 
			
		||||
          as modifying the License.
 | 
			
		||||
 | 
			
		||||
      You may add Your own copyright statement to Your modifications and
 | 
			
		||||
      may provide additional or different license terms and conditions
 | 
			
		||||
      for use, reproduction, or distribution of Your modifications, or
 | 
			
		||||
      for any such Derivative Works as a whole, provided Your use,
 | 
			
		||||
      reproduction, and distribution of the Work otherwise complies with
 | 
			
		||||
      the conditions stated in this License.
 | 
			
		||||
 | 
			
		||||
   5. Submission of Contributions. Unless You explicitly state otherwise,
 | 
			
		||||
      any Contribution intentionally submitted for inclusion in the Work
 | 
			
		||||
      by You to the Licensor shall be under the terms and conditions of
 | 
			
		||||
      this License, without any additional terms or conditions.
 | 
			
		||||
      Notwithstanding the above, nothing herein shall supersede or modify
 | 
			
		||||
      the terms of any separate license agreement you may have executed
 | 
			
		||||
      with Licensor regarding such Contributions.
 | 
			
		||||
 | 
			
		||||
   6. Trademarks. This License does not grant permission to use the trade
 | 
			
		||||
      names, trademarks, service marks, or product names of the Licensor,
 | 
			
		||||
      except as required for reasonable and customary use in describing the
 | 
			
		||||
      origin of the Work and reproducing the content of the NOTICE file.
 | 
			
		||||
 | 
			
		||||
   7. Disclaimer of Warranty. Unless required by applicable law or
 | 
			
		||||
      agreed to in writing, Licensor provides the Work (and each
 | 
			
		||||
      Contributor provides its Contributions) on an "AS IS" BASIS,
 | 
			
		||||
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 | 
			
		||||
      implied, including, without limitation, any warranties or conditions
 | 
			
		||||
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 | 
			
		||||
      PARTICULAR PURPOSE. You are solely responsible for determining the
 | 
			
		||||
      appropriateness of using or redistributing the Work and assume any
 | 
			
		||||
      risks associated with Your exercise of permissions under this License.
 | 
			
		||||
 | 
			
		||||
   8. Limitation of Liability. In no event and under no legal theory,
 | 
			
		||||
      whether in tort (including negligence), contract, or otherwise,
 | 
			
		||||
      unless required by applicable law (such as deliberate and grossly
 | 
			
		||||
      negligent acts) or agreed to in writing, shall any Contributor be
 | 
			
		||||
      liable to You for damages, including any direct, indirect, special,
 | 
			
		||||
      incidental, or consequential damages of any character arising as a
 | 
			
		||||
      result of this License or out of the use or inability to use the
 | 
			
		||||
      Work (including but not limited to damages for loss of goodwill,
 | 
			
		||||
      work stoppage, computer failure or malfunction, or any and all
 | 
			
		||||
      other commercial damages or losses), even if such Contributor
 | 
			
		||||
      has been advised of the possibility of such damages.
 | 
			
		||||
 | 
			
		||||
   9. Accepting Warranty or Additional Liability. While redistributing
 | 
			
		||||
      the Work or Derivative Works thereof, You may choose to offer,
 | 
			
		||||
      and charge a fee for, acceptance of support, warranty, indemnity,
 | 
			
		||||
      or other liability obligations and/or rights consistent with this
 | 
			
		||||
      License. However, in accepting such obligations, You may act only
 | 
			
		||||
      on Your own behalf and on Your sole responsibility, not on behalf
 | 
			
		||||
      of any other Contributor, and only if You agree to indemnify,
 | 
			
		||||
      defend, and hold each Contributor harmless for any liability
 | 
			
		||||
      incurred by, or claims asserted against, such Contributor by reason
 | 
			
		||||
      of your accepting any such warranty or additional liability.
 | 
			
		||||
 | 
			
		||||
   END OF TERMS AND CONDITIONS
 | 
			
		||||
							
								
								
									
										23
									
								
								_archive/rhai_engine/rhaiexamples/LICENSE-MIT.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								_archive/rhai_engine/rhaiexamples/LICENSE-MIT.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
Permission is hereby granted, free of charge, to any
 | 
			
		||||
person obtaining a copy of this software and associated
 | 
			
		||||
documentation files (the "Software"), to deal in the
 | 
			
		||||
Software without restriction, including without
 | 
			
		||||
limitation the rights to use, copy, modify, merge,
 | 
			
		||||
publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
the Software, and to permit persons to whom the Software
 | 
			
		||||
is furnished to do so, subject to the following
 | 
			
		||||
conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice
 | 
			
		||||
shall be included in all copies or substantial portions
 | 
			
		||||
of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
 | 
			
		||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 | 
			
		||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 | 
			
		||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
 | 
			
		||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 | 
			
		||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 | 
			
		||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 | 
			
		||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 | 
			
		||||
DEALINGS IN THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										37
									
								
								_archive/rhai_engine/rhaiexamples/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								_archive/rhai_engine/rhaiexamples/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
# Sample Applications
 | 
			
		||||
 | 
			
		||||
## Standard Examples
 | 
			
		||||
 | 
			
		||||
| Example                                                   | Description                                                                                                                                         |
 | 
			
		||||
| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
 | 
			
		||||
| [`arrays_and_structs`](arrays_and_structs.rs)             | shows how to register a Rust type and using it with arrays                                                                                          |
 | 
			
		||||
| [`callback`](callback.rs)                                 | shows how to store a Rhai closure and call it later within Rust                                                                                     |
 | 
			
		||||
| [`custom_types_and_methods`](custom_types_and_methods.rs) | shows how to register a Rust type and methods/getters/setters for it                                                                                |
 | 
			
		||||
| [`custom_types`](custom_types.rs)                         | shows how to register a Rust type and methods/getters/setters using the `CustomType` trait.                                                         |
 | 
			
		||||
| [`definitions`](./definitions)                            | shows how to generate definition files for use with the [Rhai Language Server](https://github.com/rhaiscript/lsp) (requires the `metadata` feature) |
 | 
			
		||||
| [`hello`](hello.rs)                                       | simple example that evaluates an expression and prints the result                                                                                   |
 | 
			
		||||
| [`pause_and_resume`](pause_and_resume.rs)                 | shows how to pause/resume/stop an `Engine` running in a separate thread via an MPSC channel                                                         |
 | 
			
		||||
| [`reuse_scope`](reuse_scope.rs)                           | evaluates two pieces of code in separate runs, but using a common `Scope`                                                                           |
 | 
			
		||||
| [`serde`](serde.rs)                                       | example to serialize and deserialize Rust types with [`serde`](https://crates.io/crates/serde) (requires the `serde` feature)                       |
 | 
			
		||||
| [`simple_fn`](simple_fn.rs)                               | shows how to register a simple Rust function                                                                                                        |
 | 
			
		||||
| [`strings`](strings.rs)                                   | shows different ways to register Rust functions taking string arguments                                                                             |
 | 
			
		||||
| [`threading`](threading.rs)                               | shows how to communicate in duplex with an `Engine` running in a separate thread via a pair of MPSC channels                                        |
 | 
			
		||||
 | 
			
		||||
## Scriptable Event Handler With State Examples
 | 
			
		||||
 | 
			
		||||
Because of its popularity, included are sample implementations for the pattern
 | 
			
		||||
[_Scriptable Event Handler With State_](https://rhai.rs/book/patterns/events.html) in different styles.
 | 
			
		||||
 | 
			
		||||
| Example                                    | Handler Script                                                     |                         Description                         |
 | 
			
		||||
| ------------------------------------------ | ------------------------------------------------------------------ | :---------------------------------------------------------: |
 | 
			
		||||
| [`event_handler_main`](event_handler_main) | [`event_handler_main/script.rhai`](event_handler_main/script.rhai) | [_Main Style_](https://rhai.rs/book/patterns/events-1.html) |
 | 
			
		||||
| [`event_handler_js`](event_handler_js)     | [`event_handler_js/script.rhai`](event_handler_js/script.rhai)     |  [_JS Style_](https://rhai.rs/book/patterns/events-2.html)  |
 | 
			
		||||
| [`event_handler_map`](event_handler_map)   | [`event_handler_map/script.rhai`](event_handler_map/script.rhai)   | [_Map Style_](https://rhai.rs/book/patterns/events-3.html)  |
 | 
			
		||||
 | 
			
		||||
## Running Examples
 | 
			
		||||
 | 
			
		||||
Examples can be run with the following command:
 | 
			
		||||
 | 
			
		||||
```sh
 | 
			
		||||
cargo run --example {example_name}
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										67
									
								
								_archive/rhai_engine/rhaiexamples/arrays_and_structs.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								_archive/rhai_engine/rhaiexamples/arrays_and_structs.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
//! An example showing how to register a Rust type and use it with arrays.
 | 
			
		||||
 | 
			
		||||
#[cfg(any(feature = "no_index", feature = "no_object"))]
 | 
			
		||||
fn main() {
 | 
			
		||||
    panic!("This example does not run under 'no_index' or 'no_object'.")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
use rhai::{Engine, EvalAltResult};
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "no_index"))]
 | 
			
		||||
#[cfg(not(feature = "no_object"))]
 | 
			
		||||
fn main() -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
    #[derive(Debug, Clone)]
 | 
			
		||||
    struct TestStruct {
 | 
			
		||||
        x: i64,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl TestStruct {
 | 
			
		||||
        pub fn new() -> Self {
 | 
			
		||||
            Self { x: 1 }
 | 
			
		||||
        }
 | 
			
		||||
        pub fn update(&mut self) {
 | 
			
		||||
            self.x += 1000;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let mut engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
    engine
 | 
			
		||||
        .register_type_with_name::<TestStruct>("TestStruct")
 | 
			
		||||
        .register_fn("new_ts", TestStruct::new)
 | 
			
		||||
        .register_fn("update", TestStruct::update);
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "metadata")]
 | 
			
		||||
    {
 | 
			
		||||
        println!("Functions registered:");
 | 
			
		||||
 | 
			
		||||
        engine
 | 
			
		||||
            .gen_fn_signatures(false)
 | 
			
		||||
            .into_iter()
 | 
			
		||||
            .for_each(|func| println!("{func}"));
 | 
			
		||||
 | 
			
		||||
        println!();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result = engine.eval::<TestStruct>(
 | 
			
		||||
        "
 | 
			
		||||
            let x = new_ts();
 | 
			
		||||
            x.update();
 | 
			
		||||
            x
 | 
			
		||||
        ",
 | 
			
		||||
    )?;
 | 
			
		||||
 | 
			
		||||
    println!("{result:?}");
 | 
			
		||||
 | 
			
		||||
    let result = engine.eval::<TestStruct>(
 | 
			
		||||
        "
 | 
			
		||||
            let x = [ new_ts() ];
 | 
			
		||||
            x[0].update();
 | 
			
		||||
            x[0]
 | 
			
		||||
        ",
 | 
			
		||||
    )?;
 | 
			
		||||
 | 
			
		||||
    println!("{result:?}");
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								_archive/rhai_engine/rhaiexamples/callback.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								_archive/rhai_engine/rhaiexamples/callback.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
//! This example stores a Rhai closure for later use as a callback.
 | 
			
		||||
 | 
			
		||||
use rhai::{Engine, EvalAltResult, FnPtr};
 | 
			
		||||
 | 
			
		||||
// To call a Rhai closure at a later time, you'd need three things:
 | 
			
		||||
// 1) an `Engine` (with all needed functions registered),
 | 
			
		||||
// 2) a compiled `AST`,
 | 
			
		||||
// 3) the closure (of type `FnPtr`).
 | 
			
		||||
fn main() -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
    let engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
    // This script creates a closure which captures a variable and returns it.
 | 
			
		||||
    let ast = engine.compile(
 | 
			
		||||
        "
 | 
			
		||||
            let x = 18;
 | 
			
		||||
 | 
			
		||||
            // The following closure captures 'x'
 | 
			
		||||
            return |a, b| {
 | 
			
		||||
                x += 1;         // x is incremented each time
 | 
			
		||||
                (x + a) * b
 | 
			
		||||
            };
 | 
			
		||||
        ",
 | 
			
		||||
    )?;
 | 
			
		||||
 | 
			
		||||
    let closure = engine.eval_ast::<FnPtr>(&ast)?;
 | 
			
		||||
 | 
			
		||||
    // Create a closure by encapsulating the `Engine`, `AST` and `FnPtr`.
 | 
			
		||||
    // In a real application, you'd be handling errors.
 | 
			
		||||
    let func = move |x: i64, y: i64| -> i64 { closure.call(&engine, &ast, (x, y)).unwrap() };
 | 
			
		||||
 | 
			
		||||
    // Now we can call `func` anywhere just like a normal function!
 | 
			
		||||
    let r1 = func(1, 2);
 | 
			
		||||
 | 
			
		||||
    // Notice that each call to `func` returns a different value
 | 
			
		||||
    // because the captured `x` is always changing!
 | 
			
		||||
    let r2 = func(1, 2);
 | 
			
		||||
    let r3 = func(1, 2);
 | 
			
		||||
 | 
			
		||||
    println!("The Answers: {r1}, {r2}, {r3}"); // prints 40, 42, 44
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										85
									
								
								_archive/rhai_engine/rhaiexamples/custom_types.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								_archive/rhai_engine/rhaiexamples/custom_types.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
//! An example showing how to register a Rust type and methods/getters/setters using the `CustomType` trait.
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "no_object")]
 | 
			
		||||
fn main() {
 | 
			
		||||
    panic!("This example does not run under 'no_object'.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
use rhai::{CustomType, Engine, EvalAltResult, TypeBuilder};
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "no_object"))]
 | 
			
		||||
fn main() -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
    #[derive(Debug, Clone, CustomType)]
 | 
			
		||||
    #[rhai_type(extra = Self::build_extra)]
 | 
			
		||||
    struct TestStruct {
 | 
			
		||||
        x: i64,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl TestStruct {
 | 
			
		||||
        pub fn new() -> Self {
 | 
			
		||||
            Self { x: 1 }
 | 
			
		||||
        }
 | 
			
		||||
        pub fn update(&mut self) {
 | 
			
		||||
            self.x += 1000;
 | 
			
		||||
        }
 | 
			
		||||
        pub fn calculate(&mut self, data: i64) -> i64 {
 | 
			
		||||
            self.x * data
 | 
			
		||||
        }
 | 
			
		||||
        fn build_extra(builder: &mut TypeBuilder<Self>) {
 | 
			
		||||
            builder
 | 
			
		||||
                .with_name("TestStruct")
 | 
			
		||||
                .with_fn("new_ts", Self::new)
 | 
			
		||||
                .with_fn("update", Self::update)
 | 
			
		||||
                .with_fn("calc", Self::calculate)
 | 
			
		||||
                .is_iterable();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl IntoIterator for TestStruct {
 | 
			
		||||
        type Item = i64;
 | 
			
		||||
        type IntoIter = std::vec::IntoIter<Self::Item>;
 | 
			
		||||
 | 
			
		||||
        #[inline]
 | 
			
		||||
        #[must_use]
 | 
			
		||||
        fn into_iter(self) -> Self::IntoIter {
 | 
			
		||||
            vec![self.x - 1, self.x, self.x + 1].into_iter()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let mut engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
    engine.build_type::<TestStruct>();
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "metadata")]
 | 
			
		||||
    {
 | 
			
		||||
        println!("Functions registered:");
 | 
			
		||||
 | 
			
		||||
        engine
 | 
			
		||||
            .gen_fn_signatures(false)
 | 
			
		||||
            .into_iter()
 | 
			
		||||
            .for_each(|func| println!("{func}"));
 | 
			
		||||
 | 
			
		||||
        println!();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result = engine.eval::<i64>(
 | 
			
		||||
        "
 | 
			
		||||
            let x = new_ts();
 | 
			
		||||
 | 
			
		||||
            x.x = 42;
 | 
			
		||||
 | 
			
		||||
            for n in x {
 | 
			
		||||
                x.x += n;
 | 
			
		||||
                print(`n = ${n}, total = ${x.x}`);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            x.update();
 | 
			
		||||
 | 
			
		||||
            x.calc(x.x)
 | 
			
		||||
        ",
 | 
			
		||||
    )?;
 | 
			
		||||
 | 
			
		||||
    println!("result: {result}"); // prints 1085764
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										114
									
								
								_archive/rhai_engine/rhaiexamples/custom_types_and_methods.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								_archive/rhai_engine/rhaiexamples/custom_types_and_methods.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
//! An example showing how to register a Rust type and methods/getters/setters for it.
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "no_object")]
 | 
			
		||||
fn main() {
 | 
			
		||||
    panic!("This example does not run under 'no_object'.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
use rhai::{CustomType, Engine, EvalAltResult, TypeBuilder};
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "no_object"))]
 | 
			
		||||
fn main() -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
    /// This is a test structure. If the metadata feature
 | 
			
		||||
    /// is enabled, this comment will be exported.
 | 
			
		||||
    #[derive(Debug, Clone, CustomType)]
 | 
			
		||||
    #[rhai_type(extra = Self::build_extra)]
 | 
			
		||||
    struct TestStruct {
 | 
			
		||||
        /// A number.
 | 
			
		||||
        ///
 | 
			
		||||
        /// ```js
 | 
			
		||||
        /// let t = new_ts();
 | 
			
		||||
        /// print(t.x); // Get the value of x.
 | 
			
		||||
        /// t.x = 42;   // Set the value of x.
 | 
			
		||||
        /// ```
 | 
			
		||||
        x: i64,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    impl TestStruct {
 | 
			
		||||
        pub fn new() -> Self {
 | 
			
		||||
            Self { x: 1 }
 | 
			
		||||
        }
 | 
			
		||||
        pub fn update(&mut self) {
 | 
			
		||||
            self.x += 1000;
 | 
			
		||||
        }
 | 
			
		||||
        pub fn calculate(&mut self, data: i64) -> i64 {
 | 
			
		||||
            self.x * data
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fn build_extra(builder: &mut TypeBuilder<Self>) {
 | 
			
		||||
            builder
 | 
			
		||||
                .with_fn("new_ts", TestStruct::new)
 | 
			
		||||
                .with_fn("update", TestStruct::update)
 | 
			
		||||
                .with_fn("calc", TestStruct::calculate);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let mut engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
    engine.build_type::<TestStruct>();
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "metadata")]
 | 
			
		||||
    {
 | 
			
		||||
        println!("Functions registered:");
 | 
			
		||||
 | 
			
		||||
        engine
 | 
			
		||||
            .gen_fn_signatures(false)
 | 
			
		||||
            .into_iter()
 | 
			
		||||
            .for_each(|func| println!("{func}"));
 | 
			
		||||
 | 
			
		||||
        println!();
 | 
			
		||||
 | 
			
		||||
        let docs: serde_json::Value =
 | 
			
		||||
            serde_json::from_str(&engine.gen_fn_metadata_to_json(false).unwrap()).unwrap();
 | 
			
		||||
 | 
			
		||||
        // compare comments from the type.
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            docs["customTypes"][0]["docComments"],
 | 
			
		||||
            serde_json::json!([
 | 
			
		||||
                "/// This is a test structure. If the metadata feature",
 | 
			
		||||
                "/// is enabled, this comment will be exported."
 | 
			
		||||
            ])
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // compare comments from the getter.
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            docs["functions"][1]["docComments"],
 | 
			
		||||
            serde_json::json!([
 | 
			
		||||
                "/// A number.",
 | 
			
		||||
                "///",
 | 
			
		||||
                "/// ```js",
 | 
			
		||||
                "/// let t = new_ts();",
 | 
			
		||||
                "/// print(t.x); // Get the value of x.",
 | 
			
		||||
                "/// t.x = 42;   // Set the value of x.",
 | 
			
		||||
                "/// ```"
 | 
			
		||||
            ])
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // compare comments from the setter.
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            docs["functions"][3]["docComments"],
 | 
			
		||||
            serde_json::json!([
 | 
			
		||||
                "/// A number.",
 | 
			
		||||
                "///",
 | 
			
		||||
                "/// ```js",
 | 
			
		||||
                "/// let t = new_ts();",
 | 
			
		||||
                "/// print(t.x); // Get the value of x.",
 | 
			
		||||
                "/// t.x = 42;   // Set the value of x.",
 | 
			
		||||
                "/// ```"
 | 
			
		||||
            ])
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result = engine.eval::<i64>(
 | 
			
		||||
        "
 | 
			
		||||
            let x = new_ts();
 | 
			
		||||
            x.x = 42;
 | 
			
		||||
            x.update();
 | 
			
		||||
            x.calc(x.x)
 | 
			
		||||
        ",
 | 
			
		||||
    )?;
 | 
			
		||||
 | 
			
		||||
    println!("result: {result}"); // prints 1085764
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
module static;
 | 
			
		||||
 | 
			
		||||
op minus(int, int) -> int;
 | 
			
		||||
 | 
			
		||||
module general_kenobi {
 | 
			
		||||
const CONSTANT: int;
 | 
			
		||||
 | 
			
		||||
/// Returns a string where "hello there" is repeated `n` times.
 | 
			
		||||
fn hello_there(n: int) -> String;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let hello_there: string;
 | 
			
		||||
 | 
			
		||||
const HELLO: string;
 | 
			
		||||
@@ -0,0 +1,259 @@
 | 
			
		||||
module static;
 | 
			
		||||
 | 
			
		||||
op ==(int, int) -> bool;
 | 
			
		||||
op !=(int, int) -> bool;
 | 
			
		||||
op >(int, int) -> bool;
 | 
			
		||||
op >=(int, int) -> bool;
 | 
			
		||||
op <(int, int) -> bool;
 | 
			
		||||
op <=(int, int) -> bool;
 | 
			
		||||
op &(int, int) -> int;
 | 
			
		||||
op |(int, int) -> int;
 | 
			
		||||
op ^(int, int) -> int;
 | 
			
		||||
op ..(int, int) -> Range<int>;
 | 
			
		||||
op ..=(int, int) -> RangeInclusive<int>;
 | 
			
		||||
 | 
			
		||||
op ==(bool, bool) -> bool;
 | 
			
		||||
op !=(bool, bool) -> bool;
 | 
			
		||||
op >(bool, bool) -> bool;
 | 
			
		||||
op >=(bool, bool) -> bool;
 | 
			
		||||
op <(bool, bool) -> bool;
 | 
			
		||||
op <=(bool, bool) -> bool;
 | 
			
		||||
op &(bool, bool) -> bool;
 | 
			
		||||
op |(bool, bool) -> bool;
 | 
			
		||||
op ^(bool, bool) -> bool;
 | 
			
		||||
 | 
			
		||||
op ==((), ()) -> bool;
 | 
			
		||||
op !=((), ()) -> bool;
 | 
			
		||||
op >((), ()) -> bool;
 | 
			
		||||
op >=((), ()) -> bool;
 | 
			
		||||
op <((), ()) -> bool;
 | 
			
		||||
op <=((), ()) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(int, int) -> int;
 | 
			
		||||
op -(int, int) -> int;
 | 
			
		||||
op *(int, int) -> int;
 | 
			
		||||
op /(int, int) -> int;
 | 
			
		||||
op %(int, int) -> int;
 | 
			
		||||
op **(int, int) -> int;
 | 
			
		||||
op >>(int, int) -> int;
 | 
			
		||||
op <<(int, int) -> int;
 | 
			
		||||
 | 
			
		||||
op +(float, float) -> float;
 | 
			
		||||
op -(float, float) -> float;
 | 
			
		||||
op *(float, float) -> float;
 | 
			
		||||
op /(float, float) -> float;
 | 
			
		||||
op %(float, float) -> float;
 | 
			
		||||
op **(float, float) -> float;
 | 
			
		||||
op ==(float, float) -> bool;
 | 
			
		||||
op !=(float, float) -> bool;
 | 
			
		||||
op >(float, float) -> bool;
 | 
			
		||||
op >=(float, float) -> bool;
 | 
			
		||||
op <(float, float) -> bool;
 | 
			
		||||
op <=(float, float) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(float, int) -> float;
 | 
			
		||||
op -(float, int) -> float;
 | 
			
		||||
op *(float, int) -> float;
 | 
			
		||||
op /(float, int) -> float;
 | 
			
		||||
op %(float, int) -> float;
 | 
			
		||||
op **(float, int) -> float;
 | 
			
		||||
op ==(float, int) -> bool;
 | 
			
		||||
op !=(float, int) -> bool;
 | 
			
		||||
op >(float, int) -> bool;
 | 
			
		||||
op >=(float, int) -> bool;
 | 
			
		||||
op <(float, int) -> bool;
 | 
			
		||||
op <=(float, int) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(int, float) -> float;
 | 
			
		||||
op -(int, float) -> float;
 | 
			
		||||
op *(int, float) -> float;
 | 
			
		||||
op /(int, float) -> float;
 | 
			
		||||
op %(int, float) -> float;
 | 
			
		||||
op **(int, float) -> float;
 | 
			
		||||
op ==(int, float) -> bool;
 | 
			
		||||
op !=(int, float) -> bool;
 | 
			
		||||
op >(int, float) -> bool;
 | 
			
		||||
op >=(int, float) -> bool;
 | 
			
		||||
op <(int, float) -> bool;
 | 
			
		||||
op <=(int, float) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(Decimal, Decimal) -> Decimal;
 | 
			
		||||
op -(Decimal, Decimal) -> Decimal;
 | 
			
		||||
op *(Decimal, Decimal) -> Decimal;
 | 
			
		||||
op /(Decimal, Decimal) -> Decimal;
 | 
			
		||||
op %(Decimal, Decimal) -> Decimal;
 | 
			
		||||
op **(Decimal, Decimal) -> Decimal;
 | 
			
		||||
op ==(Decimal, Decimal) -> bool;
 | 
			
		||||
op !=(Decimal, Decimal) -> bool;
 | 
			
		||||
op >(Decimal, Decimal) -> bool;
 | 
			
		||||
op >=(Decimal, Decimal) -> bool;
 | 
			
		||||
op <(Decimal, Decimal) -> bool;
 | 
			
		||||
op <=(Decimal, Decimal) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(Decimal, int) -> Decimal;
 | 
			
		||||
op -(Decimal, int) -> Decimal;
 | 
			
		||||
op *(Decimal, int) -> Decimal;
 | 
			
		||||
op /(Decimal, int) -> Decimal;
 | 
			
		||||
op %(Decimal, int) -> Decimal;
 | 
			
		||||
op **(Decimal, int) -> Decimal;
 | 
			
		||||
op ==(Decimal, int) -> bool;
 | 
			
		||||
op !=(Decimal, int) -> bool;
 | 
			
		||||
op >(Decimal, int) -> bool;
 | 
			
		||||
op >=(Decimal, int) -> bool;
 | 
			
		||||
op <(Decimal, int) -> bool;
 | 
			
		||||
op <=(Decimal, int) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(int, Decimal) -> Decimal;
 | 
			
		||||
op -(int, Decimal) -> Decimal;
 | 
			
		||||
op *(int, Decimal) -> Decimal;
 | 
			
		||||
op /(int, Decimal) -> Decimal;
 | 
			
		||||
op %(int, Decimal) -> Decimal;
 | 
			
		||||
op **(int, Decimal) -> Decimal;
 | 
			
		||||
op ==(int, Decimal) -> bool;
 | 
			
		||||
op !=(int, Decimal) -> bool;
 | 
			
		||||
op >(int, Decimal) -> bool;
 | 
			
		||||
op >=(int, Decimal) -> bool;
 | 
			
		||||
op <(int, Decimal) -> bool;
 | 
			
		||||
op <=(int, Decimal) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(String, String) -> String;
 | 
			
		||||
op -(String, String) -> String;
 | 
			
		||||
op ==(String, String) -> bool;
 | 
			
		||||
op !=(String, String) -> bool;
 | 
			
		||||
op >(String, String) -> bool;
 | 
			
		||||
op >=(String, String) -> bool;
 | 
			
		||||
op <(String, String) -> bool;
 | 
			
		||||
op <=(String, String) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(char, char) -> String;
 | 
			
		||||
op ==(char, char) -> bool;
 | 
			
		||||
op !=(char, char) -> bool;
 | 
			
		||||
op >(char, char) -> bool;
 | 
			
		||||
op >=(char, char) -> bool;
 | 
			
		||||
op <(char, char) -> bool;
 | 
			
		||||
op <=(char, char) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(char, String) -> String;
 | 
			
		||||
op ==(char, String) -> bool;
 | 
			
		||||
op !=(char, String) -> bool;
 | 
			
		||||
op >(char, String) -> bool;
 | 
			
		||||
op >=(char, String) -> bool;
 | 
			
		||||
op <(char, String) -> bool;
 | 
			
		||||
op <=(char, String) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(String, char) -> String;
 | 
			
		||||
op -(String, char) -> String;
 | 
			
		||||
op ==(String, char) -> bool;
 | 
			
		||||
op !=(String, char) -> bool;
 | 
			
		||||
op >(String, char) -> bool;
 | 
			
		||||
op >=(String, char) -> bool;
 | 
			
		||||
op <(String, char) -> bool;
 | 
			
		||||
op <=(String, char) -> bool;
 | 
			
		||||
 | 
			
		||||
op +((), String) -> String;
 | 
			
		||||
op ==((), String) -> bool;
 | 
			
		||||
op !=((), String) -> bool;
 | 
			
		||||
op >((), String) -> bool;
 | 
			
		||||
op >=((), String) -> bool;
 | 
			
		||||
op <((), String) -> bool;
 | 
			
		||||
op <=((), String) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(String, ()) -> String;
 | 
			
		||||
op ==(String, ()) -> bool;
 | 
			
		||||
op !=(String, ()) -> bool;
 | 
			
		||||
op >(String, ()) -> bool;
 | 
			
		||||
op >=(String, ()) -> bool;
 | 
			
		||||
op <(String, ()) -> bool;
 | 
			
		||||
op <=(String, ()) -> bool;
 | 
			
		||||
 | 
			
		||||
op +(Blob, Blob) -> Blob;
 | 
			
		||||
op +(Blob, char) -> Blob;
 | 
			
		||||
op ==(Blob, Blob) -> bool;
 | 
			
		||||
op !=(Blob, Blob) -> bool;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
op ==(Range<int>, RangeInclusive<int>) -> bool;
 | 
			
		||||
op !=(Range<int>, RangeInclusive<int>) -> bool;
 | 
			
		||||
 | 
			
		||||
op ==(RangeInclusive<int>, Range<int>) -> bool;
 | 
			
		||||
op !=(RangeInclusive<int>, Range<int>) -> bool;
 | 
			
		||||
 | 
			
		||||
op ==(Range<int>, Range<int>) -> bool;
 | 
			
		||||
op !=(Range<int>, Range<int>) -> bool;
 | 
			
		||||
 | 
			
		||||
op ==(RangeInclusive<int>, RangeInclusive<int>) -> bool;
 | 
			
		||||
op !=(RangeInclusive<int>, RangeInclusive<int>) -> bool;
 | 
			
		||||
 | 
			
		||||
op ==(?, ?) -> bool;
 | 
			
		||||
op !=(?, ?) -> bool;
 | 
			
		||||
op >(?, ?) -> bool;
 | 
			
		||||
op >=(?, ?) -> bool;
 | 
			
		||||
op <(?, ?) -> bool;
 | 
			
		||||
op <=(?, ?) -> bool;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
op &=(bool, bool);
 | 
			
		||||
op |=(bool, bool);
 | 
			
		||||
 | 
			
		||||
op +=(int, int);
 | 
			
		||||
op -=(int, int);
 | 
			
		||||
op *=(int, int);
 | 
			
		||||
op /=(int, int);
 | 
			
		||||
op %=(int, int);
 | 
			
		||||
op **=(int, int);
 | 
			
		||||
op >>=(int, int);
 | 
			
		||||
op <<=(int, int);
 | 
			
		||||
op &=(int, int);
 | 
			
		||||
op |=(int, int);
 | 
			
		||||
op ^=(int, int);
 | 
			
		||||
 | 
			
		||||
op +=(float, float);
 | 
			
		||||
op -=(float, float);
 | 
			
		||||
op *=(float, float);
 | 
			
		||||
op /=(float, float);
 | 
			
		||||
op %=(float, float);
 | 
			
		||||
op **=(float, float);
 | 
			
		||||
 | 
			
		||||
op +=(float, int);
 | 
			
		||||
op -=(float, int);
 | 
			
		||||
op *=(float, int);
 | 
			
		||||
op /=(float, int);
 | 
			
		||||
op %=(float, int);
 | 
			
		||||
op **=(float, int);
 | 
			
		||||
 | 
			
		||||
op +=(Decimal, Decimal);
 | 
			
		||||
op -=(Decimal, Decimal);
 | 
			
		||||
op *=(Decimal, Decimal);
 | 
			
		||||
op /=(Decimal, Decimal);
 | 
			
		||||
op %=(Decimal, Decimal);
 | 
			
		||||
op **=(Decimal, Decimal);
 | 
			
		||||
 | 
			
		||||
op +=(Decimal, int);
 | 
			
		||||
op -=(Decimal, int);
 | 
			
		||||
op *=(Decimal, int);
 | 
			
		||||
op /=(Decimal, int);
 | 
			
		||||
op %=(Decimal, int);
 | 
			
		||||
op **=(Decimal, int);
 | 
			
		||||
 | 
			
		||||
op +=(String, String);
 | 
			
		||||
op -=(String, String);
 | 
			
		||||
op +=(String, char);
 | 
			
		||||
op -=(String, char);
 | 
			
		||||
op +=(char, String);
 | 
			
		||||
op +=(char, char);
 | 
			
		||||
 | 
			
		||||
op +=(Array, Array);
 | 
			
		||||
op +=(Array, ?);
 | 
			
		||||
 | 
			
		||||
op +=(Blob, Blob);
 | 
			
		||||
op +=(Blob, int);
 | 
			
		||||
op +=(Blob, char);
 | 
			
		||||
op +=(Blob, String);
 | 
			
		||||
 | 
			
		||||
op in(?, Array) -> bool;
 | 
			
		||||
op in(String, String) -> bool;
 | 
			
		||||
op in(char, String) -> bool;
 | 
			
		||||
op in(int, Range<int>) -> bool;
 | 
			
		||||
op in(int, RangeInclusive<int>) -> bool;
 | 
			
		||||
op in(String, Map) -> bool;
 | 
			
		||||
op in(int, Blob) -> bool;
 | 
			
		||||
@@ -0,0 +1,261 @@
 | 
			
		||||
module static;
 | 
			
		||||
 | 
			
		||||
/// Display any data to the standard output.
 | 
			
		||||
///
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let answer = 42;
 | 
			
		||||
/// 
 | 
			
		||||
/// print(`The Answer is ${answer}`);
 | 
			
		||||
/// ```
 | 
			
		||||
fn print(data: ?);
 | 
			
		||||
 | 
			
		||||
/// Display any data to the standard output in debug format.
 | 
			
		||||
///
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let answer = 42;
 | 
			
		||||
/// 
 | 
			
		||||
/// debug(answer);
 | 
			
		||||
/// ```
 | 
			
		||||
fn debug(data: ?);
 | 
			
		||||
 | 
			
		||||
/// Get the type of a value.
 | 
			
		||||
///
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let x = "hello, world!";
 | 
			
		||||
/// 
 | 
			
		||||
/// print(x.type_of());     // prints "string"
 | 
			
		||||
/// ```
 | 
			
		||||
fn type_of(data: ?) -> String;
 | 
			
		||||
 | 
			
		||||
/// Create a function pointer to a named function.
 | 
			
		||||
///
 | 
			
		||||
/// If the specified name is not a valid function name, an error is raised.
 | 
			
		||||
/// 
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let f = Fn("foo");      // function pointer to 'foo'
 | 
			
		||||
/// 
 | 
			
		||||
/// f.call(42);             // call: foo(42)
 | 
			
		||||
/// ```
 | 
			
		||||
fn Fn(fn_name: String) -> FnPtr;
 | 
			
		||||
 | 
			
		||||
/// Call a function pointed to by a function pointer,
 | 
			
		||||
/// passing following arguments to the function call.
 | 
			
		||||
///
 | 
			
		||||
/// If an appropriate function is not found, an error is raised.
 | 
			
		||||
/// 
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let f = Fn("foo");      // function pointer to 'foo'
 | 
			
		||||
/// 
 | 
			
		||||
/// f.call(1, 2, 3);        // call: foo(1, 2, 3)
 | 
			
		||||
/// ```
 | 
			
		||||
fn call(fn_ptr: FnPtr, ...args: ?) -> ?;
 | 
			
		||||
 | 
			
		||||
/// Call a function pointed to by a function pointer, binding the `this` pointer
 | 
			
		||||
/// to the object of the method call, and passing on following arguments to the function call.
 | 
			
		||||
///
 | 
			
		||||
/// If an appropriate function is not found, an error is raised.
 | 
			
		||||
/// 
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// fn add(x) {
 | 
			
		||||
///     this + x
 | 
			
		||||
/// }
 | 
			
		||||
/// 
 | 
			
		||||
/// let f = Fn("add");      // function pointer to 'add'
 | 
			
		||||
/// 
 | 
			
		||||
/// let x = 41;
 | 
			
		||||
/// 
 | 
			
		||||
/// let r = x.call(f, 1);   // call: add(1) with 'this' = 'x'
 | 
			
		||||
/// 
 | 
			
		||||
/// print(r);               // prints 42
 | 
			
		||||
/// ```
 | 
			
		||||
fn call(obj: ?, fn_ptr: FnPtr, ...args: ?) -> ?;
 | 
			
		||||
 | 
			
		||||
/// Curry a number of arguments into a function pointer and return it as a new function pointer.
 | 
			
		||||
/// 
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// fn foo(x, y, z) {
 | 
			
		||||
///     x + y + z
 | 
			
		||||
/// }
 | 
			
		||||
/// 
 | 
			
		||||
/// let f = Fn("foo");
 | 
			
		||||
/// 
 | 
			
		||||
/// let g = f.curry(1, 2);  // curried arguments: 1, 2
 | 
			
		||||
/// 
 | 
			
		||||
/// g.call(3);              // call: foo(1, 2, 3)
 | 
			
		||||
/// ```
 | 
			
		||||
fn curry(fn_ptr: FnPtr, ...args: ?) -> FnPtr;
 | 
			
		||||
 | 
			
		||||
/// Return `true` if a script-defined function exists with a specified name and
 | 
			
		||||
/// number of parameters.
 | 
			
		||||
/// 
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// fn foo(x) { }
 | 
			
		||||
/// 
 | 
			
		||||
/// print(is_def_fn("foo", 1));     // prints true
 | 
			
		||||
/// print(is_def_fn("foo", 2));     // prints false
 | 
			
		||||
/// print(is_def_fn("foo", 0));     // prints false
 | 
			
		||||
/// print(is_def_fn("bar", 1));     // prints false
 | 
			
		||||
/// ```
 | 
			
		||||
fn is_def_fn(fn_name: String, num_params: int) -> bool;
 | 
			
		||||
 | 
			
		||||
/// Return `true` if a variable matching a specified name is defined.
 | 
			
		||||
/// 
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let x = 42;
 | 
			
		||||
/// 
 | 
			
		||||
/// print(is_def_var("x"));         // prints true
 | 
			
		||||
/// print(is_def_var("foo"));       // prints false
 | 
			
		||||
/// 
 | 
			
		||||
/// {
 | 
			
		||||
///     let y = 1;
 | 
			
		||||
///     print(is_def_var("y"));     // prints true
 | 
			
		||||
/// }
 | 
			
		||||
/// 
 | 
			
		||||
/// print(is_def_var("y"));         // prints false
 | 
			
		||||
/// ```
 | 
			
		||||
fn is_def_var(var_name: String) -> bool;
 | 
			
		||||
 | 
			
		||||
/// Return `true` if the variable is shared.
 | 
			
		||||
/// 
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let x = 42;
 | 
			
		||||
/// 
 | 
			
		||||
/// print(is_shared(x));        // prints false
 | 
			
		||||
/// 
 | 
			
		||||
/// let f = || x;               // capture 'x', making it shared
 | 
			
		||||
/// 
 | 
			
		||||
/// print(is_shared(x));        // prints true
 | 
			
		||||
/// ```
 | 
			
		||||
fn is_shared(variable: ?) -> bool;
 | 
			
		||||
 | 
			
		||||
/// Evaluate a text script within the current scope.
 | 
			
		||||
/// 
 | 
			
		||||
/// # Example
 | 
			
		||||
/// 
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let x = 42;
 | 
			
		||||
/// 
 | 
			
		||||
/// eval("let y = x; x = 123;");
 | 
			
		||||
/// 
 | 
			
		||||
/// print(x);           // prints 123
 | 
			
		||||
/// print(y);           // prints 42
 | 
			
		||||
/// ```
 | 
			
		||||
fn eval(script: String) -> ?;
 | 
			
		||||
 | 
			
		||||
/// Return `true` if the string contains another string.
 | 
			
		||||
///
 | 
			
		||||
/// This function also drives the `in` operator.
 | 
			
		||||
///
 | 
			
		||||
/// # Example
 | 
			
		||||
///
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let x = "hello world!";
 | 
			
		||||
///
 | 
			
		||||
/// // The 'in' operator calls 'contains' in the background
 | 
			
		||||
/// if "world" in x {
 | 
			
		||||
///     print("found!");
 | 
			
		||||
/// }
 | 
			
		||||
/// ```
 | 
			
		||||
fn contains(string: String, find: String) -> bool;
 | 
			
		||||
 | 
			
		||||
/// Return `true` if the string contains a character.
 | 
			
		||||
///
 | 
			
		||||
/// This function also drives the `in` operator.
 | 
			
		||||
///
 | 
			
		||||
/// # Example
 | 
			
		||||
///
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let x = "hello world!";
 | 
			
		||||
///
 | 
			
		||||
/// // The 'in' operator calls 'contains' in the background
 | 
			
		||||
/// if 'w' in x {
 | 
			
		||||
///     print("found!");
 | 
			
		||||
/// }
 | 
			
		||||
/// ```
 | 
			
		||||
fn contains(string: String, ch: char) -> bool;
 | 
			
		||||
 | 
			
		||||
/// Return `true` if a value falls within the exclusive range.
 | 
			
		||||
///
 | 
			
		||||
/// This function also drives the `in` operator.
 | 
			
		||||
///
 | 
			
		||||
/// # Example
 | 
			
		||||
///
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let r = 1..100;
 | 
			
		||||
///
 | 
			
		||||
/// // The 'in' operator calls 'contains' in the background
 | 
			
		||||
/// if 42 in r {
 | 
			
		||||
///     print("found!");
 | 
			
		||||
/// }
 | 
			
		||||
/// ```
 | 
			
		||||
fn contains(range: Range<int>, value: int) -> bool;
 | 
			
		||||
 | 
			
		||||
/// Return `true` if a value falls within the inclusive range.
 | 
			
		||||
///
 | 
			
		||||
/// This function also drives the `in` operator.
 | 
			
		||||
///
 | 
			
		||||
/// # Example
 | 
			
		||||
///
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let r = 1..=100;
 | 
			
		||||
///
 | 
			
		||||
/// // The 'in' operator calls 'contains' in the background
 | 
			
		||||
/// if 42 in r {
 | 
			
		||||
///     print("found!");
 | 
			
		||||
/// }
 | 
			
		||||
/// ```
 | 
			
		||||
fn contains(range: RangeInclusive<int>, value: int) -> bool;
 | 
			
		||||
 | 
			
		||||
/// Return `true` if a key exists within the object map.
 | 
			
		||||
///
 | 
			
		||||
/// This function also drives the `in` operator.
 | 
			
		||||
///
 | 
			
		||||
/// # Example
 | 
			
		||||
///
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let m = #{a:1, b:2, c:3};
 | 
			
		||||
///
 | 
			
		||||
/// // The 'in' operator calls 'contains' in the background
 | 
			
		||||
/// if "c" in m {
 | 
			
		||||
///     print("found!");
 | 
			
		||||
/// }
 | 
			
		||||
/// ```
 | 
			
		||||
fn contains(map: Map, string: String) -> bool;
 | 
			
		||||
 | 
			
		||||
/// Return `true` if a value is found within the BLOB.
 | 
			
		||||
///
 | 
			
		||||
/// This function also drives the `in` operator.
 | 
			
		||||
///
 | 
			
		||||
/// # Example
 | 
			
		||||
///
 | 
			
		||||
/// ```rhai
 | 
			
		||||
/// let b = blob();
 | 
			
		||||
///
 | 
			
		||||
/// b += 1; b += 2; b += 3; b += 4; b += 5;
 | 
			
		||||
///
 | 
			
		||||
/// // The 'in' operator calls 'contains' in the background
 | 
			
		||||
/// if 3 in b {
 | 
			
		||||
///     print("found!");
 | 
			
		||||
/// }
 | 
			
		||||
/// ```
 | 
			
		||||
fn contains(blob: Blob, value: int) -> bool;
 | 
			
		||||
@@ -0,0 +1,5 @@
 | 
			
		||||
module static;
 | 
			
		||||
 | 
			
		||||
let hello_there: string;
 | 
			
		||||
 | 
			
		||||
const HELLO: string;
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
module general_kenobi;
 | 
			
		||||
 | 
			
		||||
const CONSTANT: int;
 | 
			
		||||
 | 
			
		||||
/// Returns a string where "hello there" is repeated `n` times.
 | 
			
		||||
fn hello_there(n: int) -> String;
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
{
 | 
			
		||||
  "modules": {
 | 
			
		||||
    "general_kenobi": {
 | 
			
		||||
      "functions": [
 | 
			
		||||
        {
 | 
			
		||||
          "baseHash": 3873007749982070651,
 | 
			
		||||
          "fullHash": 5865213555928423624,
 | 
			
		||||
          "namespace": "internal",
 | 
			
		||||
          "access": "public",
 | 
			
		||||
          "name": "hello_there",
 | 
			
		||||
          "type": "native",
 | 
			
		||||
          "numParams": 1,
 | 
			
		||||
          "params": [
 | 
			
		||||
            {
 | 
			
		||||
              "name": "n",
 | 
			
		||||
              "type": "i64"
 | 
			
		||||
            }
 | 
			
		||||
          ],
 | 
			
		||||
          "returnType": "String",
 | 
			
		||||
          "signature": "hello_there(n: i64) -> String",
 | 
			
		||||
          "docComments": [
 | 
			
		||||
            "/// Returns a string where \"hello there\" is repeated `n` times."
 | 
			
		||||
          ]
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  "functions": [
 | 
			
		||||
    {
 | 
			
		||||
      "baseHash": 12461724250411739075,
 | 
			
		||||
      "fullHash": 14530626537296006176,
 | 
			
		||||
      "namespace": "global",
 | 
			
		||||
      "access": "public",
 | 
			
		||||
      "name": "minus",
 | 
			
		||||
      "type": "native",
 | 
			
		||||
      "numParams": 2,
 | 
			
		||||
      "params": [
 | 
			
		||||
        {
 | 
			
		||||
          "type": "i64"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          "type": "i64"
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "returnType": "i64",
 | 
			
		||||
      "signature": "minus(_: i64, _: i64) -> i64"
 | 
			
		||||
    }
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								_archive/rhai_engine/rhaiexamples/definitions/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								_archive/rhai_engine/rhaiexamples/definitions/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
use rhai::plugin::*;
 | 
			
		||||
use rhai::{Engine, EvalAltResult, Scope};
 | 
			
		||||
 | 
			
		||||
#[export_module]
 | 
			
		||||
pub mod general_kenobi {
 | 
			
		||||
    /// General Kenobi's Constant.
 | 
			
		||||
    pub const CONSTANT: i64 = 42;
 | 
			
		||||
 | 
			
		||||
    /// Returns a string where "hello there" is repeated `n` times.
 | 
			
		||||
    pub fn hello_there(n: i64) -> String {
 | 
			
		||||
        use std::convert::TryInto;
 | 
			
		||||
        "hello there ".repeat(n.try_into().unwrap())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
    let mut engine = Engine::new();
 | 
			
		||||
    let mut scope = Scope::new();
 | 
			
		||||
 | 
			
		||||
    // This variable will also show up in the definitions, since it will be part of the scope.
 | 
			
		||||
    scope.push("hello_there", "hello there");
 | 
			
		||||
 | 
			
		||||
    // This constant will also show up in the definitions, since it will be part of the scope.
 | 
			
		||||
    scope.push_constant("HELLO", "hello there");
 | 
			
		||||
 | 
			
		||||
    #[cfg(not(feature = "no_module"))]
 | 
			
		||||
    engine.register_static_module("general_kenobi", exported_module!(general_kenobi).into());
 | 
			
		||||
 | 
			
		||||
    // Custom operators also show up in definitions.
 | 
			
		||||
    #[cfg(not(feature = "no_custom_syntax"))]
 | 
			
		||||
    {
 | 
			
		||||
        engine.register_custom_operator("minus", 100).unwrap();
 | 
			
		||||
        engine.register_fn("minus", |a: i64, b: i64| a - b);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    engine.run_with_scope(
 | 
			
		||||
        &mut scope,
 | 
			
		||||
        "hello_there = general_kenobi::hello_there(4 minus 2);",
 | 
			
		||||
    )?;
 | 
			
		||||
 | 
			
		||||
    // Generate definitions for the contents of the engine and the scope.
 | 
			
		||||
    engine
 | 
			
		||||
        .definitions_with_scope(&scope)
 | 
			
		||||
        .write_to_dir("examples/definitions/.rhai/definitions")
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
    // Alternatively we can write all of the above to a single file.
 | 
			
		||||
    engine
 | 
			
		||||
        .definitions_with_scope(&scope)
 | 
			
		||||
        .write_to_file("examples/definitions/.rhai/all_in_one.d.rhai")
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
    // Skip standard packages if not needed (e.g. they are provided elsewhere).
 | 
			
		||||
    engine
 | 
			
		||||
        .definitions_with_scope(&scope)
 | 
			
		||||
        .include_standard_packages(false)
 | 
			
		||||
        .write_to_file("examples/definitions/.rhai/all_in_one_without_standard.d.rhai")
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
    // Write function definitions as JSON.
 | 
			
		||||
    let json = engine
 | 
			
		||||
        .definitions()
 | 
			
		||||
        .include_standard_packages(false)
 | 
			
		||||
        .json()
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
    std::fs::write("examples/definitions/.rhai/defs.json", json).unwrap();
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,3 @@
 | 
			
		||||
// The following will be valid based on the definitions.
 | 
			
		||||
hello_there = general_kenobi::hello_there(123);
 | 
			
		||||
print(hello_there);
 | 
			
		||||
							
								
								
									
										168
									
								
								_archive/rhai_engine/rhaiexamples/event_handler_js/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								_archive/rhai_engine/rhaiexamples/event_handler_js/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
			
		||||
//! Implementation of the Event Handler With State Pattern - JS Style
 | 
			
		||||
 | 
			
		||||
#[cfg(any(feature = "no_function", feature = "no_object"))]
 | 
			
		||||
pub fn main() {
 | 
			
		||||
    panic!("This example does not run under 'no_function' or 'no_object'.")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "no_function"))]
 | 
			
		||||
#[cfg(not(feature = "no_object"))]
 | 
			
		||||
pub fn main() {
 | 
			
		||||
    use rhai::{CallFnOptions, Dynamic, Engine, Map, Scope, AST};
 | 
			
		||||
    use std::io::{stdin, stdout, Write};
 | 
			
		||||
 | 
			
		||||
    const SCRIPT_FILE: &str = "event_handler_js/script.rhai";
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug)]
 | 
			
		||||
    struct Handler {
 | 
			
		||||
        pub engine: Engine,
 | 
			
		||||
        pub scope: Scope<'static>,
 | 
			
		||||
        pub states: Dynamic,
 | 
			
		||||
        pub ast: AST,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn print_scope(scope: &Scope) {
 | 
			
		||||
        for (i, (name, constant, value)) in scope.iter_raw().enumerate() {
 | 
			
		||||
            #[cfg(not(feature = "no_closure"))]
 | 
			
		||||
            let value_is_shared = if value.is_shared() { " (shared)" } else { "" };
 | 
			
		||||
            #[cfg(feature = "no_closure")]
 | 
			
		||||
            let value_is_shared = "";
 | 
			
		||||
 | 
			
		||||
            println!(
 | 
			
		||||
                "[{}] {}{}{} = {:?}",
 | 
			
		||||
                i + 1,
 | 
			
		||||
                if constant { "const " } else { "" },
 | 
			
		||||
                name,
 | 
			
		||||
                value_is_shared,
 | 
			
		||||
                *value.read_lock::<Dynamic>().unwrap(),
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        println!();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    println!("Events Handler Example - JS Style");
 | 
			
		||||
    println!("==================================");
 | 
			
		||||
 | 
			
		||||
    let mut input = String::new();
 | 
			
		||||
 | 
			
		||||
    // Read script file
 | 
			
		||||
    print!("Script file [{}]: ", SCRIPT_FILE);
 | 
			
		||||
    stdout().flush().expect("flush stdout");
 | 
			
		||||
 | 
			
		||||
    input.clear();
 | 
			
		||||
 | 
			
		||||
    stdin().read_line(&mut input).expect("read input");
 | 
			
		||||
 | 
			
		||||
    let path = match input.trim() {
 | 
			
		||||
        "" => SCRIPT_FILE,
 | 
			
		||||
        path => path,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Create Engine
 | 
			
		||||
    let engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
    // Use an object map to hold state
 | 
			
		||||
    let mut states = Map::new();
 | 
			
		||||
 | 
			
		||||
    // Default states can be added
 | 
			
		||||
    states.insert("bool_state".into(), Dynamic::FALSE);
 | 
			
		||||
 | 
			
		||||
    // Convert the object map into 'Dynamic'
 | 
			
		||||
    let mut states: Dynamic = states.into();
 | 
			
		||||
 | 
			
		||||
    // Create a custom 'Scope' to hold state
 | 
			
		||||
    let mut scope = Scope::new();
 | 
			
		||||
 | 
			
		||||
    // Add any system-provided state into the custom 'Scope'.
 | 
			
		||||
    // Constants can be used to optimize the script.
 | 
			
		||||
    scope.push_constant("MY_CONSTANT", 42_i64);
 | 
			
		||||
 | 
			
		||||
    // Compile the handler script.
 | 
			
		||||
    println!("> Loading script file: {path}");
 | 
			
		||||
 | 
			
		||||
    let ast = match engine.compile_file_with_scope(&scope, path.into()) {
 | 
			
		||||
        Ok(ast) => ast,
 | 
			
		||||
        Err(err) => {
 | 
			
		||||
            eprintln!("! Error: {err}");
 | 
			
		||||
            println!("Cannot continue. Bye!");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    println!("> Script file loaded.");
 | 
			
		||||
    println!();
 | 
			
		||||
    println!("quit      = exit program");
 | 
			
		||||
    println!("scope     = print scope");
 | 
			
		||||
    println!("states    = print states");
 | 
			
		||||
    println!("event arg = run function with argument");
 | 
			
		||||
    println!();
 | 
			
		||||
 | 
			
		||||
    // Run the 'init' function to initialize the state, retaining variables.
 | 
			
		||||
 | 
			
		||||
    let options = CallFnOptions::new()
 | 
			
		||||
        .eval_ast(false)
 | 
			
		||||
        .bind_this_ptr(&mut states);
 | 
			
		||||
 | 
			
		||||
    let result = engine.call_fn_with_options::<()>(options, &mut scope, &ast, "init", ());
 | 
			
		||||
 | 
			
		||||
    if let Err(err) = result {
 | 
			
		||||
        eprintln!("! {err}")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create handler instance
 | 
			
		||||
    let mut handler = Handler {
 | 
			
		||||
        engine,
 | 
			
		||||
        scope,
 | 
			
		||||
        states,
 | 
			
		||||
        ast,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Events loop
 | 
			
		||||
    loop {
 | 
			
		||||
        print!("event> ");
 | 
			
		||||
        stdout().flush().expect("flush stdout");
 | 
			
		||||
 | 
			
		||||
        // Read event
 | 
			
		||||
        input.clear();
 | 
			
		||||
        stdin().read_line(&mut input).expect("read input");
 | 
			
		||||
 | 
			
		||||
        let mut fields = input.trim().splitn(2, ' ');
 | 
			
		||||
 | 
			
		||||
        let event = fields.next().expect("event").trim();
 | 
			
		||||
        let arg = fields.next().unwrap_or("").to_string();
 | 
			
		||||
 | 
			
		||||
        // Process event
 | 
			
		||||
        match event {
 | 
			
		||||
            "quit" => break,
 | 
			
		||||
 | 
			
		||||
            "scope" => {
 | 
			
		||||
                print_scope(&handler.scope);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            "states" => {
 | 
			
		||||
                println!("{:?}", handler.states);
 | 
			
		||||
                println!();
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Map all other events to function calls
 | 
			
		||||
            _ => {
 | 
			
		||||
                let engine = &handler.engine;
 | 
			
		||||
                let scope = &mut handler.scope;
 | 
			
		||||
                let ast = &handler.ast;
 | 
			
		||||
                let options = CallFnOptions::new()
 | 
			
		||||
                    .eval_ast(false)
 | 
			
		||||
                    .bind_this_ptr(&mut handler.states);
 | 
			
		||||
 | 
			
		||||
                let result = engine.call_fn_with_options::<()>(options, scope, ast, event, (arg,));
 | 
			
		||||
 | 
			
		||||
                if let Err(err) = result {
 | 
			
		||||
                    eprintln!("! {err}")
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    println!("Bye!");
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,50 @@
 | 
			
		||||
//! Implementation of the Event Handler With State Pattern - JS Style
 | 
			
		||||
 | 
			
		||||
/// Initialize user-provided state.
 | 
			
		||||
fn init() {
 | 
			
		||||
    // Can detect system-provided default states!
 | 
			
		||||
    // Add 'bool_state' as new state variable if one does not exist
 | 
			
		||||
    if "bool_state" !in this {
 | 
			
		||||
        this.bool_state = false;
 | 
			
		||||
    }
 | 
			
		||||
    // Add 'value' as new state variable (overwrites any existing)
 | 
			
		||||
    this.value = 0;
 | 
			
		||||
 | 
			
		||||
    // Can also add OOP-style functions!
 | 
			
		||||
    this.log = |x| print(`State = ${this.value}, data = ${x}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 'start' event handler
 | 
			
		||||
fn start(data) {
 | 
			
		||||
    if this.bool_state {
 | 
			
		||||
        throw "Already started!";
 | 
			
		||||
    }
 | 
			
		||||
    if this.value <= 0 {
 | 
			
		||||
        throw "Conditions not yet ready to start!";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Constant 'MY_CONSTANT' in custom scope is also visible!
 | 
			
		||||
    print(`MY_CONSTANT = ${MY_CONSTANT}`);
 | 
			
		||||
 | 
			
		||||
    this.value += parse_int(data);
 | 
			
		||||
    this.bool_state = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 'end' event handler
 | 
			
		||||
fn end(data) {
 | 
			
		||||
    if !this.bool_state {
 | 
			
		||||
        throw "Not yet started!";
 | 
			
		||||
    }
 | 
			
		||||
    if this.value > 0 {
 | 
			
		||||
        throw "Conditions not yet ready to end!";
 | 
			
		||||
    }
 | 
			
		||||
    this.value = parse_int(data);
 | 
			
		||||
    this.bool_state = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 'update' event handler
 | 
			
		||||
fn update(data) {
 | 
			
		||||
    let data = parse_int(data);
 | 
			
		||||
    this.value += data;
 | 
			
		||||
    this.log(data);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										139
									
								
								_archive/rhai_engine/rhaiexamples/event_handler_main/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								_archive/rhai_engine/rhaiexamples/event_handler_main/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
//! Implementation of the Event Handler With State Pattern - Main Style
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "no_function")]
 | 
			
		||||
pub fn main() {
 | 
			
		||||
    panic!("This example does not run under 'no_function'.")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "no_function"))]
 | 
			
		||||
pub fn main() {
 | 
			
		||||
    use rhai::{CallFnOptions, Dynamic, Engine, Scope, AST};
 | 
			
		||||
    use std::io::{stdin, stdout, Write};
 | 
			
		||||
 | 
			
		||||
    const SCRIPT_FILE: &str = "event_handler_main/script.rhai";
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug)]
 | 
			
		||||
    struct Handler {
 | 
			
		||||
        pub engine: Engine,
 | 
			
		||||
        pub scope: Scope<'static>,
 | 
			
		||||
        pub ast: AST,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn print_scope(scope: &Scope) {
 | 
			
		||||
        for (i, (name, constant, value)) in scope.iter_raw().enumerate() {
 | 
			
		||||
            #[cfg(not(feature = "no_closure"))]
 | 
			
		||||
            let value_is_shared = if value.is_shared() { " (shared)" } else { "" };
 | 
			
		||||
            #[cfg(feature = "no_closure")]
 | 
			
		||||
            let value_is_shared = "";
 | 
			
		||||
 | 
			
		||||
            println!(
 | 
			
		||||
                "[{}] {}{}{} = {:?}",
 | 
			
		||||
                i + 1,
 | 
			
		||||
                if constant { "const " } else { "" },
 | 
			
		||||
                name,
 | 
			
		||||
                value_is_shared,
 | 
			
		||||
                *value.read_lock::<Dynamic>().unwrap(),
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        println!();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    println!("Events Handler Example - Main Style");
 | 
			
		||||
    println!("===================================");
 | 
			
		||||
 | 
			
		||||
    let mut input = String::new();
 | 
			
		||||
 | 
			
		||||
    // Read script file
 | 
			
		||||
    print!("Script file [{SCRIPT_FILE}]: ");
 | 
			
		||||
    stdout().flush().expect("flush stdout");
 | 
			
		||||
 | 
			
		||||
    input.clear();
 | 
			
		||||
 | 
			
		||||
    stdin().read_line(&mut input).expect("read input");
 | 
			
		||||
 | 
			
		||||
    let path = match input.trim() {
 | 
			
		||||
        "" => SCRIPT_FILE,
 | 
			
		||||
        path => path,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Create Engine
 | 
			
		||||
    let engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
    // Create a custom 'Scope' to hold state
 | 
			
		||||
    let mut scope = Scope::new();
 | 
			
		||||
 | 
			
		||||
    // Add any system-provided state into the custom 'Scope'.
 | 
			
		||||
    // Constants can be used to optimize the script.
 | 
			
		||||
    scope.push_constant("MY_CONSTANT", 42_i64);
 | 
			
		||||
 | 
			
		||||
    // Compile the handler script.
 | 
			
		||||
    println!("> Loading script file: {path}");
 | 
			
		||||
 | 
			
		||||
    let ast = match engine.compile_file_with_scope(&scope, path.into()) {
 | 
			
		||||
        Ok(ast) => ast,
 | 
			
		||||
        Err(err) => {
 | 
			
		||||
            eprintln!("! Error: {}", err);
 | 
			
		||||
            println!("Cannot continue. Bye!");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    println!("> Script file loaded.");
 | 
			
		||||
    println!();
 | 
			
		||||
    println!("quit      = exit program");
 | 
			
		||||
    println!("scope     = print scope");
 | 
			
		||||
    println!("event arg = run function with argument");
 | 
			
		||||
    println!();
 | 
			
		||||
 | 
			
		||||
    // Run the 'init' function to initialize the state, retaining variables.
 | 
			
		||||
    let options = CallFnOptions::new().eval_ast(false).rewind_scope(false);
 | 
			
		||||
 | 
			
		||||
    let result = engine.call_fn_with_options::<()>(options, &mut scope, &ast, "init", ());
 | 
			
		||||
 | 
			
		||||
    if let Err(err) = result {
 | 
			
		||||
        eprintln!("! {err}")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create handler instance
 | 
			
		||||
    let mut handler = Handler { engine, scope, ast };
 | 
			
		||||
 | 
			
		||||
    // Events loop
 | 
			
		||||
    loop {
 | 
			
		||||
        print!("event> ");
 | 
			
		||||
        stdout().flush().expect("flush stdout");
 | 
			
		||||
 | 
			
		||||
        // Read event
 | 
			
		||||
        input.clear();
 | 
			
		||||
        stdin().read_line(&mut input).expect("read input");
 | 
			
		||||
 | 
			
		||||
        let mut fields = input.trim().splitn(2, ' ');
 | 
			
		||||
 | 
			
		||||
        let event = fields.next().expect("event").trim();
 | 
			
		||||
        let arg = fields.next().unwrap_or("").to_string();
 | 
			
		||||
 | 
			
		||||
        // Process event
 | 
			
		||||
        match event {
 | 
			
		||||
            "quit" => break,
 | 
			
		||||
 | 
			
		||||
            "scope" => {
 | 
			
		||||
                print_scope(&handler.scope);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Map all other events to function calls
 | 
			
		||||
            _ => {
 | 
			
		||||
                let engine = &handler.engine;
 | 
			
		||||
                let scope = &mut handler.scope;
 | 
			
		||||
                let ast = &handler.ast;
 | 
			
		||||
 | 
			
		||||
                let result = engine.call_fn::<()>(scope, ast, event, (arg,));
 | 
			
		||||
 | 
			
		||||
                if let Err(err) = result {
 | 
			
		||||
                    eprintln!("! {err}")
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    println!("Bye!");
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,56 @@
 | 
			
		||||
//! Implementation of the Event Handler With State Pattern - Main Style
 | 
			
		||||
 | 
			
		||||
/// Initialize user-provided state (shadows system-provided state, if any).
 | 
			
		||||
fn init() {
 | 
			
		||||
    // Add 'bool_state' and 'value' as new state variables
 | 
			
		||||
    let bool_state = false;
 | 
			
		||||
    let value = 0;
 | 
			
		||||
 | 
			
		||||
    // Constants can also be added!
 | 
			
		||||
    const EXTRA_CONSTANT = "hello, world!";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Without 'OOP' support, the can only be a function.
 | 
			
		||||
fn log(value, data) {
 | 
			
		||||
    print(`State = ${value}, data = ${data}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 'start' event handler
 | 
			
		||||
fn start(data) {
 | 
			
		||||
    if bool_state {
 | 
			
		||||
        throw "Already started!";
 | 
			
		||||
    }
 | 
			
		||||
    if value <= 0 {
 | 
			
		||||
        throw "Conditions not yet ready to start!";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Constants 'MY_CONSTANT' and 'EXTRA_CONSTANT'
 | 
			
		||||
    // in custom scope are also visible!
 | 
			
		||||
    print(`MY_CONSTANT = ${MY_CONSTANT}`);
 | 
			
		||||
    print(`EXTRA_CONSTANT = ${EXTRA_CONSTANT}`);
 | 
			
		||||
 | 
			
		||||
    value += parse_int(data);
 | 
			
		||||
    bool_state = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 'end' event handler
 | 
			
		||||
fn end(data) {
 | 
			
		||||
    if !bool_state {
 | 
			
		||||
        throw "Not yet started!";
 | 
			
		||||
    }
 | 
			
		||||
    if value > 0 {
 | 
			
		||||
        throw "Conditions not yet ready to end!";
 | 
			
		||||
    }
 | 
			
		||||
    value = parse_int(data);
 | 
			
		||||
    bool_state = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 'update' event handler
 | 
			
		||||
fn update(data) {
 | 
			
		||||
    let data = parse_int(data);
 | 
			
		||||
 | 
			
		||||
    value += data;
 | 
			
		||||
 | 
			
		||||
    // Without OOP support, can only call function
 | 
			
		||||
    log(value, data);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										151
									
								
								_archive/rhai_engine/rhaiexamples/event_handler_map/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								_archive/rhai_engine/rhaiexamples/event_handler_map/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
			
		||||
//! Implementation of the Event Handler With State Pattern - Map Style
 | 
			
		||||
 | 
			
		||||
#[cfg(any(feature = "no_function", feature = "no_object"))]
 | 
			
		||||
pub fn main() {
 | 
			
		||||
    panic!("This example does not run under 'no_function' or 'no_object'.")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "no_function"))]
 | 
			
		||||
#[cfg(not(feature = "no_object"))]
 | 
			
		||||
pub fn main() {
 | 
			
		||||
    use rhai::{Dynamic, Engine, Map, Scope, AST};
 | 
			
		||||
    use std::io::{stdin, stdout, Write};
 | 
			
		||||
 | 
			
		||||
    const SCRIPT_FILE: &str = "event_handler_map/script.rhai";
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug)]
 | 
			
		||||
    struct Handler {
 | 
			
		||||
        pub engine: Engine,
 | 
			
		||||
        pub scope: Scope<'static>,
 | 
			
		||||
        pub ast: AST,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn print_scope(scope: &Scope) {
 | 
			
		||||
        for (i, (name, constant, value)) in scope.iter_raw().enumerate() {
 | 
			
		||||
            #[cfg(not(feature = "no_closure"))]
 | 
			
		||||
            let value_is_shared = if value.is_shared() { " (shared)" } else { "" };
 | 
			
		||||
            #[cfg(feature = "no_closure")]
 | 
			
		||||
            let value_is_shared = "";
 | 
			
		||||
 | 
			
		||||
            println!(
 | 
			
		||||
                "[{}] {}{}{} = {:?}",
 | 
			
		||||
                i + 1,
 | 
			
		||||
                if constant { "const " } else { "" },
 | 
			
		||||
                name,
 | 
			
		||||
                value_is_shared,
 | 
			
		||||
                *value.read_lock::<Dynamic>().unwrap(),
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        println!();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    println!("Events Handler Example - Map Style");
 | 
			
		||||
    println!("==================================");
 | 
			
		||||
 | 
			
		||||
    let mut input = String::new();
 | 
			
		||||
 | 
			
		||||
    // Read script file
 | 
			
		||||
    print!("Script file [{}]: ", SCRIPT_FILE);
 | 
			
		||||
    stdout().flush().expect("flush stdout");
 | 
			
		||||
 | 
			
		||||
    input.clear();
 | 
			
		||||
 | 
			
		||||
    stdin().read_line(&mut input).expect("read input");
 | 
			
		||||
 | 
			
		||||
    let path = match input.trim() {
 | 
			
		||||
        "" => SCRIPT_FILE,
 | 
			
		||||
        path => path,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Create Engine
 | 
			
		||||
    let mut engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
    // Prevent shadowing of `state`
 | 
			
		||||
    #[allow(deprecated)]
 | 
			
		||||
    engine.on_def_var(|_, info, _| Ok(info.name() != "state"));
 | 
			
		||||
 | 
			
		||||
    // Create a custom 'Scope' to hold state
 | 
			
		||||
    let mut scope = Scope::new();
 | 
			
		||||
 | 
			
		||||
    // Add any system-provided state into the custom 'Scope'.
 | 
			
		||||
    // Constants can be used to optimize the script.
 | 
			
		||||
    scope.push_constant("MY_CONSTANT", 42_i64);
 | 
			
		||||
 | 
			
		||||
    // Use an object map to hold state
 | 
			
		||||
    let mut states = Map::new();
 | 
			
		||||
 | 
			
		||||
    // Default states can be added
 | 
			
		||||
    states.insert("bool_state".into(), Dynamic::FALSE);
 | 
			
		||||
 | 
			
		||||
    // Add the main states-holding object map and call it 'state'
 | 
			
		||||
    scope.push("state", states);
 | 
			
		||||
 | 
			
		||||
    // Compile the handler script.
 | 
			
		||||
    println!("> Loading script file: {path}");
 | 
			
		||||
 | 
			
		||||
    let ast = match engine.compile_file_with_scope(&scope, path.into()) {
 | 
			
		||||
        Ok(ast) => ast,
 | 
			
		||||
        Err(err) => {
 | 
			
		||||
            eprintln!("! Error: {err}");
 | 
			
		||||
            println!("Cannot continue. Bye!");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    println!("> Script file loaded.");
 | 
			
		||||
    println!();
 | 
			
		||||
    println!("quit      = exit program");
 | 
			
		||||
    println!("scope     = print scope");
 | 
			
		||||
    println!("event arg = run function with argument");
 | 
			
		||||
    println!();
 | 
			
		||||
 | 
			
		||||
    // Run the 'init' function to initialize the state, retaining variables.
 | 
			
		||||
    let result = engine.call_fn::<()>(&mut scope, &ast, "init", ());
 | 
			
		||||
 | 
			
		||||
    if let Err(err) = result {
 | 
			
		||||
        eprintln!("! {err}")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create handler instance
 | 
			
		||||
    let mut handler = Handler { engine, scope, ast };
 | 
			
		||||
 | 
			
		||||
    // Events loop
 | 
			
		||||
    loop {
 | 
			
		||||
        print!("event> ");
 | 
			
		||||
        stdout().flush().expect("flush stdout");
 | 
			
		||||
 | 
			
		||||
        // Read event
 | 
			
		||||
        input.clear();
 | 
			
		||||
        stdin().read_line(&mut input).expect("read input");
 | 
			
		||||
 | 
			
		||||
        let mut fields = input.trim().splitn(2, ' ');
 | 
			
		||||
 | 
			
		||||
        let event = fields.next().expect("event").trim();
 | 
			
		||||
        let arg = fields.next().unwrap_or("").to_string();
 | 
			
		||||
 | 
			
		||||
        // Process event
 | 
			
		||||
        match event {
 | 
			
		||||
            "quit" => break,
 | 
			
		||||
 | 
			
		||||
            "scope" => {
 | 
			
		||||
                print_scope(&handler.scope);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Map all other events to function calls
 | 
			
		||||
            _ => {
 | 
			
		||||
                let engine = &handler.engine;
 | 
			
		||||
                let scope = &mut handler.scope;
 | 
			
		||||
                let ast = &handler.ast;
 | 
			
		||||
 | 
			
		||||
                let result = engine.call_fn::<()>(scope, ast, event, (arg,));
 | 
			
		||||
 | 
			
		||||
                if let Err(err) = result {
 | 
			
		||||
                    eprintln!("! {err}")
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    println!("Bye!");
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,58 @@
 | 
			
		||||
//! Implementation of the Event Handler With State Pattern - Map Style
 | 
			
		||||
 | 
			
		||||
/// Initialize user-provided state.
 | 
			
		||||
/// State is stored inside an object map bound to 'state'.
 | 
			
		||||
fn init() {
 | 
			
		||||
    // Add 'bool_state' as new state variable if one does not exist
 | 
			
		||||
    if "bool_state" !in state {
 | 
			
		||||
        state.bool_state = false;
 | 
			
		||||
    }
 | 
			
		||||
    // Add 'obj_state' as new state variable (overwrites any existing)
 | 
			
		||||
    state.value = 0;
 | 
			
		||||
 | 
			
		||||
    // Can also add OOP-style functions!
 | 
			
		||||
    state.log = |x| print(`State = ${this.value}, data = ${x}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 'start' event handler
 | 
			
		||||
fn start(data) {
 | 
			
		||||
    // Can detect system-provided default states!
 | 
			
		||||
    // Access state variables in 'state'
 | 
			
		||||
    if state.bool_state {
 | 
			
		||||
        throw "Already started!";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // New values can be added to the state
 | 
			
		||||
    state.start_mode = data;
 | 
			
		||||
 | 
			
		||||
    if state.value <= 0 {
 | 
			
		||||
        throw "Conditions not yet ready to start!";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Constant 'MY_CONSTANT' in custom scope is also visible!
 | 
			
		||||
    print(`MY_CONSTANT = ${MY_CONSTANT}`);
 | 
			
		||||
 | 
			
		||||
    state.value = parse_int(data);
 | 
			
		||||
    state.bool_state = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 'end' event handler
 | 
			
		||||
fn end(data) {
 | 
			
		||||
    if !state.bool_state || "start_mode" !in state {
 | 
			
		||||
        throw "Not yet started!";
 | 
			
		||||
    }
 | 
			
		||||
    if state.value > 0 {
 | 
			
		||||
        throw "Conditions not yet ready to end!";
 | 
			
		||||
    }
 | 
			
		||||
    state.value = parse_int(data);
 | 
			
		||||
    state.bool_state = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// 'update' event handler
 | 
			
		||||
fn update(data) {
 | 
			
		||||
    let data = parse_int(data);
 | 
			
		||||
    state.value += data;
 | 
			
		||||
 | 
			
		||||
    // Call user-defined function OOP-style!
 | 
			
		||||
    state.log(data);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								_archive/rhai_engine/rhaiexamples/hello.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								_archive/rhai_engine/rhaiexamples/hello.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
//! A simple example that evaluates an expression and prints the result.
 | 
			
		||||
 | 
			
		||||
use rhai::{Engine, EvalAltResult};
 | 
			
		||||
 | 
			
		||||
fn main() -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
    let engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
    engine.run(r#"print("hello, world!")"#)?;
 | 
			
		||||
 | 
			
		||||
    let result = engine.eval::<i64>("40 + 2")?;
 | 
			
		||||
 | 
			
		||||
    println!("The Answer: {result}"); // prints 42
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										112
									
								
								_archive/rhai_engine/rhaiexamples/pause_and_resume.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								_archive/rhai_engine/rhaiexamples/pause_and_resume.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
			
		||||
//! An advanced example showing how to pause/resume/stop an `Engine` via an MPSC channel.
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "unchecked")]
 | 
			
		||||
fn main() {
 | 
			
		||||
    panic!("This example does not run under 'unchecked'.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
use rhai::{Dynamic, Engine};
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "sync")]
 | 
			
		||||
use std::sync::Mutex;
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "unchecked"))]
 | 
			
		||||
fn main() {
 | 
			
		||||
    let (tx, rx) = std::sync::mpsc::channel::<String>();
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "sync")]
 | 
			
		||||
    let rx = Mutex::new(rx);
 | 
			
		||||
 | 
			
		||||
    // Spawn thread with Engine, capturing the channel
 | 
			
		||||
    std::thread::spawn(move || {
 | 
			
		||||
        // Create Engine
 | 
			
		||||
        let mut engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
        engine.on_progress(move |_ops| {
 | 
			
		||||
            #[cfg(feature = "sync")]
 | 
			
		||||
            if _ops % 5 != 0 {
 | 
			
		||||
                return None;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            #[cfg(feature = "sync")]
 | 
			
		||||
            let rx = &*rx.lock().unwrap();
 | 
			
		||||
 | 
			
		||||
            let mut paused = false;
 | 
			
		||||
 | 
			
		||||
            loop {
 | 
			
		||||
                match rx.try_recv() {
 | 
			
		||||
                    Ok(cmd) => match cmd.as_str() {
 | 
			
		||||
                        "pause" => {
 | 
			
		||||
                            println!("[Thread] Script paused. Type 'resume' to continue or 'stop' to terminate.");
 | 
			
		||||
                            paused = true;
 | 
			
		||||
                        }
 | 
			
		||||
                        "resume" => {
 | 
			
		||||
                            println!("[Thread] Resuming script...");
 | 
			
		||||
                            return None;
 | 
			
		||||
                        }
 | 
			
		||||
                        "stop" => {
 | 
			
		||||
                            println!("[Thread] Stopping script...");
 | 
			
		||||
                            return Some(Dynamic::UNIT);
 | 
			
		||||
                        }
 | 
			
		||||
                        cmd if paused => {
 | 
			
		||||
                            println!("[Thread] I don't understand '{cmd}'!");
 | 
			
		||||
                            println!("Type 'resume' to continue script, or 'stop' to terminate!");
 | 
			
		||||
                        }
 | 
			
		||||
                        _ => {
 | 
			
		||||
                            println!("[Thread] I don't understand '{cmd}'!");
 | 
			
		||||
                            return None;
 | 
			
		||||
                        }
 | 
			
		||||
                    },
 | 
			
		||||
                    Err(_) if paused => (),
 | 
			
		||||
                    Err(_) => return None,
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                std::thread::sleep(std::time::Duration::from_millis(100));
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Run script
 | 
			
		||||
        let _ = engine
 | 
			
		||||
            .run(
 | 
			
		||||
                r#"
 | 
			
		||||
                    let counter = 0;
 | 
			
		||||
 | 
			
		||||
                    loop {
 | 
			
		||||
                        print("[Script] One Potato...");
 | 
			
		||||
                        sleep(1);
 | 
			
		||||
 | 
			
		||||
                        counter += 1;
 | 
			
		||||
 | 
			
		||||
                        print("[Script] Two Potatoes...");
 | 
			
		||||
                        sleep(1);
 | 
			
		||||
 | 
			
		||||
                        print(`[Script] Boring Counter: ${counter}...`);
 | 
			
		||||
                        sleep(1);
 | 
			
		||||
 | 
			
		||||
                        print("[Script] Three Potatoes...");
 | 
			
		||||
                        sleep(1);
 | 
			
		||||
                    }
 | 
			
		||||
                "#,
 | 
			
		||||
            )
 | 
			
		||||
            .expect_err("Error expected");
 | 
			
		||||
 | 
			
		||||
        println!("[Thread] Script stopped!");
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    println!("[Main] Type 'pause' or 'stop' to control the script.");
 | 
			
		||||
 | 
			
		||||
    let mut input = String::new();
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
        input.clear();
 | 
			
		||||
 | 
			
		||||
        match std::io::stdin().read_line(&mut input) {
 | 
			
		||||
            Ok(0) => (),
 | 
			
		||||
            Ok(_) => match tx.send(input.trim().to_string()) {
 | 
			
		||||
                Ok(_) => (),
 | 
			
		||||
                Err(_) => break,
 | 
			
		||||
            },
 | 
			
		||||
            Err(_) => break,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								_archive/rhai_engine/rhaiexamples/reuse_scope.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								_archive/rhai_engine/rhaiexamples/reuse_scope.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
//! An example that evaluates two pieces of code in separate runs, but using a common `Scope`.
 | 
			
		||||
 | 
			
		||||
use rhai::{Engine, EvalAltResult, Scope};
 | 
			
		||||
 | 
			
		||||
fn main() -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
    let engine = Engine::new();
 | 
			
		||||
    let mut scope = Scope::new();
 | 
			
		||||
 | 
			
		||||
    engine.run_with_scope(&mut scope, "let x = 4 + 5")?;
 | 
			
		||||
 | 
			
		||||
    println!("x = {}", scope.get_value::<i64>("x").unwrap());
 | 
			
		||||
 | 
			
		||||
    for _ in 0..10 {
 | 
			
		||||
        let result = engine.eval_with_scope::<i64>(&mut scope, "x += 1; x")?;
 | 
			
		||||
 | 
			
		||||
        println!("result: {result}");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    println!("x = {}", scope.get_value::<i64>("x").unwrap());
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								_archive/rhai_engine/rhaiexamples/serde.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								_archive/rhai_engine/rhaiexamples/serde.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
//! An example to serialize and deserialize Rust types.
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "no_object")]
 | 
			
		||||
fn main() {
 | 
			
		||||
    panic!("This example does not run under 'no_object'.")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(not(feature = "no_object"))]
 | 
			
		||||
fn main() {
 | 
			
		||||
    use rhai::serde::{from_dynamic, to_dynamic};
 | 
			
		||||
    use rhai::{Dynamic, Engine, Map};
 | 
			
		||||
    use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 | 
			
		||||
    struct Point {
 | 
			
		||||
        x: f64,
 | 
			
		||||
        y: f64,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
 | 
			
		||||
    struct MyStruct {
 | 
			
		||||
        a: i64,
 | 
			
		||||
        b: Vec<String>,
 | 
			
		||||
        c: bool,
 | 
			
		||||
        d: Point,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn ser() {
 | 
			
		||||
        let x = MyStruct {
 | 
			
		||||
            a: 42,
 | 
			
		||||
            b: vec!["hello".into(), "world".into()],
 | 
			
		||||
            c: true,
 | 
			
		||||
            d: Point {
 | 
			
		||||
                x: 123.456,
 | 
			
		||||
                y: 999.0,
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        println!("Source struct: {x:#?}");
 | 
			
		||||
 | 
			
		||||
        // Convert the 'MyStruct' into a 'Dynamic'
 | 
			
		||||
        let map: Dynamic = to_dynamic(x).unwrap();
 | 
			
		||||
 | 
			
		||||
        assert!(map.is::<Map>());
 | 
			
		||||
        println!("Serialized to Dynamic: {map:#?}");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn de() {
 | 
			
		||||
        let engine = Engine::new();
 | 
			
		||||
        let result: Dynamic = engine
 | 
			
		||||
            .eval(
 | 
			
		||||
                r#"
 | 
			
		||||
                        #{
 | 
			
		||||
                            a: 42,
 | 
			
		||||
                            b: [ "hello", "world" ],
 | 
			
		||||
                            c: true,
 | 
			
		||||
                            d: #{ x: 123.456, y: 999.0 }
 | 
			
		||||
                        }
 | 
			
		||||
                    "#,
 | 
			
		||||
            )
 | 
			
		||||
            .unwrap();
 | 
			
		||||
 | 
			
		||||
        println!("Source Dynamic: {result:#?}");
 | 
			
		||||
 | 
			
		||||
        // Convert the 'Dynamic' object map into 'MyStruct'
 | 
			
		||||
        let x: MyStruct = from_dynamic(&result).unwrap();
 | 
			
		||||
 | 
			
		||||
        assert_eq!(
 | 
			
		||||
            x,
 | 
			
		||||
            MyStruct {
 | 
			
		||||
                a: 42,
 | 
			
		||||
                b: vec!["hello".into(), "world".into()],
 | 
			
		||||
                c: true,
 | 
			
		||||
                d: Point {
 | 
			
		||||
                    x: 123.456,
 | 
			
		||||
                    y: 999.0,
 | 
			
		||||
                },
 | 
			
		||||
            }
 | 
			
		||||
        );
 | 
			
		||||
        println!("Deserialized to struct: {x:#?}");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ser();
 | 
			
		||||
    println!();
 | 
			
		||||
    de();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										19
									
								
								_archive/rhai_engine/rhaiexamples/simple_fn.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								_archive/rhai_engine/rhaiexamples/simple_fn.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
//! An example showing how to register a simple Rust function.
 | 
			
		||||
 | 
			
		||||
use rhai::{Engine, EvalAltResult};
 | 
			
		||||
 | 
			
		||||
fn add(x: i64, y: i64) -> i64 {
 | 
			
		||||
    x + y
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
    let mut engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
    engine.register_fn("add", add);
 | 
			
		||||
 | 
			
		||||
    let result = engine.eval::<i64>("add(40, 2)")?;
 | 
			
		||||
 | 
			
		||||
    println!("Answer: {result}"); // prints 42
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								_archive/rhai_engine/rhaiexamples/strings.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								_archive/rhai_engine/rhaiexamples/strings.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
//! An example that registers a variety of functions that operate on strings.
 | 
			
		||||
//! Remember to use `ImmutableString` or `&str` instead of `String` as parameters.
 | 
			
		||||
 | 
			
		||||
use rhai::{Engine, EvalAltResult, ImmutableString, Scope};
 | 
			
		||||
use std::io::{stdin, stdout, Write};
 | 
			
		||||
 | 
			
		||||
/// Trim whitespace from a string. The original string argument is changed.
 | 
			
		||||
///
 | 
			
		||||
/// This version uses `&mut ImmutableString`
 | 
			
		||||
fn trim_string(s: &mut ImmutableString) {
 | 
			
		||||
    *s = s.trim().into();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Notice this is different from the built-in Rhai 'len' function for strings
 | 
			
		||||
/// which counts the actual number of Unicode _characters_ in a string.
 | 
			
		||||
///
 | 
			
		||||
/// This version simply counts the number of _bytes_ in the UTF-8 representation.
 | 
			
		||||
///
 | 
			
		||||
/// This version uses `&str`.
 | 
			
		||||
fn count_string_bytes(s: &str) -> i64 {
 | 
			
		||||
    s.len() as i64
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// This version uses `ImmutableString` and `&str`.
 | 
			
		||||
fn find_substring(s: ImmutableString, sub: &str) -> i64 {
 | 
			
		||||
    s.find(sub).map(|x| x as i64).unwrap_or(-1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
    // Create a `raw` Engine with no built-in string functions.
 | 
			
		||||
    let mut engine = Engine::new_raw();
 | 
			
		||||
 | 
			
		||||
    engine
 | 
			
		||||
        // Register string functions
 | 
			
		||||
        .register_fn("trim", trim_string)
 | 
			
		||||
        .register_fn("len", count_string_bytes)
 | 
			
		||||
        .register_fn("index_of", find_substring)
 | 
			
		||||
        // Register string functions using closures
 | 
			
		||||
        .register_fn("display", |label: &str, value: i64| {
 | 
			
		||||
            println!("{label}: {value}")
 | 
			
		||||
        })
 | 
			
		||||
        .register_fn("display", |label: ImmutableString, value: &str| {
 | 
			
		||||
            println!(r#"{label}: "{value}""#) // Quote the input string
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    let mut scope = Scope::new();
 | 
			
		||||
    let mut input = String::new();
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
        scope.clear();
 | 
			
		||||
 | 
			
		||||
        println!("Type something. Press Ctrl-C to exit.");
 | 
			
		||||
        print!("strings> ");
 | 
			
		||||
        stdout().flush().expect("couldn't flush stdout");
 | 
			
		||||
 | 
			
		||||
        input.clear();
 | 
			
		||||
 | 
			
		||||
        if let Err(err) = stdin().read_line(&mut input) {
 | 
			
		||||
            panic!("input error: {}", err);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        scope.push("x", input.clone());
 | 
			
		||||
 | 
			
		||||
        println!("Line: {}", input.replace('\r', "\\r").replace('\n', "\\n"));
 | 
			
		||||
 | 
			
		||||
        engine.run_with_scope(
 | 
			
		||||
            &mut scope,
 | 
			
		||||
            r#"
 | 
			
		||||
                display("Length", x.len());
 | 
			
		||||
                x.trim();
 | 
			
		||||
                display("Trimmed", x);
 | 
			
		||||
                display("Trimmed Length", x.len());
 | 
			
		||||
                display("Index of \"!!!\"", x.index_of("!!!"));
 | 
			
		||||
            "#,
 | 
			
		||||
        )?;
 | 
			
		||||
 | 
			
		||||
        println!();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								_archive/rhai_engine/rhaiexamples/threading.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								_archive/rhai_engine/rhaiexamples/threading.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
//! An advanced example showing how to communicate with an `Engine` running in a separate thread via
 | 
			
		||||
//! an MPSC channel.
 | 
			
		||||
 | 
			
		||||
use rhai::Engine;
 | 
			
		||||
 | 
			
		||||
#[cfg(feature = "sync")]
 | 
			
		||||
use std::sync::Mutex;
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    // Channel: Script -> Master
 | 
			
		||||
    let (tx_script, rx_master) = std::sync::mpsc::channel();
 | 
			
		||||
    // Channel: Master -> Script
 | 
			
		||||
    let (tx_master, rx_script) = std::sync::mpsc::channel();
 | 
			
		||||
 | 
			
		||||
    #[cfg(feature = "sync")]
 | 
			
		||||
    let (tx_script, rx_script) = (Mutex::new(tx_script), Mutex::new(rx_script));
 | 
			
		||||
 | 
			
		||||
    // Spawn thread with Engine
 | 
			
		||||
    std::thread::spawn(move || {
 | 
			
		||||
        // Create Engine
 | 
			
		||||
        let mut engine = Engine::new();
 | 
			
		||||
 | 
			
		||||
        // Register API
 | 
			
		||||
        // Notice that the API functions are blocking
 | 
			
		||||
 | 
			
		||||
        #[cfg(not(feature = "sync"))]
 | 
			
		||||
        engine
 | 
			
		||||
            .register_fn("get", move || rx_script.recv().unwrap_or_default())
 | 
			
		||||
            .register_fn("put", move |v: i64| tx_script.send(v).unwrap());
 | 
			
		||||
 | 
			
		||||
        #[cfg(feature = "sync")]
 | 
			
		||||
        engine
 | 
			
		||||
            .register_fn("get", move || rx_script.lock().unwrap().recv().unwrap())
 | 
			
		||||
            .register_fn("put", move |v: i64| {
 | 
			
		||||
                tx_script.lock().unwrap().send(v).unwrap()
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        // Run script
 | 
			
		||||
        engine
 | 
			
		||||
            .run(
 | 
			
		||||
                r#"
 | 
			
		||||
                    print("Starting script loop...");
 | 
			
		||||
 | 
			
		||||
                    loop {
 | 
			
		||||
                        let x = get();
 | 
			
		||||
                        print(`Script Read: ${x}`);
 | 
			
		||||
                        x += 1;
 | 
			
		||||
                        print(`Script Write: ${x}`);
 | 
			
		||||
                        put(x);
 | 
			
		||||
                    }
 | 
			
		||||
                "#,
 | 
			
		||||
            )
 | 
			
		||||
            .unwrap();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // This is the main processing thread
 | 
			
		||||
 | 
			
		||||
    println!("Starting main loop...");
 | 
			
		||||
 | 
			
		||||
    let mut value: i64 = 0;
 | 
			
		||||
 | 
			
		||||
    while value < 10 {
 | 
			
		||||
        println!("Value: {value}");
 | 
			
		||||
        // Send value to script
 | 
			
		||||
        tx_master.send(value).unwrap();
 | 
			
		||||
        // Receive value from script
 | 
			
		||||
        value = rx_master.recv().unwrap();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user