Scott Michel director patch, typemap consolidation

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@7174 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2005-04-28 22:11:06 +00:00
commit c2e9c01ab1
5 changed files with 237 additions and 128 deletions

View file

@ -59,12 +59,15 @@ namespace Swig {
void release(JNIEnv *jenv) {
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "JObjectWrapper::release(" << jthis_ << "): " << (weak_global_ ? "local ref" : "global ref") << std::endl;
std::cout << "JObjectWrapper::release(" << jthis_ << "): " << (weak_global_ ? "weak global ref" : "global ref") << std::endl;
#endif
if (weak_global_)
jenv->DeleteWeakGlobalRef(jthis_);
else
jenv->DeleteGlobalRef(jthis_);
if (jthis_ != NULL) {
if (weak_global_) {
if (jenv->IsSameObject(jthis_, NULL) == JNI_FALSE)
jenv->DeleteWeakGlobalRef(jthis_);
} else
jenv->DeleteGlobalRef(jthis_);
}
jthis_ = NULL;
weak_global_ = true;
@ -74,6 +77,25 @@ namespace Swig {
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 releses ownership of C++ object's lifetime */
if (weak_global_) {
jenv->DeleteWeakGlobalRef(jthis_);
jthis_ = jenv->NewGlobalRef(jself);
weak_global_ = false;
}
}
}
private:
/* pointer to Java object */
jobject jthis_;
@ -101,16 +123,17 @@ namespace Swig {
/* 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);
jobject jobj = swig_self_.peek();
#if defined(DEBUG_DIRECTOR_OWNED)
std::cout << "Swig::Director::disconnect_director_self(" << jobj << ")" << std::endl;
#endif
if (jobj) {
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);
} else {
jenv->ExceptionClear();
}
}
}
@ -132,6 +155,11 @@ namespace Swig {
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);
}
};
}

View file

@ -583,13 +583,13 @@
}
$1 = *argp; %}
%typemap(directorout) SWIGTYPE ($&1_type argp)
%{ argp = *($&1_ltype*)&$input;
%typemap(directorout) SWIGTYPE ($1_ltype argp)
%{ argp = *($&1_ltype)&$input;
if (!argp) {
SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type");
return $null;
}
$1 = *argp; %}
$1 = argp; %}
%typemap(out) SWIGTYPE
#ifdef __cplusplus
@ -1105,46 +1105,36 @@ SWIG_JAVABODY_METHODS(protected, protected, SWIGTYPE)
/*
* Java constructor typemaps:
*
* The javaconstruct and javaconstruct_director typemaps are inserted when a
* proxy class's constructor is generated. These typemaps allow control over what
* code is executed in the constructor as well as specifying who owns the
* underlying C/C++ object. Normally, Java has ownership and the underlying
* C/C++ object is deallocated when the Java object is finalized (swigCMemOwn
* is true.) If swigCMemOwn is false, C/C++ is ultimately responsible for
* deallocating the underlying object's memory.
* The javaconstruct typemap is inserted when a proxy class's constructor is generated.
* This typemap allows control over what code is executed in the constructor as
* well as specifying who owns the underlying C/C++ object. Normally, Java has
* ownership and the underlying C/C++ object is deallocated when the Java object
* is finalized (swigCMemOwn is true.) If swigCMemOwn is false, C/C++ is
* ultimately responsible for deallocating the underlying object's memory.
*
* The SWIG_PROXY_CONSTRUCTOR and SWIG_DIRECTOR_CONSTRUCTOR macros define the
* javaconstruct and javaconstruct_director typemaps for a proxy class for a
* particular TYPENAME. OWNERSHIP is passed as the value of swigCMemOwn to the
* pointer constructor method. SWIG_DIRECTOR_CONSTRUCTOR takes an additional
* parameter, WEAKREF, that determines which kind of Java object reference
* will be used by the C++ director class (WeakGlobalRef vs. GlobalRef.)
* The SWIG_PROXY_CONSTRUCTOR macro defines the javaconstruct typemap for a proxy
* class for a particular TYPENAME. OWNERSHIP is passed as the value of
* swigCMemOwn to the pointer constructor method. WEAKREF determines which kind
* of Java object reference will be used by the C++ director class (WeakGlobalRef
* vs. GlobalRef.)
*
* The SWIG_DIRECTOR_OWNED macro sets the ownership of director-based proxy
* classes to false, meaning that the underlying C++ object will be
* reclaimed by C++.
* classes and the weak reference flag to false, meaning that the underlying C++
* object will be reclaimed by C++.
*/
%define SWIG_PROXY_CONSTRUCTOR(OWNERSHIP, TYPENAME...)
%typemap(javaconstruct) TYPENAME {
this($imcall, OWNERSHIP);
}
%enddef
%define SWIG_DIRECTOR_CONSTRUCTOR(OWNERSHIP, WEAKREF, TYPENAME...)
%typemap(javaconstruct_director) TYPENAME {
this($imcall, OWNERSHIP);
$moduleJNI.$javaclassname_director_connect(this, swigCPtr, OWNERSHIP, WEAKREF);
%define SWIG_PROXY_CONSTRUCTOR(OWNERSHIP, WEAKREF, TYPENAME...)
%typemap(javaconstruct,directorconnect="\n $moduleJNI.$javaclassname_director_connect(this, swigCPtr, swigCMemOwn, WEAKREF);") TYPENAME {
this($imcall, OWNERSHIP);$directorconnect
}
%enddef
%define SWIG_DIRECTOR_OWNED(TYPENAME...)
SWIG_DIRECTOR_CONSTRUCTOR(true, false, TYPENAME)
SWIG_PROXY_CONSTRUCTOR(true, false, TYPENAME)
%enddef
// Set the default for SWIGTYPE: Java owns the C/C++ object.
SWIG_PROXY_CONSTRUCTOR(true, SWIGTYPE)
SWIG_DIRECTOR_CONSTRUCTOR(true, true, SWIGTYPE)
SWIG_PROXY_CONSTRUCTOR(true, true, SWIGTYPE)
%typemap(javadestruct, methodname="delete") SWIGTYPE {
if(swigCPtr != 0 && swigCMemOwn) {
@ -1163,15 +1153,26 @@ SWIG_DIRECTOR_CONSTRUCTOR(true, true, SWIGTYPE)
super.delete();
}
%typemap(directordisconnect, methodname="swigDirectorDisconnect") SWIGTYPE {
%typemap(directordisconnect, methodname="swigDirectorDisconnect") SWIGTYPE %{
protected void $methodname() {
swigCMemOwn = false;
$jnicall;
}
%}
%typemap(directordisconnect_derived, methodname="swigDirectorDisconnect") SWIGTYPE {
%typemap(directorowner_release, methodname="swigReleaseOwnership") SWIGTYPE %{
public void $methodname() {
swigCMemOwn = false;
$jnicall;
}
%}
%typemap(directorowner_take, methodname="swigTakeOwnership") SWIGTYPE %{
public void $methodname() {
swigCMemOwn = true;
$jnicall;
}
%}
/* Java specific directives */
#define %javaconst(flag) %feature("java:const","flag")