Modifications to the typemaps giving users fine control over memory ownership and lifetime of director classes. Patch from Scott Michel.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@7070 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
827fa350ab
commit
47e471fc7e
3 changed files with 269 additions and 143 deletions
|
|
@ -12,57 +12,126 @@
|
|||
|
||||
#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_ == NULL) {
|
||||
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_ ? "local ref" : "global ref") << std::endl;
|
||||
#endif
|
||||
if (weak_global_)
|
||||
jenv->DeleteWeakGlobalRef(jthis_);
|
||||
else
|
||||
jenv->DeleteGlobalRef(jthis_);
|
||||
|
||||
jthis_ = NULL;
|
||||
weak_global_ = true;
|
||||
}
|
||||
|
||||
jobject peek() {
|
||||
return jthis_;
|
||||
}
|
||||
|
||||
private:
|
||||
/* pointer to Java object */
|
||||
jobject jthis_;
|
||||
/* Local or global reference flag */
|
||||
bool weak_global_;
|
||||
};
|
||||
|
||||
/* director base class */
|
||||
class Director {
|
||||
private:
|
||||
/* pointer to Java virtual machine */
|
||||
JavaVM *swig_jvm;
|
||||
private:
|
||||
/* pointer to Java virtual machine */
|
||||
JavaVM *swig_jvm_;
|
||||
|
||||
protected:
|
||||
/* pointer to the wrapped Java object */
|
||||
jobject swig_self;
|
||||
protected:
|
||||
/* Java object wrapper */
|
||||
JObjectWrapper swig_self_;
|
||||
|
||||
/* Acquire Java VM environment from Java VM */
|
||||
JNIEnv *swig_acquire_jenv() const {
|
||||
JNIEnv *env = NULL;
|
||||
swig_jvm->AttachCurrentThread((void **) &env, NULL);
|
||||
return env;
|
||||
}
|
||||
/* Acquire Java VM environment from Java VM */
|
||||
JNIEnv *swig_acquire_jenv() const {
|
||||
JNIEnv *env = NULL;
|
||||
swig_jvm_->AttachCurrentThread((void **) &env, NULL);
|
||||
return env;
|
||||
}
|
||||
|
||||
/* Disconnect director from Java object */
|
||||
void swig_disconnect_director_self(const char *disconn_method) {
|
||||
if (swig_self) {
|
||||
JNIEnv *jenv = swig_acquire_jenv();
|
||||
jmethodID disconn_meth = jenv->GetMethodID(jenv->GetObjectClass(swig_self), disconn_method, "()V");
|
||||
if (disconn_meth) {
|
||||
jenv->CallVoidMethod(swig_self, disconn_meth);
|
||||
} else {
|
||||
jenv->ExceptionClear();
|
||||
}
|
||||
jenv->DeleteGlobalRef(swig_self);
|
||||
swig_self = (jobject) NULL;
|
||||
/* Disconnect director from Java object */
|
||||
void swig_disconnect_director_self(const char *disconn_method) {
|
||||
JNIEnv *jenv = swig_acquire_jenv();
|
||||
jobject jobj = swig_self_.get(jenv);
|
||||
#if defined(DEBUG_DIRECTOR_OWNED)
|
||||
std::cout << "Swig::Director::disconnect_director_self(" << jobj << ")" << std::endl;
|
||||
#endif
|
||||
if (jobj) {
|
||||
jmethodID disconn_meth = jenv->GetMethodID(jenv->GetObjectClass(jobj), disconn_method, "()V");
|
||||
if (disconn_meth) {
|
||||
jenv->CallVoidMethod(jobj, disconn_meth);
|
||||
} else {
|
||||
jenv->ExceptionClear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Director(JNIEnv *jenv) : swig_jvm((JavaVM *) NULL), swig_self(NULL) {
|
||||
/* Acquire the Java VM pointer */
|
||||
jenv->GetJavaVM(&swig_jvm);
|
||||
}
|
||||
public:
|
||||
Director(JNIEnv *jenv) : swig_jvm_((JavaVM *) NULL), swig_self_() {
|
||||
/* Acquire the Java VM pointer */
|
||||
jenv->GetJavaVM(&swig_jvm_);
|
||||
}
|
||||
|
||||
virtual ~Director() {
|
||||
}
|
||||
virtual ~Director() {
|
||||
swig_self_.release(swig_acquire_jenv());
|
||||
}
|
||||
|
||||
/* Set swig_self and get Java global reference on object */
|
||||
void swig_set_self(JNIEnv *jenv, jobject jself) {
|
||||
swig_self = jenv->NewGlobalRef(jself);
|
||||
}
|
||||
bool swig_set_self(JNIEnv *jenv, jobject jself, bool mem_own, bool weak_global) {
|
||||
return swig_self_.set(jenv, jself, mem_own, weak_global);
|
||||
}
|
||||
|
||||
/* return a pointer to the wrapped Java object */
|
||||
jobject swig_get_self() const {
|
||||
return swig_self;
|
||||
}
|
||||
jobject swig_get_self(JNIEnv *jenv) const {
|
||||
return swig_self_.get(jenv);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue