Closed lammermann closed 4 years ago
Check out side_effects.rs
in tests
.
You'll need to use Rc
-wrapped interior mutable wrappers, e.g. Rc<RefCell>
, to access anything that is mutable from a script.
The reason being that Engine
instances can be shared and are re-entrant, so they cannot hold FnMut
's.
It is better this way because you can more easily group all side-effects in a central location.
Thanks for the very quick response. I try this out right now.
It seems I'm getting livetime errors. I try to call rhai inside a function and wrapping self
. However rhai seems to expect a static
livetime (even though the engine itself lives only in that same function).
Is there any way I can work around this?
It expects 'static
because it is re-entrant, so you can technically use one instance of Engine
in a massively-parallel way.
But because of this, you have to go through some hoops for Rhai to mutate external state - it is rather dangerous if you think about it, that a text script should be allowed to mutate state outside of the scripting engine.
I suggest that you carefully design your types to make this work seamlessly. What you need is basically Rc<RefCell<T>>
that allows you to keep state outside of the Engine
, share a link to it via a variable into Rhai, and then use Rhai to call methods on that link. Mutability is achieved through the RefCell
.
even though the engine itself lives only in that same function
Although Engine
creation is cheap, you still have to deal with setting it up properly, packages, registering functions etc. So creating one Engine
during each script run may not be very efficient - unless all you do is to run one single script one single time. It is much better to create a shared instance of an Engine
, set it up once, then use it for all your scripts.
Thank you for your advice. I adjusted my types to work correctly.
Going to close this now.
Hi, in my use case I would like to register a closure in via
engine.register_fn
which executes a side effect in my surrounding environment but when I try to do this I get a compile error which says:Is it possible to support
FnMut
inregister_fn
? Is there a other way to archive this? Or a workaround?Thanks very much in advance.