Skip to content

Commit bcbee51

Browse files
kkaeferjfirebaugh
authored andcommitted
Add Local ref methods and wrappers
1 parent 6afa20e commit bcbee51

File tree

4 files changed

+83
-4
lines changed

4 files changed

+83
-4
lines changed

include/jni/functions.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,14 +145,18 @@ namespace jni
145145

146146

147147
template < class T >
148-
T* NewLocalRef(JNIEnv& env, T* ref)
148+
UniqueLocalRef<T> NewLocalRef(JNIEnv& env, T* t)
149149
{
150-
return CheckJavaException(env, Wrap<T*>(env.NewLocalRef(Unwrap(ref))));
150+
jobject* obj = Wrap<jobject*>(env.NewLocalRef(Unwrap(t)));
151+
CheckJavaException(env);
152+
if (t && !obj)
153+
throw std::bad_alloc();
154+
return UniqueLocalRef<T>(reinterpret_cast<T*>(obj), LocalRefDeleter(env));
151155
}
152156

153-
inline void DeleteLocalRef(JNIEnv& env, jobject* localRef)
157+
inline void DeleteLocalRef(JNIEnv& env, UniqueLocalRef<jobject>&& ref)
154158
{
155-
env.DeleteLocalRef(Unwrap(localRef));
159+
env.DeleteLocalRef(Unwrap(ref.release()));
156160
CheckJavaException(env);
157161
}
158162

include/jni/object.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ namespace jni
3232
template < class TagType = ObjectTag >
3333
using UniqueWeakObject = std::unique_ptr< const Object<TagType>, WeakObjectRefDeleter<TagType> >;
3434

35+
template < class TagType >
36+
class LocalObjectRefDeleter;
37+
38+
template < class TagType = ObjectTag >
39+
using UniqueLocalObject = std::unique_ptr< const Object<TagType>, LocalObjectRefDeleter<TagType> >;
40+
3541
template < class TheTag = ObjectTag >
3642
class Object
3743
{
@@ -141,6 +147,11 @@ namespace jni
141147
return SeizeWeakRef(env, Object(jni::NewWeakGlobalRef(env, obj).release()));
142148
}
143149

150+
UniqueLocalObject<TagType> NewLocalRef(JNIEnv& env) const
151+
{
152+
return SeizeLocalRef(env, Object(jni::NewLocalRef(env, obj).release()));
153+
}
154+
144155
template < class OtherTag >
145156
bool IsInstanceOf(JNIEnv& env, const Class<OtherTag>& clazz) const
146157
{
@@ -204,6 +215,34 @@ namespace jni
204215
return UniqueWeakObject<TagType>(PointerToValue<Object<TagType>>(std::move(object)), WeakObjectRefDeleter<TagType>(env));
205216
};
206217

218+
template < class TagType >
219+
class LocalObjectRefDeleter
220+
{
221+
private:
222+
JNIEnv* env = nullptr;
223+
224+
public:
225+
using pointer = PointerToValue< Object<TagType> >;
226+
227+
LocalObjectRefDeleter() = default;
228+
LocalObjectRefDeleter(JNIEnv& e) : env(&e) {}
229+
230+
void operator()(pointer p) const
231+
{
232+
if (p)
233+
{
234+
assert(env);
235+
env->DeleteLocalRef(Unwrap(p->Get()));
236+
}
237+
}
238+
};
239+
240+
template < class TagType >
241+
UniqueLocalObject<TagType> SeizeLocalRef(JNIEnv& env, Object<TagType>&& object)
242+
{
243+
return UniqueLocalObject<TagType>(PointerToValue<Object<TagType>>(std::move(object)), LocalObjectRefDeleter<TagType>(env));
244+
};
245+
207246

208247
template < class OutTagType, class InTagType >
209248
Object<OutTagType> Cast(JNIEnv& env, const Object<InTagType>& object, const Class<OutTagType>& clazz)

include/jni/ownership.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,29 @@ namespace jni
6666
using UniqueWeakGlobalRef = std::unique_ptr< T, WeakGlobalRefDeleter >;
6767

6868

69+
class LocalRefDeleter
70+
{
71+
private:
72+
JNIEnv* env = nullptr;
73+
74+
public:
75+
LocalRefDeleter() = default;
76+
LocalRefDeleter(JNIEnv& e) : env(&e) {}
77+
78+
void operator()(jobject* p) const
79+
{
80+
if (p)
81+
{
82+
assert(env);
83+
env->DeleteLocalRef(Unwrap(p));
84+
}
85+
}
86+
};
87+
88+
template < class T >
89+
using UniqueLocalRef = std::unique_ptr< T, LocalRefDeleter >;
90+
91+
6992
class StringCharsDeleter
7093
{
7194
private:

test/high_level.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ int main()
7272

7373
static bool calledNewGlobalRef = false;
7474
static bool calledNewWeakGlobalRef = false;
75+
static bool calledNewLocalRef = false;
7576

7677
env.functions->NewGlobalRef = [] (JNIEnv*, jobject obj) -> jobject
7778
{
@@ -93,6 +94,16 @@ int main()
9394
{
9495
};
9596

97+
env.functions->NewLocalRef = [] (JNIEnv*, jobject obj) -> jobject
98+
{
99+
calledNewLocalRef = true;
100+
return obj;
101+
};
102+
103+
env.functions->DeleteLocalRef = [] (JNIEnv*, jobject) -> void
104+
{
105+
};
106+
96107
testClass.NewGlobalRef(env);
97108
assert(calledNewGlobalRef);
98109

@@ -102,10 +113,12 @@ int main()
102113
jni::Object<Test> object { objectValue.Ptr() };
103114
object.NewGlobalRef(env);
104115
object.NewWeakGlobalRef(env);
116+
object.NewLocalRef(env);
105117

106118
jni::String string { stringValue.Ptr() };
107119
string.NewGlobalRef(env);
108120
string.NewWeakGlobalRef(env);
121+
string.NewLocalRef(env);
109122

110123

111124
/// Constructor

0 commit comments

Comments
 (0)