JavaClassWrapper: Fix converting returned arrays to Godot types

This commit is contained in:
David Snopek 2025-02-27 16:50:51 -06:00
parent 9f68a81659
commit bbc66056a8

View file

@ -881,11 +881,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jboolean val; jboolean val;
env->GetBooleanArrayRegion((jbooleanArray)arr, 0, 1, &val); env->GetBooleanArrayRegion((jbooleanArray)arr, i, 1, &val);
ret.push_back(val); ret[i] = (bool)val;
} }
var = ret; var = ret;
@ -893,106 +894,85 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
} break; } break;
case ARG_ARRAY_BIT | ARG_TYPE_BYTE: { case ARG_ARRAY_BIT | ARG_TYPE_BYTE: {
Array ret; PackedByteArray ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
for (int i = 0; i < count; i++) { env->GetByteArrayRegion((jbyteArray)arr, 0, count, (int8_t *)ret.ptrw());
jbyte val;
env->GetByteArrayRegion((jbyteArray)arr, 0, 1, &val);
ret.push_back(val);
}
var = ret; var = ret;
return true; return true;
} break; } break;
case ARG_ARRAY_BIT | ARG_TYPE_CHAR: { case ARG_ARRAY_BIT | ARG_TYPE_CHAR: {
Array ret; PackedByteArray ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
// Char arrays are UTF-16 encoded, so it's double the length.
for (int i = 0; i < count; i++) { ret.resize(count * 2);
jchar val; env->GetCharArrayRegion((jcharArray)arr, 0, count, (jchar *)ret.ptrw());
env->GetCharArrayRegion((jcharArray)arr, 0, 1, &val);
ret.push_back(val);
}
var = ret; var = ret;
return true; return true;
} break; } break;
case ARG_ARRAY_BIT | ARG_TYPE_SHORT: { case ARG_ARRAY_BIT | ARG_TYPE_SHORT: {
Array ret; PackedInt32Array ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
int32_t *ptr = ret.ptrw();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jshort val; jshort val;
env->GetShortArrayRegion((jshortArray)arr, 0, 1, &val); env->GetShortArrayRegion((jshortArray)arr, i, 1, &val);
ret.push_back(val); ptr[i] = val;
} }
var = ret; var = ret;
return true; return true;
} break; } break;
case ARG_ARRAY_BIT | ARG_TYPE_INT: { case ARG_ARRAY_BIT | ARG_TYPE_INT: {
Array ret; PackedInt32Array ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
for (int i = 0; i < count; i++) { env->GetIntArrayRegion((jintArray)arr, 0, count, ret.ptrw());
jint val;
env->GetIntArrayRegion((jintArray)arr, 0, 1, &val);
ret.push_back(val);
}
var = ret; var = ret;
return true; return true;
} break; } break;
case ARG_ARRAY_BIT | ARG_TYPE_LONG: { case ARG_ARRAY_BIT | ARG_TYPE_LONG: {
Array ret; PackedInt64Array ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
for (int i = 0; i < count; i++) { env->GetLongArrayRegion((jlongArray)arr, 0, count, ret.ptrw());
jlong val;
env->GetLongArrayRegion((jlongArray)arr, 0, 1, &val);
ret.push_back((int64_t)val);
}
var = ret; var = ret;
return true; return true;
} break; } break;
case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: { case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: {
Array ret; PackedFloat32Array ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
for (int i = 0; i < count; i++) { env->GetFloatArrayRegion((jfloatArray)arr, 0, count, ret.ptrw());
jfloat val;
env->GetFloatArrayRegion((jfloatArray)arr, 0, 1, &val);
ret.push_back(val);
}
var = ret; var = ret;
return true; return true;
} break; } break;
case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: { case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: {
Array ret; PackedFloat64Array ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
for (int i = 0; i < count; i++) { env->GetDoubleArrayRegion((jdoubleArray)arr, 0, count, ret.ptrw());
jdouble val;
env->GetDoubleArrayRegion((jdoubleArray)arr, 0, 1, &val);
ret.push_back(val);
}
var = ret; var = ret;
return true; return true;
@ -1002,14 +982,13 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(arr, i); jobject o = env->GetObjectArrayElement(arr, i);
if (!o) { if (o) {
ret.push_back(Variant());
} else {
bool val = env->CallBooleanMethod(o, JavaClassWrapper::singleton->Boolean_booleanValue); bool val = env->CallBooleanMethod(o, JavaClassWrapper::singleton->Boolean_booleanValue);
ret.push_back(val); ret[i] = val;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1019,18 +998,20 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
} break; } break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_BYTE: { case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_BYTE: {
Array ret; PackedByteArray ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
uint8_t *ptr = ret.ptrw();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(arr, i); jobject o = env->GetObjectArrayElement(arr, i);
if (!o) { if (!o) {
ret.push_back(Variant()); ptr[i] = 0;
} else { } else {
int val = env->CallByteMethod(o, JavaClassWrapper::singleton->Byte_byteValue); int val = env->CallByteMethod(o, JavaClassWrapper::singleton->Byte_byteValue);
ret.push_back(val); ptr[i] = (uint8_t)val;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1039,18 +1020,22 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true; return true;
} break; } break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_CHAR: { case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_CHAR: {
Array ret; PackedByteArray ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
// Char arrays are UTF-16 encoded, so it's double the length.
ret.resize(count * 2);
jchar *ptr = (jchar *)ret.ptrw();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(arr, i); jobject o = env->GetObjectArrayElement(arr, i);
if (!o) { if (!o) {
ret.push_back(Variant()); count = i;
break;
} else { } else {
int val = env->CallCharMethod(o, JavaClassWrapper::singleton->Character_characterValue); int val = env->CallCharMethod(o, JavaClassWrapper::singleton->Character_characterValue);
ret.push_back(val); ptr[i] = (jchar)val;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1059,18 +1044,20 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true; return true;
} break; } break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_SHORT: { case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_SHORT: {
Array ret; PackedInt32Array ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
int32_t *ptr = ret.ptrw();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(arr, i); jobject o = env->GetObjectArrayElement(arr, i);
if (!o) { if (!o) {
ret.push_back(Variant()); ptr[i] = 0;
} else { } else {
int val = env->CallShortMethod(o, JavaClassWrapper::singleton->Short_shortValue); int val = env->CallShortMethod(o, JavaClassWrapper::singleton->Short_shortValue);
ret.push_back(val); ptr[i] = val;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1079,18 +1066,20 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true; return true;
} break; } break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_INT: { case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_INT: {
Array ret; PackedInt32Array ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
int32_t *ptr = ret.ptrw();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(arr, i); jobject o = env->GetObjectArrayElement(arr, i);
if (!o) { if (!o) {
ret.push_back(Variant()); ptr[i] = 0;
} else { } else {
int val = env->CallIntMethod(o, JavaClassWrapper::singleton->Integer_integerValue); int val = env->CallIntMethod(o, JavaClassWrapper::singleton->Integer_integerValue);
ret.push_back(val); ptr[i] = val;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1099,18 +1088,20 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true; return true;
} break; } break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_LONG: { case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_LONG: {
Array ret; PackedInt64Array ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
int64_t *ptr = ret.ptrw();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(arr, i); jobject o = env->GetObjectArrayElement(arr, i);
if (!o) { if (!o) {
ret.push_back(Variant()); ptr[i] = 0;
} else { } else {
int64_t val = env->CallLongMethod(o, JavaClassWrapper::singleton->Long_longValue); int64_t val = env->CallLongMethod(o, JavaClassWrapper::singleton->Long_longValue);
ret.push_back(val); ptr[i] = val;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1119,18 +1110,20 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true; return true;
} break; } break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_FLOAT: { case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_FLOAT: {
Array ret; PackedFloat32Array ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
float *ptr = ret.ptrw();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(arr, i); jobject o = env->GetObjectArrayElement(arr, i);
if (!o) { if (!o) {
ret.push_back(Variant()); ptr[i] = 0.0;
} else { } else {
float val = env->CallFloatMethod(o, JavaClassWrapper::singleton->Float_floatValue); float val = env->CallFloatMethod(o, JavaClassWrapper::singleton->Float_floatValue);
ret.push_back(val); ptr[i] = val;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1139,18 +1132,20 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true; return true;
} break; } break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: { case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: {
Array ret; PackedFloat64Array ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
double *ptr = ret.ptrw();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(arr, i); jobject o = env->GetObjectArrayElement(arr, i);
if (!o) { if (!o) {
ret.push_back(Variant()); ptr[i] = 0.0;
} else { } else {
double val = env->CallDoubleMethod(o, JavaClassWrapper::singleton->Double_doubleValue); double val = env->CallDoubleMethod(o, JavaClassWrapper::singleton->Double_doubleValue);
ret.push_back(val); ptr[i] = val;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1160,18 +1155,18 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
} break; } break;
case ARG_ARRAY_BIT | ARG_TYPE_STRING: { case ARG_ARRAY_BIT | ARG_TYPE_STRING: {
Array ret; PackedStringArray ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
String *ptr = ret.ptrw();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(arr, i); jobject o = env->GetObjectArrayElement(arr, i);
if (!o) { if (o) {
ret.push_back(Variant());
} else {
String val = jstring_to_string((jstring)o, env); String val = jstring_to_string((jstring)o, env);
ret.push_back(val); ptr[i] = val;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1180,18 +1175,18 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true; return true;
} break; } break;
case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE: { case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE: {
Array ret; PackedStringArray ret;
jobjectArray arr = (jobjectArray)obj; jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr); int count = env->GetArrayLength(arr);
ret.resize(count);
String *ptr = ret.ptrw();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(arr, i); jobject o = env->GetObjectArrayElement(arr, i);
if (!o) { if (o) {
ret.push_back(Variant());
} else {
String val = charsequence_to_string(env, o); String val = charsequence_to_string(env, o);
ret.push_back(val); ptr[i] = val;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1203,13 +1198,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
Array ret; Array ret;
jobjectArray jarr = (jobjectArray)obj; jobjectArray jarr = (jobjectArray)obj;
int count = env->GetArrayLength(jarr); int count = env->GetArrayLength(jarr);
ret.resize(count);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
jobject o = env->GetObjectArrayElement(jarr, i); jobject o = env->GetObjectArrayElement(jarr, i);
if (!o) { if (o) {
ret.push_back(Variant());
} else {
Callable callable = jcallable_to_callable(env, o); Callable callable = jcallable_to_callable(env, o);
ret.push_back(callable); ret[i] = callable;
} }
env->DeleteLocalRef(o); env->DeleteLocalRef(o);
} }
@ -1218,6 +1212,27 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true; return true;
} break; } break;
case ARG_ARRAY_BIT | ARG_TYPE_CLASS: { case ARG_ARRAY_BIT | ARG_TYPE_CLASS: {
Array ret;
jobjectArray jarr = (jobjectArray)obj;
int count = env->GetArrayLength(jarr);
ret.resize(count);
for (int i = 0; i < count; i++) {
jobject obj = env->GetObjectArrayElement(jarr, i);
if (obj) {
jclass java_class = env->GetObjectClass(obj);
Ref<JavaClass> java_class_wrapped = JavaClassWrapper::singleton->wrap_jclass(java_class);
env->DeleteLocalRef(java_class);
if (java_class_wrapped.is_valid()) {
Ref<JavaObject> java_obj_wrapped = Ref<JavaObject>(memnew(JavaObject(java_class_wrapped, obj)));
ret[i] = java_obj_wrapped;
}
}
env->DeleteLocalRef(obj);
}
var = ret;
return true;
} break; } break;
} }