/* * Copyright (C) 2010-2011 Max Kellermann * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef JAVA_REF_HXX #define JAVA_REF_HXX #include "Global.hxx" #include #include namespace Java { /** * Hold a local reference on a JNI object. */ template class LocalRef { JNIEnv *const env; const T value; public: /** * The local reference is obtained by the caller. */ LocalRef(JNIEnv *_env, T _value):env(_env), value(_value) { assert(env != nullptr); assert(value != nullptr); } ~LocalRef() { env->DeleteLocalRef(value); } LocalRef(const LocalRef &other) = delete; LocalRef &operator=(const LocalRef &other) = delete; T Get() const { return value; } operator T() const { return value; } }; /** * Hold a global reference on a JNI object. */ template class GlobalRef { T value; public: /** * Constructs an uninitialized object. The method set() must be * called before it is destructed. */ GlobalRef() = default; GlobalRef(JNIEnv *env, T _value):value(_value) { assert(env != nullptr); assert(value != nullptr); value = (T)env->NewGlobalRef(value); } ~GlobalRef() { GetEnv()->DeleteGlobalRef(value); } GlobalRef(const GlobalRef &other) = delete; GlobalRef &operator=(const GlobalRef &other) = delete; /** * Sets the object, ignoring the previous value. This is only * allowed once after the default constructor was used. */ void Set(JNIEnv *env, T _value) { assert(_value != nullptr); value = (T)env->NewGlobalRef(_value); } T Get() const { return value; } operator T() const { return value; } }; /** * Container for a global reference to a JNI object that gets * initialised and deinitialised explicitly. Since there is no * implicit initialisation in the default constructor, this is a * trivial C++ class. It should only be used for global variables * that are implicitly initialised with zeroes. */ template class TrivialRef { T value; public: constexpr TrivialRef() {}; TrivialRef(const TrivialRef &other) = delete; TrivialRef &operator=(const TrivialRef &other) = delete; bool IsDefined() const { return value != nullptr; } /** * Obtain a global reference on the specified object and store it. * This object must not be set already. */ void Set(JNIEnv *env, T _value) { assert(value == nullptr); assert(_value != nullptr); value = (T)env->NewGlobalRef(_value); } /** * Release the global reference and clear this object. */ void Clear(JNIEnv *env) { assert(value != nullptr); env->DeleteGlobalRef(value); value = nullptr; } /** * Release the global reference and clear this object. It is * allowed to call this method without ever calling Set(). */ void ClearOptional(JNIEnv *env) { if (value != nullptr) Clear(env); } T Get() const { return value; } operator T() const { return value; } }; } #endif