Closed KaiserKarel closed 4 years ago
First of all, the API for call_fn
is not ideal, especially when dealing with functions taking one argument. A new version will land in crates.io soon that has a different API, so I suggest you pull directly from this repo to get it. For functions with one argument, you call call_fn1
which takes an AST
and any argument.
let ast = engine.compile(&script)?;
engine.call_fn1(Scope::new(), &ast, "main", copy)?;
The value in copy
, regardless of what it is, will show up as the arg
argument in main
.
An thanks; so this would be the idiomatic way to call scripts which always have a main function?
On a sidenote; is there a way to store the ast; so that I can store ASTs instead of the raw scripts to save on some computational overhead?
On a sidenote; is there a way to store the ast; so that I can store ASTs instead of the raw scripts to save on some computational overhead?
This is one of the outstanding issues (see https://github.com/jonathandturner/rhai/issues/100). However, I wonder how useful it'll be, since persisting an AST
is most likely less efficient than persisting the script text itself -- which can be compressed etc.
Parsing the script doesn't take much time or resources, so it is probably not worth it unless you have really large scripts.
An thanks; so this would be the idiomatic way to call scripts which always have a main function?
Yes. Compiling to AST
and then repeatedly calling call_fn
to access one function is the correct way of calling Rhai functions from Rust.
If you only need to call it once, you can omit the main
function and just put the body of the main
function as the script text itself. Then you can simply evaluate the script.
call_fn
is for you to call a script multiple times.
Being able to persist an AST would allow for persisting optimization, as well as guaranteeing that the script is valid rhai.
Once you successfully parse a script, you know it is valid. When you store it and retrieve it later, it will not suddenly become invalid...
Yeah, right now it doesn't make much sense, as parsing and optimizing is cheap, however you are repeating work. There might be cases where parsing and running do not happen that consecutively.
I'm actually toying with the idea of further compiling the AST into byte-code. That would give more speed plus an easily persistable data format. However, I'm still wondering whether it'd be worth doing, as currently I don't run massively parallel scripts under heavy loading.
Reading through some of the issues; this would definitely be useful for ECS; an easy option would also be to add a serde feature flag; to compare speeds between deserializing from bincode and just reparsing for example.
I'm trying to call a function which I previously registered using engine.consume; however rhai types the argument as dynamic.
How do I have rhai use the registered Args type?