polyhorn_android_sys/
runnable.rs1use jni::objects::JValue;
2use jni::sys::{jobject, JNIEnv};
3use jni::NativeMethod;
4
5use super::{Env, Reference};
6
7pub struct Runnable {
8 reference: Reference,
9}
10
11struct RunnableClosure(Box<dyn FnOnce(&Env) + Send>);
12
13impl Runnable {
14 pub fn new<F>(env: &Env, closure: F) -> Runnable
15 where
16 F: FnOnce(&Env) + Send + 'static,
17 {
18 extern "C" fn main(env: *mut JNIEnv, _: jobject, data: i64) {
19 unsafe {
20 log::error!("Invoking closure.");
21 let closure = Box::<RunnableClosure>::from_raw(data as *mut _);
22 closure.0(&Env::new(env));
23 }
24 }
25
26 unsafe {
27 env.register_natives(
28 "com/glacyr/polyhorn/Runnable",
29 vec![NativeMethod {
30 name: "main".to_owned().into(),
31 sig: "(J)V".to_owned().into(),
32 fn_ptr: main as *mut _,
33 }],
34 );
35
36 let closure = Box::new(RunnableClosure(Box::new(closure)));
37 Runnable {
38 reference: env.retain(env.call_constructor(
39 "com/glacyr/polyhorn/Runnable",
40 "(J)V",
41 &[JValue::Long(Box::into_raw(closure) as i64)],
42 )),
43 }
44 }
45 }
46
47 pub fn queue(self, env: &Env) {
48 log::error!("Queueing runnable.");
49 unsafe {
50 env.call_method(self.reference.as_object(), "queue", "()V", &[]);
51 }
52 }
53}