java_spaghetti/refs/
global.rs1use std::marker::PhantomData;
2
3use jni_sys::*;
4
5use crate::{Env, Local, Ref, ReferenceType, VM};
6
7pub struct Global<T: ReferenceType> {
19 object: jobject,
20 vm: VM,
21 pd: PhantomData<T>,
22}
23
24unsafe impl<T: ReferenceType> Send for Global<T> {}
25unsafe impl<T: ReferenceType> Sync for Global<T> {}
26
27impl<T: ReferenceType> Global<T> {
28 pub unsafe fn from_raw(vm: VM, object: jobject) -> Self {
29 Self {
30 object,
31 vm,
32 pd: PhantomData,
33 }
34 }
35
36 pub fn vm(&self) -> VM {
37 self.vm
38 }
39
40 pub fn as_raw(&self) -> jobject {
41 self.object
42 }
43
44 pub fn into_raw(self) -> jobject {
45 let object = self.object;
46 std::mem::forget(self); object
48 }
49
50 pub fn as_local<'env>(&self, env: Env<'env>) -> Local<'env, T> {
51 let jnienv = env.as_raw();
52 let object = unsafe { ((**jnienv).v1_2.NewLocalRef)(jnienv, self.as_raw()) };
53 unsafe { Local::from_raw(env, object) }
54 }
55
56 pub fn as_ref<'env>(&'env self, env: Env<'env>) -> Ref<'env, T> {
57 unsafe { Ref::from_raw(env, self.object) }
58 }
59}
60
61impl<'env, T: ReferenceType> From<Local<'env, T>> for Global<T> {
62 fn from(x: Local<'env, T>) -> Self {
63 x.as_global()
64 }
65}
66
67impl<'env, T: ReferenceType> From<Ref<'env, T>> for Global<T> {
68 fn from(x: Ref<'env, T>) -> Self {
69 x.as_global()
70 }
71}
72
73impl<'env, T: ReferenceType> From<&Local<'env, T>> for Global<T> {
74 fn from(x: &Local<'env, T>) -> Self {
75 x.as_global()
76 }
77}
78
79impl<'env, T: ReferenceType> From<&Ref<'env, T>> for Global<T> {
80 fn from(x: &Ref<'env, T>) -> Self {
81 x.as_global()
82 }
83}
84
85impl<T: ReferenceType> Clone for Global<T> {
86 fn clone(&self) -> Self {
87 self.vm.with_env(|env| {
88 let env = env.as_raw();
89 let object = unsafe { ((**env).v1_2.NewGlobalRef)(env, self.object) };
90 Self {
91 object,
92 vm: self.vm,
93 pd: PhantomData,
94 }
95 })
96 }
97}
98
99impl<T: ReferenceType> Drop for Global<T> {
100 fn drop(&mut self) {
101 self.vm.with_env(|env| {
102 let env = env.as_raw();
103 unsafe { ((**env).v1_2.DeleteGlobalRef)(env, self.object) }
104 });
105 }
106}