diff options
Diffstat (limited to 'platform/android/java_glue.cpp')
-rw-r--r-- | platform/android/java_glue.cpp | 113 |
1 files changed, 88 insertions, 25 deletions
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 0312d13644..349db08e36 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -45,9 +45,18 @@ static JavaClassWrapper *java_class_wrapper=NULL; static OS_Android *os_android=NULL; -jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_arg, bool force_jobject = false) { +struct jvalret { - jvalue v; + jobject obj; + jvalue val; + jvalret() { obj=NULL; } + + +}; + +jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_arg, bool force_jobject = false) { + + jvalret v; switch(p_type) { @@ -59,9 +68,12 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jvalue val; val.z = (bool)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); - v.l = obj; + v.val.l = obj; + v.obj=obj; + env->DeleteLocalRef(bclass); } else { - v.z=*p_arg; + v.val.z=*p_arg; + }; } break; case Variant::INT: { @@ -73,10 +85,13 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jvalue val; val.i = (int)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); - v.l = obj; + v.val.l = obj; + v.obj=obj; + env->DeleteLocalRef(bclass); } else { - v.i=*p_arg; + v.val.i=*p_arg; + }; } break; case Variant::REAL: { @@ -88,17 +103,20 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jvalue val; val.d = (double)(*p_arg); jobject obj = env->NewObjectA(bclass, ctor, &val); - v.l = obj; + v.val.l = obj; + v.obj=obj; + env->DeleteLocalRef(bclass); } else { - v.f=*p_arg; + v.val.f=*p_arg; }; } break; case Variant::STRING: { String s = *p_arg; jstring jStr = env->NewStringUTF(s.utf8().get_data()); - v.l=jStr; + v.val.l=jStr; + v.obj=jStr; } break; case Variant::STRING_ARRAY: { @@ -107,9 +125,12 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar for(int j=0;j<sarray.size();j++) { - env->SetObjectArrayElement(arr,j,env->NewStringUTF( sarray[j].utf8().get_data() )); + jstring str = env->NewStringUTF( sarray[j].utf8().get_data() ); + env->SetObjectArrayElement(arr,j,str); + env->DeleteLocalRef(str); } - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; @@ -124,27 +145,36 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jobjectArray jkeys = env->NewObjectArray(keys.size(), env->FindClass("java/lang/String"), env->NewStringUTF("")); for (int j=0; j<keys.size(); j++) { - env->SetObjectArrayElement(jkeys, j, env->NewStringUTF(String(keys[j]).utf8().get_data())); + jstring str = env->NewStringUTF(String(keys[j]).utf8().get_data()); + env->SetObjectArrayElement(jkeys, j, str); + env->DeleteLocalRef(str); }; jmethodID set_keys = env->GetMethodID(dclass, "set_keys", "([Ljava/lang/String;)V"); jvalue val; val.l = jkeys; env->CallVoidMethodA(jdict, set_keys, &val); + env->DeleteLocalRef(jkeys); jobjectArray jvalues = env->NewObjectArray(keys.size(), env->FindClass("java/lang/Object"), NULL); for (int j=0; j<keys.size(); j++) { Variant var = dict[keys[j]]; - val = _variant_to_jvalue(env, var.get_type(), &var, true); - env->SetObjectArrayElement(jvalues, j, val.l); + jvalret v = _variant_to_jvalue(env, var.get_type(), &var, true); + env->SetObjectArrayElement(jvalues, j, v.val.l); + if (v.obj) { + env->DeleteLocalRef(v.obj); + } }; jmethodID set_values = env->GetMethodID(dclass, "set_values", "([Ljava/lang/Object;)V"); val.l = jvalues; env->CallVoidMethodA(jdict, set_values, &val); + env->DeleteLocalRef(jvalues); + env->DeleteLocalRef(dclass); - v.l = jdict; + v.val.l = jdict; + v.obj=jdict; } break; case Variant::INT_ARRAY: { @@ -153,7 +183,8 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jintArray arr = env->NewIntArray(array.size()); DVector<int>::Read r = array.read(); env->SetIntArrayRegion(arr,0,array.size(),r.ptr()); - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; case Variant::RAW_ARRAY: { @@ -161,7 +192,8 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jbyteArray arr = env->NewByteArray(array.size()); DVector<uint8_t>::Read r = array.read(); env->SetByteArrayRegion(arr,0,array.size(),reinterpret_cast<const signed char*>(r.ptr())); - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; case Variant::REAL_ARRAY: { @@ -170,12 +202,13 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar jfloatArray arr = env->NewFloatArray(array.size()); DVector<float>::Read r = array.read(); env->SetFloatArrayRegion(arr,0,array.size(),r.ptr()); - v.l=arr; + v.val.l=arr; + v.obj=arr; } break; default: { - v.i = 0; + v.val.i = 0; } break; } @@ -193,8 +226,11 @@ String _get_class_name(JNIEnv * env, jclass cls, bool* array) { jboolean isarr = env->CallBooleanMethod(cls, isArray); (*array) = isarr ? true : false; } + String name = env->GetStringUTFChars( clsName, NULL ); + env->DeleteLocalRef(clsName); + + return name; - return env->GetStringUTFChars( clsName, NULL ); }; @@ -223,6 +259,8 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) { jstring string = (jstring) env->GetObjectArrayElement(arr, i); const char *rawString = env->GetStringUTFChars(string, 0); sarr.push_back(String(rawString)); + env->DeleteLocalRef(string); + } return sarr; @@ -321,30 +359,34 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) { jobjectArray arr = (jobjectArray)obj; int objCount = env->GetArrayLength(arr); - Array varr; + Array varr(true); for (int i=0; i<objCount; i++) { jobject jobj = env->GetObjectArrayElement(arr, i); Variant v = _jobject_to_variant(env, jobj); varr.push_back(v); + env->DeleteLocalRef(jobj); + } return varr; }; - if (name == "com.android.godot.Dictionary") { + if (name == "java.util.HashMap" || name == "com.android.godot.Dictionary") { - Dictionary ret; + Dictionary ret(true); jclass oclass = c; jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;"); jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys); StringArray keys = _jobject_to_variant(env, arr); + env->DeleteLocalRef(arr); jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;"); arr = (jobjectArray)env->CallObjectMethod(obj, get_values); Array vals = _jobject_to_variant(env, arr); + env->DeleteLocalRef(arr); //print_line("adding " + String::num(keys.size()) + " to Dictionary!"); for (int i=0; i<keys.size(); i++) { @@ -352,9 +394,12 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) { ret[keys[i]] = vals[i]; }; + return ret; }; + env->DeleteLocalRef(c); + return Variant(); }; @@ -432,9 +477,13 @@ public: JNIEnv *env = ThreadAndroid::get_env(); //print_line("argcount "+String::num(p_argcount)); + List<jobject> to_erase; for(int i=0;i<p_argcount;i++) { - v[i] = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]); + jvalret vr = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]); + v[i] = vr.val; + if (vr.obj) + to_erase.push_back(vr.obj); } //print_line("calling method!!"); @@ -468,6 +517,7 @@ public: jobject o = env->CallObjectMethodA(instance,E->get().method,v); String str = env->GetStringUTFChars((jstring)o, NULL ); ret=str; + env->DeleteLocalRef(o); } break; case Variant::STRING_ARRAY: { @@ -475,6 +525,7 @@ public: ret = _jobject_to_variant(env, arr); + env->DeleteLocalRef(arr); } break; case Variant::INT_ARRAY: { @@ -488,6 +539,7 @@ public: env->GetIntArrayRegion(arr,0,fCount,w.ptr()); w = DVector<int>::Write(); ret=sarr; + env->DeleteLocalRef(arr); } break; case Variant::REAL_ARRAY: { @@ -501,6 +553,7 @@ public: env->GetFloatArrayRegion(arr,0,fCount,w.ptr()); w = DVector<float>::Write(); ret=sarr; + env->DeleteLocalRef(arr); } break; case Variant::DICTIONARY: { @@ -508,6 +561,7 @@ public: //print_line("call dictionary"); jobject obj = env->CallObjectMethodA(instance, E->get().method, v); ret = _jobject_to_variant(env, obj); + env->DeleteLocalRef(obj); } break; default: { @@ -518,6 +572,10 @@ public: } break; } + while (to_erase.size()) { + env->DeleteLocalRef(to_erase.front()->get()); + to_erase.pop_front(); + } //print_line("success"); return ret; @@ -872,6 +930,7 @@ static void _initialize_java_modules() { String modules = Globals::get_singleton()->get("android/modules"); Vector<String> mods = modules.split(",",false); + print_line("ANDROID MODULES : " + modules); __android_log_print(ANDROID_LOG_INFO,"godot","mod count: %i",mods.size()); if (mods.size()) { @@ -1571,6 +1630,8 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_callobject(JNIEnv * env, memnew_placement(&vlist[i], Variant); vlist[i] = v; vptr[i] = &vlist[i]; + env->DeleteLocalRef(obj); + }; Variant::CallError err; @@ -1588,13 +1649,15 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_calldeferred(JNIEnv * env int count = env->GetArrayLength(params); Variant args[VARIANT_ARG_MAX]; -// print_line("Java->GD call: "+obj->get_type()+"::"+str_method+" argc "+itos(count)); + //print_line("Java->GD call: "+obj->get_type()+"::"+str_method+" argc "+itos(count)); for (int i=0; i<MIN(count,VARIANT_ARG_MAX); i++) { jobject obj = env->GetObjectArrayElement(params, i); if (obj) args[i] = _jobject_to_variant(env, obj); + env->DeleteLocalRef(obj); + // print_line("\targ"+itos(i)+": "+Variant::get_type_name(args[i].get_type())); }; |