Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Operate scope in context #506

Closed
cn-kali-team opened this issue Jan 14, 2022 · 6 comments
Closed

Operate scope in context #506

cn-kali-team opened this issue Jan 14, 2022 · 6 comments
Labels

Comments

@cn-kali-team
Copy link

  • my script code
fn main{
  push_item("some data");
}
  • I define an array in scope,Execute the script to get the results
let mut scope = Scope::new();
scope.set_or_push("list",[""]);
self.engine.call_fn(&mut scope, &ast, "main", (target.clone(),))?;
let list = scope.get_value::<Array>("list").unwrap_or_default();
println!("{:?}",list);
  • register_fn
use rhai::plugin::*;

fn push_item(context: NativeCallContext,item:&str){
    println!("{:#?}",context);
    // I want to find the list in the scope in the context and add the item to the list
    // #TODO 
    let mut list = context.scope.get_value::<Array>("list").unwrap_or_default();
    list.pust(item);
    context.scope.set_or_push("list",list);
}

pub fn register_context_ctx(engine: &mut Engine) {
    engine.register_fn("push_item",push_item);
}
  • Maybe I can write scripts like this, but I want to reduce the difficulty of writing scripts. Sometimes I forget to define list
  • Or I want to make scripting more standardized and make it a framework
let list = [];
fn main(){
    list.pust("some data");
}
  • This is better
fn main{
  push_item("some data");
}
@schungx
Copy link
Collaborator

schungx commented Jan 14, 2022

You seem to be using scripts to program event handlers, modifying global state.

This may match what you want: https://rhai.rs/book/patterns/events.html

@cn-kali-team
Copy link
Author

okay, thank you

@cn-kali-team
Copy link
Author

  • But it seems that it needs to create the engine and scope repeatedly, which is expensive. I've tried
  • The variable scope found cannot be used in the second function, Is this normal? Why is it designed like this?
let mut engine = Engine::new();
let ast = engine.compile_(script_code);
let mut scope = Scope::new();
scope.set_or_push("host", "127.0.0.1");
engine.run_ast_with_scope(&mut scope, &ast)?;
  • script code
fn push_item(s) {
    print(host);
}
print(host);
push_item("A");
  • err
127.0.0.1
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Variable not found: host (line 2, position 11) in call to function push_item (line 5, position 1)'
let mut engine = Engine::new();
let ast = engine.compile_(script_code);
let mut scope = Scope::new();
scope.set_or_push("host", "127.0.0.1");
engine.call_fn(&mut scope, &ast, "verify", (host,))?;
  • script code
fn push_item(s) {
    print(host);
}
fn verify(s){
    print(host);
    push_item(host);
}
  • err
127.0.0.1
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Variable not found: host (line 2, position 11) in call to function push_item < verify', src/main.rs:14:49
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

@schungx
Copy link
Collaborator

schungx commented Jan 15, 2022

Functions cannot access the global scope. Functions are pure.

Bind host to the this pointer in your function call and it'll work for you:

fn push_item(s) {
    print(this);
}

host.push_item("A");

If you just want read access, pass it as a parameter.

@schungx
Copy link
Collaborator

schungx commented Jan 15, 2022

But it seems that it needs to create the engine and scope repeatedly, which is expensive. I've tried

No it doesn't. As per the example, it is created once and kept alive inside a Handler type.

@schungx
Copy link
Collaborator

schungx commented Jan 23, 2022

Has this issue been resolved?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants