/***********************************************************************
* This file contains support for director classes that proxy
* method calls from C++ to Java extensions.
* Author : Scott Michel (scottm@aero.org)
* This file was adapted from the python director.swg, written by
* Mark Rose (mrose@stm.lbl.gov)
************************************************************************/
#if defined(DEBUG_DIRECTOR_OWNED)
/* Java object wrapper */
JObjectWrapper() : jthis_(NULL), weak_global_(true) {
bool set(JNIEnv *jenv, jobject jobj, bool mem_own, bool weak_global) {
weak_global_ = weak_global;
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;
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "JObjectWrapper::set(" << jobj << ", " << (weak_global ? "weak_global" : "global_ref") << ") -> already set" << std::endl;
jobject get(JNIEnv *jenv) const {
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "JObjectWrapper::get(";
std::cout << ") -> return new local ref" << std::endl;
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;
if (jenv->IsSameObject(jthis_, NULL) == JNI_FALSE)
jenv->DeleteWeakGlobalRef((jweak)jthis_);
jenv->DeleteGlobalRef(jthis_);
/* Java proxy releases ownership of C++ object, C++ object is now
responsible for destruction (creates NewGlobalRef to pin Java
void java_change_ownership(JNIEnv *jenv, jobject jself, bool take_or_release) {
if (take_or_release) { /* Java takes ownership of C++ object's lifetime. */
jenv->DeleteGlobalRef(jthis_);
jthis_ = jenv->NewWeakGlobalRef(jself);
} else { /* Java releases ownership of C++ object's lifetime */
jenv->DeleteWeakGlobalRef((jweak)jthis_);
jthis_ = jenv->NewGlobalRef(jself);
/* pointer to Java object */
/* Local or global reference flag */
/* director base class */
/* pointer to Java virtual machine */
/* Java object wrapper */
JObjectWrapper swig_self_;
/* Acquire Java VM environment from Java VM */
JNIEnv *swig_acquire_jenv() const {
swig_jvm_->AttachCurrentThread((void **) &env, NULL);
/* Disconnect director from Java object */
void swig_disconnect_director_self(const char *disconn_method) {
JNIEnv *jenv = swig_acquire_jenv();
jobject jobj = swig_self_.peek();
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "Swig::Director::disconnect_director_self(" << jobj << ")" << std::endl;
if (jobj && jenv->IsSameObject(jobj, NULL) == JNI_FALSE) {
jmethodID disconn_meth = jenv->GetMethodID(jenv->GetObjectClass(jobj), disconn_method, "()V");
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "Swig::Director::disconnect_director_self upcall to " << disconn_method << std::endl;
jenv->CallVoidMethod(jobj, disconn_meth);
Director(JNIEnv *jenv) : swig_jvm_((JavaVM *) NULL), swig_self_() {
/* Acquire the Java VM pointer */
jenv->GetJavaVM(&swig_jvm_);
swig_self_.release(swig_acquire_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);