Merge pull request #102817 from dsnopek/java-class-wrapper-array-improvements
JavaClassWrapper: Improve handling of typed array arguments
This commit is contained in:
commit
8ef0075193
@ -132,6 +132,116 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN: {
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
if (arr.is_typed() && arr.get_typed_builtin() != Variant::BOOL) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} else {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_BYTE:
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_CHAR: {
|
||||
if (p_args[i]->get_type() != Variant::PACKED_BYTE_ARRAY) {
|
||||
arg_expected = Variant::PACKED_BYTE_ARRAY;
|
||||
}
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_SHORT:
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_INT: {
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
if (arr.is_typed() && arr.get_typed_builtin() != Variant::INT) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} else if (p_args[i]->get_type() != Variant::PACKED_INT32_ARRAY) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_LONG: {
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
if (arr.is_typed() && arr.get_typed_builtin() != Variant::INT) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} else if (p_args[i]->get_type() != Variant::PACKED_INT64_ARRAY) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: {
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
if (arr.is_typed() && arr.get_typed_builtin() != Variant::FLOAT) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} else if (p_args[i]->get_type() != Variant::PACKED_FLOAT32_ARRAY) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: {
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
if (arr.is_typed() && arr.get_typed_builtin() != Variant::FLOAT) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} else if (p_args[i]->get_type() != Variant::PACKED_FLOAT64_ARRAY) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_STRING:
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE: {
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
if (arr.is_typed() && arr.get_typed_builtin() != Variant::STRING) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} else if (p_args[i]->get_type() != Variant::PACKED_STRING_ARRAY) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_CALLABLE: {
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
if (arr.is_typed() && arr.get_typed_builtin() != Variant::CALLABLE) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} else {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_CLASS: {
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
if (arr.is_typed() && arr.get_typed_builtin() != Variant::OBJECT) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
} else {
|
||||
String cn = E.param_sigs[i].operator String();
|
||||
if (cn.begins_with("[L") && cn.ends_with(";")) {
|
||||
cn = cn.substr(2, cn.length() - 3);
|
||||
}
|
||||
jclass c = env->FindClass(cn.utf8().get_data());
|
||||
if (c) {
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
Ref<JavaObject> jo = arr[j];
|
||||
if (jo.is_valid()) {
|
||||
if (!env->IsInstanceOf(jo->instance, c)) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
arg_expected = Variant::ARRAY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
arg_expected = Variant::ARRAY;
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
if (p_args[i]->get_type() != Variant::ARRAY) {
|
||||
arg_expected = Variant::ARRAY;
|
||||
@ -307,90 +417,171 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
|
||||
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_BYTE: {
|
||||
Array arr = *p_args[i];
|
||||
jbyteArray a = env->NewByteArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jbyte val = arr[j];
|
||||
env->SetByteArrayRegion(a, j, 1, &val);
|
||||
jbyteArray a = nullptr;
|
||||
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
a = env->NewByteArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jbyte val = arr[j];
|
||||
env->SetByteArrayRegion(a, j, 1, &val);
|
||||
}
|
||||
} else if (p_args[i]->get_type() == Variant::PACKED_BYTE_ARRAY) {
|
||||
PackedByteArray arr = *p_args[i];
|
||||
a = env->NewByteArray(arr.size());
|
||||
env->SetByteArrayRegion(a, 0, arr.size(), (const jbyte *)arr.ptr());
|
||||
}
|
||||
|
||||
argv[i].l = a;
|
||||
to_free.push_back(a);
|
||||
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_CHAR: {
|
||||
Array arr = *p_args[i];
|
||||
jcharArray a = env->NewCharArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jchar val = arr[j];
|
||||
env->SetCharArrayRegion(a, j, 1, &val);
|
||||
jcharArray a = nullptr;
|
||||
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
a = env->NewCharArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jchar val = arr[j];
|
||||
env->SetCharArrayRegion(a, j, 1, &val);
|
||||
}
|
||||
} else if (p_args[i]->get_type() == Variant::PACKED_BYTE_ARRAY) {
|
||||
PackedByteArray arr = *p_args[i];
|
||||
// The data is expected to be UTF-16 encoded, so the length is half the size of the byte array.
|
||||
int size = arr.size() / 2;
|
||||
a = env->NewCharArray(size);
|
||||
env->SetCharArrayRegion(a, 0, size, (const jchar *)arr.ptr());
|
||||
}
|
||||
|
||||
argv[i].l = a;
|
||||
to_free.push_back(a);
|
||||
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_SHORT: {
|
||||
Array arr = *p_args[i];
|
||||
jshortArray a = env->NewShortArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jshort val = arr[j];
|
||||
env->SetShortArrayRegion(a, j, 1, &val);
|
||||
jshortArray a = nullptr;
|
||||
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
a = env->NewShortArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jshort val = arr[j];
|
||||
env->SetShortArrayRegion(a, j, 1, &val);
|
||||
}
|
||||
} else if (p_args[i]->get_type() == Variant::PACKED_INT32_ARRAY) {
|
||||
PackedInt32Array arr = *p_args[i];
|
||||
a = env->NewShortArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jshort val = arr[j];
|
||||
env->SetShortArrayRegion(a, j, 1, &val);
|
||||
}
|
||||
}
|
||||
|
||||
argv[i].l = a;
|
||||
to_free.push_back(a);
|
||||
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_INT: {
|
||||
Array arr = *p_args[i];
|
||||
jintArray a = env->NewIntArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jint val = arr[j];
|
||||
env->SetIntArrayRegion(a, j, 1, &val);
|
||||
jintArray a = nullptr;
|
||||
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
a = env->NewIntArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jint val = arr[j];
|
||||
env->SetIntArrayRegion(a, j, 1, &val);
|
||||
}
|
||||
} else if (p_args[i]->get_type() == Variant::PACKED_INT32_ARRAY) {
|
||||
PackedInt32Array arr = *p_args[i];
|
||||
a = env->NewIntArray(arr.size());
|
||||
env->SetIntArrayRegion(a, 0, arr.size(), arr.ptr());
|
||||
}
|
||||
|
||||
argv[i].l = a;
|
||||
to_free.push_back(a);
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_LONG: {
|
||||
Array arr = *p_args[i];
|
||||
jlongArray a = env->NewLongArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jlong val = (int64_t)arr[j];
|
||||
env->SetLongArrayRegion(a, j, 1, &val);
|
||||
jlongArray a = nullptr;
|
||||
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
a = env->NewLongArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jlong val = (int64_t)arr[j];
|
||||
env->SetLongArrayRegion(a, j, 1, &val);
|
||||
}
|
||||
} else if (p_args[i]->get_type() == Variant::PACKED_INT64_ARRAY) {
|
||||
PackedInt64Array arr = *p_args[i];
|
||||
a = env->NewLongArray(arr.size());
|
||||
env->SetLongArrayRegion(a, 0, arr.size(), arr.ptr());
|
||||
}
|
||||
|
||||
argv[i].l = a;
|
||||
to_free.push_back(a);
|
||||
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: {
|
||||
Array arr = *p_args[i];
|
||||
jfloatArray a = env->NewFloatArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jfloat val = arr[j];
|
||||
env->SetFloatArrayRegion(a, j, 1, &val);
|
||||
jfloatArray a = nullptr;
|
||||
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
a = env->NewFloatArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jfloat val = arr[j];
|
||||
env->SetFloatArrayRegion(a, j, 1, &val);
|
||||
}
|
||||
} else if (p_args[i]->get_type() == Variant::PACKED_FLOAT32_ARRAY) {
|
||||
PackedFloat32Array arr = *p_args[i];
|
||||
a = env->NewFloatArray(arr.size());
|
||||
env->SetFloatArrayRegion(a, 0, arr.size(), arr.ptr());
|
||||
}
|
||||
|
||||
argv[i].l = a;
|
||||
to_free.push_back(a);
|
||||
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: {
|
||||
Array arr = *p_args[i];
|
||||
jdoubleArray a = env->NewDoubleArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jdouble val = arr[j];
|
||||
env->SetDoubleArrayRegion(a, j, 1, &val);
|
||||
jdoubleArray a = nullptr;
|
||||
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
a = env->NewDoubleArray(arr.size());
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
jdouble val = arr[j];
|
||||
env->SetDoubleArrayRegion(a, j, 1, &val);
|
||||
}
|
||||
} else if (p_args[i]->get_type() == Variant::PACKED_FLOAT64_ARRAY) {
|
||||
PackedFloat64Array arr = *p_args[i];
|
||||
a = env->NewDoubleArray(arr.size());
|
||||
env->SetDoubleArrayRegion(a, 0, arr.size(), arr.ptr());
|
||||
}
|
||||
|
||||
argv[i].l = a;
|
||||
to_free.push_back(a);
|
||||
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_STRING:
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE: {
|
||||
Array arr = *p_args[i];
|
||||
jobjectArray a = env->NewObjectArray(arr.size(), env->FindClass("java/lang/String"), nullptr);
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
String s = arr[j];
|
||||
jstring jStr = env->NewStringUTF(s.utf8().get_data());
|
||||
env->SetObjectArrayElement(a, j, jStr);
|
||||
to_free.push_back(jStr);
|
||||
jobjectArray a = nullptr;
|
||||
|
||||
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||
Array arr = *p_args[i];
|
||||
a = env->NewObjectArray(arr.size(), env->FindClass("java/lang/String"), nullptr);
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
String s = arr[j];
|
||||
jstring jStr = env->NewStringUTF(s.utf8().get_data());
|
||||
env->SetObjectArrayElement(a, j, jStr);
|
||||
to_free.push_back(jStr);
|
||||
}
|
||||
} else if (p_args[i]->get_type() == Variant::PACKED_STRING_ARRAY) {
|
||||
PackedStringArray arr = *p_args[i];
|
||||
a = env->NewObjectArray(arr.size(), env->FindClass("java/lang/String"), nullptr);
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
String s = arr[j];
|
||||
jstring jStr = env->NewStringUTF(s.utf8().get_data());
|
||||
env->SetObjectArrayElement(a, j, jStr);
|
||||
to_free.push_back(jStr);
|
||||
}
|
||||
}
|
||||
|
||||
argv[i].l = a;
|
||||
@ -410,7 +601,22 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
|
||||
to_free.push_back(jarr);
|
||||
} break;
|
||||
case ARG_ARRAY_BIT | ARG_TYPE_CLASS: {
|
||||
argv[i].l = nullptr;
|
||||
String cn = method->param_sigs[i].operator String();
|
||||
if (cn.begins_with("[L") && cn.ends_with(";")) {
|
||||
cn = cn.substr(2, cn.length() - 3);
|
||||
}
|
||||
jclass c = env->FindClass(cn.utf8().get_data());
|
||||
if (c) {
|
||||
Array arr = *p_args[i];
|
||||
jobjectArray jarr = env->NewObjectArray(arr.size(), c, nullptr);
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
Ref<JavaObject> jo = arr[j];
|
||||
env->SetObjectArrayElement(jarr, j, jo->instance);
|
||||
}
|
||||
|
||||
argv[i].l = jarr;
|
||||
to_free.push_back(jarr);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user