use std::marker::PhantomData;
use jni_sys::*;
use crate::{Env, Local, Ref, ReferenceType, VM};
pub struct Global<T: ReferenceType> {
object: jobject,
vm: VM,
pd: PhantomData<T>,
}
unsafe impl<T: ReferenceType> Send for Global<T> {}
unsafe impl<T: ReferenceType> Sync for Global<T> {}
impl<T: ReferenceType> Global<T> {
pub unsafe fn from_raw(vm: VM, object: jobject) -> Self {
Self {
object,
vm,
pd: PhantomData,
}
}
pub fn vm(&self) -> VM {
self.vm
}
pub fn as_raw(&self) -> jobject {
self.object
}
pub fn into_raw(self) -> jobject {
let object = self.object;
std::mem::forget(self); object
}
pub fn as_local<'env>(&self, env: Env<'env>) -> Local<'env, T> {
let jnienv = env.as_raw();
let object = unsafe { ((**jnienv).v1_2.NewLocalRef)(jnienv, self.as_raw()) };
unsafe { Local::from_raw(env, object) }
}
pub fn as_ref<'env>(&'env self, env: Env<'env>) -> Ref<'env, T> {
unsafe { Ref::from_raw(env, self.object) }
}
}
impl<'env, T: ReferenceType> From<Local<'env, T>> for Global<T> {
fn from(x: Local<'env, T>) -> Self {
x.as_global()
}
}
impl<'env, T: ReferenceType> From<Ref<'env, T>> for Global<T> {
fn from(x: Ref<'env, T>) -> Self {
x.as_global()
}
}
impl<'env, T: ReferenceType> From<&Local<'env, T>> for Global<T> {
fn from(x: &Local<'env, T>) -> Self {
x.as_global()
}
}
impl<'env, T: ReferenceType> From<&Ref<'env, T>> for Global<T> {
fn from(x: &Ref<'env, T>) -> Self {
x.as_global()
}
}
impl<T: ReferenceType> Clone for Global<T> {
fn clone(&self) -> Self {
self.vm.with_env(|env| {
let env = env.as_raw();
let object = unsafe { ((**env).v1_2.NewGlobalRef)(env, self.object) };
Self {
object,
vm: self.vm,
pd: PhantomData,
}
})
}
}
impl<T: ReferenceType> Drop for Global<T> {
fn drop(&mut self) {
self.vm.with_env(|env| {
let env = env.as_raw();
unsafe { ((**env).v1_2.DeleteGlobalRef)(env, self.object) }
});
}
}