mirror of
https://github.com/godotengine/godot.git
synced 2025-11-01 14:11:15 +00:00
JavaClassWrapper: Improve handling of typed array arguments
(cherry picked from commit d7672128b5)
This commit is contained in:
parent
33e0265985
commit
ab700d0e18
1 changed files with 249 additions and 43 deletions
|
|
@ -132,6 +132,116 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} 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: {
|
default: {
|
||||||
if (p_args[i]->get_type() != Variant::ARRAY) {
|
if (p_args[i]->get_type() != Variant::ARRAY) {
|
||||||
arg_expected = Variant::ARRAY;
|
arg_expected = Variant::ARRAY;
|
||||||
|
|
@ -307,90 +417,171 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case ARG_ARRAY_BIT | ARG_TYPE_BYTE: {
|
case ARG_ARRAY_BIT | ARG_TYPE_BYTE: {
|
||||||
Array arr = *p_args[i];
|
jbyteArray a = nullptr;
|
||||||
jbyteArray a = env->NewByteArray(arr.size());
|
|
||||||
for (int j = 0; j < arr.size(); j++) {
|
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||||
jbyte val = arr[j];
|
Array arr = *p_args[i];
|
||||||
env->SetByteArrayRegion(a, j, 1, &val);
|
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;
|
argv[i].l = a;
|
||||||
to_free.push_back(a);
|
to_free.push_back(a);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case ARG_ARRAY_BIT | ARG_TYPE_CHAR: {
|
case ARG_ARRAY_BIT | ARG_TYPE_CHAR: {
|
||||||
Array arr = *p_args[i];
|
jcharArray a = nullptr;
|
||||||
jcharArray a = env->NewCharArray(arr.size());
|
|
||||||
for (int j = 0; j < arr.size(); j++) {
|
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||||
jchar val = arr[j];
|
Array arr = *p_args[i];
|
||||||
env->SetCharArrayRegion(a, j, 1, &val);
|
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;
|
argv[i].l = a;
|
||||||
to_free.push_back(a);
|
to_free.push_back(a);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case ARG_ARRAY_BIT | ARG_TYPE_SHORT: {
|
case ARG_ARRAY_BIT | ARG_TYPE_SHORT: {
|
||||||
Array arr = *p_args[i];
|
jshortArray a = nullptr;
|
||||||
jshortArray a = env->NewShortArray(arr.size());
|
|
||||||
for (int j = 0; j < arr.size(); j++) {
|
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||||
jshort val = arr[j];
|
Array arr = *p_args[i];
|
||||||
env->SetShortArrayRegion(a, j, 1, &val);
|
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;
|
argv[i].l = a;
|
||||||
to_free.push_back(a);
|
to_free.push_back(a);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case ARG_ARRAY_BIT | ARG_TYPE_INT: {
|
case ARG_ARRAY_BIT | ARG_TYPE_INT: {
|
||||||
Array arr = *p_args[i];
|
jintArray a = nullptr;
|
||||||
jintArray a = env->NewIntArray(arr.size());
|
|
||||||
for (int j = 0; j < arr.size(); j++) {
|
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||||
jint val = arr[j];
|
Array arr = *p_args[i];
|
||||||
env->SetIntArrayRegion(a, j, 1, &val);
|
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;
|
argv[i].l = a;
|
||||||
to_free.push_back(a);
|
to_free.push_back(a);
|
||||||
} break;
|
} break;
|
||||||
case ARG_ARRAY_BIT | ARG_TYPE_LONG: {
|
case ARG_ARRAY_BIT | ARG_TYPE_LONG: {
|
||||||
Array arr = *p_args[i];
|
jlongArray a = nullptr;
|
||||||
jlongArray a = env->NewLongArray(arr.size());
|
|
||||||
for (int j = 0; j < arr.size(); j++) {
|
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||||
jlong val = (int64_t)arr[j];
|
Array arr = *p_args[i];
|
||||||
env->SetLongArrayRegion(a, j, 1, &val);
|
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;
|
argv[i].l = a;
|
||||||
to_free.push_back(a);
|
to_free.push_back(a);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: {
|
case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: {
|
||||||
Array arr = *p_args[i];
|
jfloatArray a = nullptr;
|
||||||
jfloatArray a = env->NewFloatArray(arr.size());
|
|
||||||
for (int j = 0; j < arr.size(); j++) {
|
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||||
jfloat val = arr[j];
|
Array arr = *p_args[i];
|
||||||
env->SetFloatArrayRegion(a, j, 1, &val);
|
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;
|
argv[i].l = a;
|
||||||
to_free.push_back(a);
|
to_free.push_back(a);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: {
|
case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: {
|
||||||
Array arr = *p_args[i];
|
jdoubleArray a = nullptr;
|
||||||
jdoubleArray a = env->NewDoubleArray(arr.size());
|
|
||||||
for (int j = 0; j < arr.size(); j++) {
|
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||||
jdouble val = arr[j];
|
Array arr = *p_args[i];
|
||||||
env->SetDoubleArrayRegion(a, j, 1, &val);
|
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;
|
argv[i].l = a;
|
||||||
to_free.push_back(a);
|
to_free.push_back(a);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case ARG_ARRAY_BIT | ARG_TYPE_STRING:
|
case ARG_ARRAY_BIT | ARG_TYPE_STRING:
|
||||||
case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE: {
|
case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE: {
|
||||||
Array arr = *p_args[i];
|
jobjectArray a = nullptr;
|
||||||
jobjectArray a = env->NewObjectArray(arr.size(), env->FindClass("java/lang/String"), nullptr);
|
|
||||||
for (int j = 0; j < arr.size(); j++) {
|
if (p_args[i]->get_type() == Variant::ARRAY) {
|
||||||
String s = arr[j];
|
Array arr = *p_args[i];
|
||||||
jstring jStr = env->NewStringUTF(s.utf8().get_data());
|
a = env->NewObjectArray(arr.size(), env->FindClass("java/lang/String"), nullptr);
|
||||||
env->SetObjectArrayElement(a, j, jStr);
|
for (int j = 0; j < arr.size(); j++) {
|
||||||
to_free.push_back(jStr);
|
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;
|
argv[i].l = a;
|
||||||
|
|
@ -410,7 +601,22 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
|
||||||
to_free.push_back(jarr);
|
to_free.push_back(jarr);
|
||||||
} break;
|
} break;
|
||||||
case ARG_ARRAY_BIT | ARG_TYPE_CLASS: {
|
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;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue