Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
5.7 KiB

5 years ago
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* director.swg
*
* This file contains support for director classes that proxy
* method calls from C++ to Java extensions.
* ----------------------------------------------------------------------------- */
#ifdef __cplusplus
#if defined(DEBUG_DIRECTOR_OWNED)
#include <iostream>
#endif
namespace Swig {
/* Java object wrapper */
class JObjectWrapper {
public:
JObjectWrapper() : jthis_(NULL), weak_global_(true) {
}
~JObjectWrapper() {
jthis_ = NULL;
weak_global_ = true;
}
bool set(JNIEnv *jenv, jobject jobj, bool mem_own, bool weak_global) {
if (!jthis_) {
weak_global_ = weak_global;
if (jobj)
jthis_ = ((weak_global_ || !mem_own) ? jenv->NewWeakGlobalRef(jobj) : jenv->NewGlobalRef(jobj));
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "JObjectWrapper::set(" << jobj << ", " << (weak_global ? "weak_global" : "global_ref") << ") -> " << jthis_ << std::endl;
#endif
return true;
} else {
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "JObjectWrapper::set(" << jobj << ", " << (weak_global ? "weak_global" : "global_ref") << ") -> already set" << std::endl;
#endif
return false;
}
}
jobject get(JNIEnv *jenv) const {
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "JObjectWrapper::get(";
if (jthis_)
std::cout << jthis_;
else
std::cout << "null";
std::cout << ") -> return new local ref" << std::endl;
#endif
return (jthis_ ? jenv->NewLocalRef(jthis_) : jthis_);
}
void release(JNIEnv *jenv) {
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "JObjectWrapper::release(" << jthis_ << "): " << (weak_global_ ? "weak global ref" : "global ref") << std::endl;
#endif
if (jthis_) {
if (weak_global_) {
if (jenv->IsSameObject(jthis_, NULL) == JNI_FALSE)
jenv->DeleteWeakGlobalRef((jweak)jthis_);
} else
jenv->DeleteGlobalRef(jthis_);
}
jthis_ = NULL;
weak_global_ = true;
}
jobject peek() {
return jthis_;
}
/* Java proxy releases ownership of C++ object, C++ object is now
responsible for destruction (creates NewGlobalRef to pin Java
proxy) */
void java_change_ownership(JNIEnv *jenv, jobject jself, bool take_or_release) {
if (take_or_release) { /* Java takes ownership of C++ object's lifetime. */
if (!weak_global_) {
jenv->DeleteGlobalRef(jthis_);
jthis_ = jenv->NewWeakGlobalRef(jself);
weak_global_ = true;
}
} else { /* Java releases ownership of C++ object's lifetime */
if (weak_global_) {
jenv->DeleteWeakGlobalRef((jweak)jthis_);
jthis_ = jenv->NewGlobalRef(jself);
weak_global_ = false;
}
}
}
private:
/* pointer to Java object */
jobject jthis_;
/* Local or global reference flag */
bool weak_global_;
};
/* director base class */
class Director {
/* pointer to Java virtual machine */
JavaVM *swig_jvm_;
protected:
#if defined (_MSC_VER) && (_MSC_VER<1300)
class JNIEnvWrapper;
friend class JNIEnvWrapper;
#endif
/* Utility class for managing the JNI environment */
class JNIEnvWrapper {
const Director *director_;
JNIEnv *jenv_;
public:
JNIEnvWrapper(const Director *director) : director_(director), jenv_(0) {
director_->swig_jvm_->AttachCurrentThread((void **) &jenv_, NULL);
}
~JNIEnvWrapper() {
// Some JVMs, eg JDK 1.4.2 and lower on Solaris have a bug and crash with the DetachCurrentThread call.
// However, without this call, the JVM hangs on exit when the thread was not created by the JVM and creates a memory leak.
#if !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
director_->swig_jvm_->DetachCurrentThread();
#endif
}
JNIEnv *getJNIEnv() const {
return jenv_;
}
};
/* Java object wrapper */
JObjectWrapper swig_self_;
/* Disconnect director from Java object */
void swig_disconnect_director_self(const char *disconn_method) {
JNIEnvWrapper jnienv(this) ;
JNIEnv *jenv = jnienv.getJNIEnv() ;
jobject jobj = swig_self_.peek();
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "Swig::Director::disconnect_director_self(" << jobj << ")" << std::endl;
#endif
if (jobj && jenv->IsSameObject(jobj, NULL) == JNI_FALSE) {
jmethodID disconn_meth = jenv->GetMethodID(jenv->GetObjectClass(jobj), disconn_method, "()V");
if (disconn_meth) {
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "Swig::Director::disconnect_director_self upcall to " << disconn_method << std::endl;
#endif
jenv->CallVoidMethod(jobj, disconn_meth);
}
}
}
public:
Director(JNIEnv *jenv) : swig_jvm_((JavaVM *) NULL), swig_self_() {
/* Acquire the Java VM pointer */
jenv->GetJavaVM(&swig_jvm_);
}
virtual ~Director() {
JNIEnvWrapper jnienv(this) ;
JNIEnv *jenv = jnienv.getJNIEnv() ;
swig_self_.release(jenv);
}
bool swig_set_self(JNIEnv *jenv, jobject jself, bool mem_own, bool weak_global) {
return swig_self_.set(jenv, jself, mem_own, weak_global);
}
jobject swig_get_self(JNIEnv *jenv) const {
return swig_self_.get(jenv);
}
// Change C++ object's ownership, relative to Java
void swig_java_change_ownership(JNIEnv *jenv, jobject jself, bool take_or_release) {
swig_self_.java_change_ownership(jenv, jself, take_or_release);
}
};
}
#endif /* __cplusplus */