summaryrefslogtreecommitdiff
path: root/platform/android/java_glue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/java_glue.cpp')
-rw-r--r--platform/android/java_glue.cpp113
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()));
};