[Android] jni: Add a wrapper to automatically release localrefs
Hugo Beauzée-Luyssen
git at videolan.org
Mon Sep 27 09:18:54 UTC 2021
vlc-android | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Fri Sep 24 12:11:00 2021 +0200| [e76b3a13aa8a2664844e0b60a38f85686f4fe9fb] | committer: Nicolas Pomepuy
jni: Add a wrapper to automatically release localrefs
> https://code.videolan.org/videolan/vlc-android/commit/e76b3a13aa8a2664844e0b60a38f85686f4fe9fb
---
medialibrary/jni/utils.h | 96 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/medialibrary/jni/utils.h b/medialibrary/jni/utils.h
index a138a74e8..8a955d98c 100644
--- a/medialibrary/jni/utils.h
+++ b/medialibrary/jni/utils.h
@@ -39,8 +39,104 @@
#include <medialibrary/IBookmark.h>
#include <medialibrary/filesystem/Errors.h>
+#include <type_traits>
+
#define VLC_JNI_VERSION JNI_VERSION_1_2
+namespace utils
+{
+namespace jni
+{
+template <typename T>
+class localref
+{
+ static_assert( std::is_pointer<T>::value, "T must be a pointer type");
+public:
+ localref(JNIEnv* env, T ref)
+ : m_env( env )
+ , m_ref( ref )
+ {
+ }
+
+ localref()
+ : m_env( nullptr )
+ , m_ref( nullptr )
+ {
+ }
+
+ ~localref()
+ {
+ if ( m_ref )
+ {
+ assert( m_env != nullptr );
+ m_env->DeleteLocalRef( m_ref );
+ }
+ }
+ /* Disable copy since there's no good reason to copy those and not move then */
+ localref( const localref& ) = delete;
+ localref& operator=( const localref& ) = delete;
+
+ localref( localref&& old )
+ : m_env( nullptr )
+ , m_ref( nullptr )
+ {
+ using std::swap;
+ swap( m_env, old.m_env );
+ swap( m_ref, old.m_ref );
+ }
+
+ localref& operator=( localref&& rhs )
+ {
+ if ( m_ref != nullptr )
+ {
+ assert( m_env != nullptr );
+ m_env->DeleteLocalRef( m_ref );
+ }
+ using std::swap;
+ swap( m_env, rhs.m_env );
+ swap( m_ref, rhs.m_ref );
+ return *this;
+ }
+
+ T get() const
+ {
+ return m_ref;
+ }
+
+ /**
+ * @brief release Will release the wrapper ownership but will *not* invoke DeleteLocalRef
+ * @return The underlying raw pointer
+ *
+ * This is meant to be used when a JNI value needs to be provided back to java
+ * which is expected to release the value itself
+ */
+ T release()
+ {
+ auto ref = m_ref;
+ m_ref = nullptr;
+ return ref;
+ }
+
+ bool operator==( std::nullptr_t ) const
+ {
+ return m_ref == nullptr;
+ }
+
+ bool operator!=( std::nullptr_t ) const
+ {
+ return m_ref != nullptr;
+ }
+
+private:
+ JNIEnv* m_env;
+ T m_ref;
+};
+
+using string = localref<jstring>;
+
+}
+}
+
struct fields {
jint SDK_INT;
struct IllegalStateException {
More information about the Android
mailing list