summaryrefslogtreecommitdiff
path: root/share/swig/2.0.11/java/director.swg
diff options
context:
space:
mode:
Diffstat (limited to 'share/swig/2.0.11/java/director.swg')
-rw-r--r--share/swig/2.0.11/java/director.swg198
1 files changed, 198 insertions, 0 deletions
diff --git a/share/swig/2.0.11/java/director.swg b/share/swig/2.0.11/java/director.swg
new file mode 100644
index 0000000..f32fda3
--- /dev/null
+++ b/share/swig/2.0.11/java/director.swg
@@ -0,0 +1,198 @@
+/* -----------------------------------------------------------------------------
+ * 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 || !mem_own; // hold as weak global if explicitly requested or not owned
+ if (jobj)
+ jthis_ = weak_global_ ? 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;
+ }
+
+ /* Only call peek if you know what you are doing wrt to weak/global references */
+ 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_;
+ int env_status;
+ public:
+ JNIEnvWrapper(const Director *director) : director_(director), jenv_(0), env_status(0) {
+#if defined(__ANDROID__)
+ JNIEnv **jenv = &jenv_;
+#else
+ void **jenv = (void **)&jenv_;
+#endif
+ env_status = director_->swig_jvm_->GetEnv((void **)&jenv_, JNI_VERSION_1_2);
+#if defined(SWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON)
+ // Attach a daemon thread to the JVM. Useful when the JVM should not wait for
+ // the thread to exit upon shutdown. Only for jdk-1.4 and later.
+ director_->swig_jvm_->AttachCurrentThreadAsDaemon(jenv, NULL);
+#else
+ director_->swig_jvm_->AttachCurrentThread(jenv, NULL);
+#endif
+ }
+ ~JNIEnvWrapper() {
+#if !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
+ // 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 (env_status == JNI_EDETACHED)
+ 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_.get(jenv);
+#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);
+ }
+ }
+ jenv->DeleteLocalRef(jobj);
+ }
+
+ 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 */
+
+