Home | History | Annotate | Download | only in common
      1 /** Creates a pool for the type and sets SWIG to use the pool instead of creating a new java object every time.
      2  * TODO: Add better pointer support
      3  * @author Xoppa */
      4 %define CREATE_POOLED_OBJECT_EXT(CTYPE, JTYPE, _JCLASS)
      5 
      6 // Add pooling to the java class
      7 %typemap(javacode) CTYPE %{
      8 	/** Temporary instance, use by native methods that return a JTYPE instance */
      9 	protected final static JTYPE temp = new JTYPE(0, false);
     10 	public static JTYPE internalTemp(long cPtr, boolean own) {
     11 		temp.reset(cPtr, own);
     12 		return temp;
     13 	}
     14 	/** Pool of JTYPE instances, used by director interface to provide the arguments. */
     15 	protected static final com.badlogic.gdx.utils.Pool<JTYPE> pool = new com.badlogic.gdx.utils.Pool<JTYPE>() {
     16 		@Override
     17 		protected JTYPE newObject() {
     18 			return new JTYPE(0, false);
     19 		}
     20 	};
     21 	/** Reuses a previous freed instance or creates a new instance and set it to reflect the specified native object */
     22 	public static JTYPE obtain(long cPtr, boolean own) {
     23 		final JTYPE result = pool.obtain();
     24 		result.reset(cPtr, own);
     25 		return result;
     26 	}
     27 	/** delete the native object if required and allow the instance to be reused by the obtain method */
     28 	public static void free(final JTYPE inst) {
     29 		inst.dispose();
     30 		pool.free(inst);
     31 	}
     32 %}
     33 
     34 %fragment(gdxToString(gdxPooled##JTYPE), "header") {
     35 	// Inline (cached) method to retrieve the type's jclass
     36 	SWIGINTERN inline jclass &gdx_getClass##JTYPE(JNIEnv * const &jenv) {
     37 		static jclass cls = NULL;
     38 		if (cls == NULL)
     39 			cls = (jclass) jenv->NewGlobalRef(jenv->FindClass(gdxToString(_JCLASS)));
     40 		return cls;
     41 	}
     42 
     43 	// Inline method to get the termporary instance
     44 	SWIGINTERN inline jobject gdx_getTemp##JTYPE(JNIEnv * jenv, void *cPtr, bool ownMem) {
     45 	  static jobject ret = NULL;
     46 	  jclass &clazz = gdx_getClass##JTYPE(jenv);
     47 	  if (ret == NULL) {
     48 	    jfieldID field = jenv->GetStaticFieldID(clazz, "temp", gdxToString(L##_JCLASS##;));
     49 	    ret = jenv->NewGlobalRef(jenv->GetStaticObjectField(clazz, field));
     50 	  }
     51 
     52 	  static jmethodID reuseMethod = NULL;
     53 	  if (reuseMethod == NULL)
     54 		  reuseMethod = (jmethodID) jenv->GetMethodID(clazz, "reset", "(JZ)V");
     55 
     56 	  long ptr;
     57 	  *(const void **)&ptr = cPtr;
     58 	  jenv->CallVoidMethod(ret, reuseMethod, ptr, (jboolean)ownMem);
     59 	  return ret;
     60 	}
     61 
     62 	// Inline method to obtain an instance from the pool
     63 	SWIGINTERN inline jobject gdx_obtain##JTYPE(JNIEnv * jenv, jclass clazz, void *cPtr, bool ownMem) {
     64 		static jmethodID obtainMethod = NULL;
     65 		if (obtainMethod == NULL)
     66 			obtainMethod = (jmethodID) jenv->GetStaticMethodID(clazz, "obtain", gdxToString((JZ)L##_JCLASS##;));
     67 
     68 		long ptr;
     69 		*(const void **)&ptr = cPtr;
     70 		jobject ret = jenv->CallStaticObjectMethod(clazz, obtainMethod, ptr, (jboolean)ownMem);
     71 
     72 		return ret;
     73 	}
     74 
     75 	// Inline method to free an instance from the pool
     76 	SWIGINTERN inline void gdx_free##JTYPE(JNIEnv * jenv, const jclass clazz, const jobject obj) {
     77 		static jmethodID freeMethod = NULL;
     78 		if (freeMethod == NULL)
     79 			freeMethod = (jmethodID) jenv->GetStaticMethodID(clazz, "free", gdxToString((L##_JCLASS##;)V));
     80 
     81 		jenv->CallStaticVoidMethod(clazz, freeMethod, obj);
     82 
     83 		jenv->DeleteLocalRef(obj);
     84 	}
     85 
     86 	// Simple raii class to auto free the instance from the pool
     87 	class gdxAutoFree##JTYPE {
     88 	private:
     89 		JNIEnv * jenv;
     90 		jobject j##JTYPE;
     91 		jclass jclazz;
     92 	public:
     93 		gdxAutoFree##JTYPE(JNIEnv * jenv, jclass jclazz, jobject j##JTYPE) :
     94 			jenv(jenv), j##JTYPE(j##JTYPE), jclazz(jclazz) { }
     95 		virtual ~gdxAutoFree##JTYPE() {
     96 			gdx_free##JTYPE(this->jenv, this->jclazz, this->j##JTYPE);
     97 		}
     98 	};
     99 }
    100 
    101 // The typemaps
    102 %typemap(jni)				CTYPE *	"jlong"
    103 %typemap(jtype)				CTYPE *	"long"
    104 %typemap(jstype)			CTYPE * "JTYPE"
    105 %typemap(jni) 				CTYPE, CTYPE &, const CTYPE &	"jobject"
    106 %typemap(jstype) 			CTYPE, CTYPE &, const CTYPE &	"JTYPE"
    107 %typemap(jtype) 			CTYPE, CTYPE &, const CTYPE &	"JTYPE"
    108 %typemap(javain)			CTYPE, CTYPE &, const CTYPE &	"$javainput"
    109 %typemap(javadirectorin)	CTYPE, CTYPE &, const CTYPE &	"$1"
    110 %typemap(javadirectorout)	CTYPE, CTYPE &, const CTYPE &	"$javacall"
    111 
    112 //%typemap(directorin, fragment=gdxToString(gdxPooled##JTYPE), descriptor=gdxToString(L##_JCLASS;), noblock=1)	const CTYPE &  {
    113 //	jclass jc$1 = gdx_getClass##JTYPE(jenv);
    114 //	$input = gdx_obtain##JTYPE(jenv, jc$1, (void*)$1, false);
    115 //	gdxAutoFree##JTYPE autoRelease_$input(jenv, jc$1, $input);
    116 //}
    117 %typemap(directorin, fragment=gdxToString(gdxPooled##JTYPE), descriptor=gdxToString(L##_JCLASS;), noblock=1)	CTYPE, CTYPE &, const CTYPE &  {
    118 	jclass jc$1 = gdx_getClass##JTYPE(jenv);
    119 	$input = gdx_obtain##JTYPE(jenv, jc$1, (void*)&$1, false);
    120 	gdxAutoFree##JTYPE autoRelease_$input(jenv, jc$1, $input);
    121 }
    122 %typemap(out, fragment=gdxToString(gdxPooled##JTYPE), noblock=1)		CTYPE, CTYPE &, const CTYPE &	{
    123 	$result = gdx_getTemp##JTYPE(jenv, &$1, false);
    124 }
    125 %typemap(javaout)		CTYPE, CTYPE &, const CTYPE &	{
    126 	return $jnicall;
    127 }
    128 %typemap(javaout)		CTYPE * {
    129 	return JTYPE.internalTemp($jnicall, false);
    130 }
    131 
    132 %enddef // CREATE_POOLED_OBJECT_EXT
    133 
    134 %define CREATE_POOLED_OBJECT(_TYPE, _JCLASS)
    135 CREATE_POOLED_OBJECT_EXT(_TYPE, _TYPE, _JCLASS)
    136 %enddef
    137