Questions about control plane / config use case (TLDR: why not (ab)use the engine tag?) #893
-
My use case seems to fit somewhere between https://rhai.rs/book/patterns/control.html and/or https://rhai.rs/book/patterns/singleton.html as well as https://rhai.rs/book/patterns/config.html For the first and third pattern I find that the recommended approach of not using plugins but instead using closures for everything makes my code awkward, especially since I have quite a few complex functions that I want to put into different static modules. The second option means that I need to mention this global object (or several global objects if I want to present a grouped API) everywhere in the rhai script. But there seems to be a simpler to use third option, and I'm wondering why it isn't mentioned (such as if there is any big draw backs): Is there a reason to simply not put my state into a So my functions would look something like: struct AccumulatedState {
// ...
}
type AccumulatedStateRef = rhai::Shared<rhai::Locked<AccumulatedState>>;
// This would be in some exported plugin module
pub fn myfunc(ctx: NativeCallContext, /* ... */) -> /* ... */ {
let tag = ctx.tag().expect("Has a tag");
let state = tag.clone_cast::<AccumulatedStateRef>();
let state = state.borrow_mut();
// ...
}
// When creating the engine
fn my_setup() -> rhai::Engine {
// ...
let state = AccumulatedStateRef = Default::default();
// Clone it here, we also need to store it elsewhere for use after the configs have been loaded to apply them to the system
engine.set_default_tag(Dynamic::from(rhai::Shared::clone(&state)));
// ...
} As far as I understand this engine tag is not accessible directly from the rhai script (unlike The above builds (but I haven't been able to test it yet, since I don't have enough of my program done so that I can run anything currently, working towards that with just a couple of simple functions). |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
This is absolutely a legit way to use the We need closures because you need a way to access the context object inside the functions. It can either be a captured variable in a closure, or some API on the call context. One pitfall is that you only have one |
Beta Was this translation helpful? Give feedback.
This is absolutely a legit way to use the
tag
, which was actually created to avoid having to use closures.We need closures because you need a way to access the context object inside the functions. It can either be a captured variable in a closure, or some API on the call context.
One pitfall is that you only have one
tag
and if you want to keep several shared objects you need to put them inside a map inside thetag
... Using a closure is much easier.