polyhorn_android_sys/
thread.rs

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