use std::ptr::null_mut;
use jni_sys::*;
use crate::Env;
#[repr(transparent)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct VM(*mut JavaVM);
impl VM {
pub fn as_raw(&self) -> *mut JavaVM {
self.0
}
pub unsafe fn from_raw(vm: *mut JavaVM) -> Self {
Self(vm)
}
pub fn with_env<F, R>(&self, callback: F) -> R
where
F: for<'env> FnOnce(Env<'env>) -> R,
{
let mut env = null_mut();
match unsafe { ((**self.0).v1_2.GetEnv)(self.0, &mut env, JNI_VERSION_1_2) } {
JNI_OK => callback(unsafe { Env::from_raw(env as _) }),
JNI_EDETACHED => match unsafe { ((**self.0).v1_2.AttachCurrentThread)(self.0, &mut env, null_mut()) } {
JNI_OK => callback(unsafe { Env::from_raw(env as _) }),
unexpected => panic!("AttachCurrentThread returned unknown error: {}", unexpected),
},
JNI_EVERSION => panic!("GetEnv returned JNI_EVERSION"),
unexpected => panic!("GetEnv returned unknown error: {}", unexpected),
}
}
}
unsafe impl Send for VM {}
unsafe impl Sync for VM {}