Skip to content

Instantly share code, notes, and snippets.

@timfish
Last active April 12, 2021 23:46
Show Gist options
  • Save timfish/e57e0d912d90e740a6d111c84f0b2809 to your computer and use it in GitHub Desktop.
Save timfish/e57e0d912d90e740a6d111c84f0b2809 to your computer and use it in GitHub Desktop.
use rhai::{plugin::*, Engine, FnPtr};
use std::{
sync::{Arc, Mutex},
thread,
time::Duration,
};
#[derive(Debug, Clone)]
pub struct Service {
func: Arc<Mutex<Option<FnPtr>>>,
}
impl Service {
pub fn set_callback(&mut self, func: FnPtr) {
let mut f = self.func.lock().unwrap();
*f = Some(func);
}
pub fn run(&mut self, ctx: NativeCallContext) {
let ctx = Arc::new(Mutex::new(ctx));
thread::spawn({
let func = self.func.clone();
let ctx = ctx.clone();
move || {
let mut i = 1;
while i < 11 {
let f = func.lock().unwrap();
if let Some(func) = &*f {
let ctx = ctx.lock().unwrap();
func.call_dynamic(&*ctx, None, [Dynamic::from(9)]).unwrap();
}
thread::sleep(Duration::from_secs(1));
i += 1;
}
}
})
.join()
.unwrap();
}
}
#[export_module]
mod my_module {
use rhai::{FnPtr, NativeCallContext};
pub fn create() -> Service {
Service {
func: Arc::new(Mutex::new(None)),
}
}
#[rhai_fn(global)]
pub fn set_callback(this: &mut Service, func: FnPtr) {
this.set_callback(func);
}
#[rhai_fn(global)]
pub fn run(ctx: NativeCallContext, this: &mut Service) {
this.run(ctx);
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut engine = Engine::new();
// The macro call creates a Rhai module from the plugin module.
let module = exported_module!(my_module);
engine.register_type_with_name::<Service>("Service");
engine.register_static_module("service", module.into());
engine.eval(
r#"
let service = service::create();
service.set_callback(|v| {
print("here " + v);
});
service.run();
"#,
)?;
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment