Skip to content

Commit dfa8936

Browse files
committed
JavaClassWrapper: Improve handling of typed array arguments
1 parent 1a0bf54 commit dfa8936

File tree

1 file changed

+265
-43
lines changed

1 file changed

+265
-43
lines changed

platform/android/java_class_wrapper.cpp

+265-43
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,116 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
132132
}
133133
}
134134
} break;
135+
case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN: {
136+
if (p_args[i]->get_type() == Variant::ARRAY) {
137+
Array arr = *p_args[i];
138+
if (arr.is_typed() && arr.get_typed_builtin() != Variant::BOOL) {
139+
arg_expected = Variant::ARRAY;
140+
}
141+
} else {
142+
arg_expected = Variant::ARRAY;
143+
}
144+
} break;
145+
case ARG_ARRAY_BIT | ARG_TYPE_BYTE:
146+
case ARG_ARRAY_BIT | ARG_TYPE_CHAR: {
147+
if (p_args[i]->get_type() != Variant::PACKED_BYTE_ARRAY) {
148+
arg_expected = Variant::PACKED_BYTE_ARRAY;
149+
}
150+
} break;
151+
case ARG_ARRAY_BIT | ARG_TYPE_SHORT:
152+
case ARG_ARRAY_BIT | ARG_TYPE_INT: {
153+
if (p_args[i]->get_type() == Variant::ARRAY) {
154+
Array arr = *p_args[i];
155+
if (arr.is_typed() && arr.get_typed_builtin() != Variant::INT) {
156+
arg_expected = Variant::ARRAY;
157+
}
158+
} else if (p_args[i]->get_type() != Variant::PACKED_INT32_ARRAY) {
159+
arg_expected = Variant::ARRAY;
160+
}
161+
} break;
162+
case ARG_ARRAY_BIT | ARG_TYPE_LONG: {
163+
if (p_args[i]->get_type() == Variant::ARRAY) {
164+
Array arr = *p_args[i];
165+
if (arr.is_typed() && arr.get_typed_builtin() != Variant::INT) {
166+
arg_expected = Variant::ARRAY;
167+
}
168+
} else if (p_args[i]->get_type() != Variant::PACKED_INT64_ARRAY) {
169+
arg_expected = Variant::ARRAY;
170+
}
171+
} break;
172+
case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: {
173+
if (p_args[i]->get_type() == Variant::ARRAY) {
174+
Array arr = *p_args[i];
175+
if (arr.is_typed() && arr.get_typed_builtin() != Variant::FLOAT) {
176+
arg_expected = Variant::ARRAY;
177+
}
178+
} else if (p_args[i]->get_type() != Variant::PACKED_FLOAT32_ARRAY) {
179+
arg_expected = Variant::ARRAY;
180+
}
181+
} break;
182+
case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: {
183+
if (p_args[i]->get_type() == Variant::ARRAY) {
184+
Array arr = *p_args[i];
185+
if (arr.is_typed() && arr.get_typed_builtin() != Variant::FLOAT) {
186+
arg_expected = Variant::ARRAY;
187+
}
188+
} else if (p_args[i]->get_type() != Variant::PACKED_FLOAT64_ARRAY) {
189+
arg_expected = Variant::ARRAY;
190+
}
191+
} break;
192+
case ARG_ARRAY_BIT | ARG_TYPE_STRING:
193+
case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE: {
194+
if (p_args[i]->get_type() == Variant::ARRAY) {
195+
Array arr = *p_args[i];
196+
if (arr.is_typed() && arr.get_typed_builtin() != Variant::STRING) {
197+
arg_expected = Variant::ARRAY;
198+
}
199+
} else if (p_args[i]->get_type() != Variant::PACKED_STRING_ARRAY) {
200+
arg_expected = Variant::ARRAY;
201+
}
202+
} break;
203+
case ARG_ARRAY_BIT | ARG_TYPE_CALLABLE: {
204+
if (p_args[i]->get_type() == Variant::ARRAY) {
205+
Array arr = *p_args[i];
206+
if (arr.is_typed() && arr.get_typed_builtin() != Variant::CALLABLE) {
207+
arg_expected = Variant::ARRAY;
208+
}
209+
} else {
210+
arg_expected = Variant::ARRAY;
211+
}
212+
} break;
213+
case ARG_ARRAY_BIT | ARG_TYPE_CLASS: {
214+
if (p_args[i]->get_type() == Variant::ARRAY) {
215+
Array arr = *p_args[i];
216+
if (arr.is_typed() && arr.get_typed_builtin() != Variant::OBJECT) {
217+
arg_expected = Variant::ARRAY;
218+
} else {
219+
String cn = E.param_sigs[i].operator String();
220+
if (cn.begins_with("[L") && cn.ends_with(";")) {
221+
cn = cn.substr(2, cn.length() - 3);
222+
}
223+
jclass c = env->FindClass(cn.utf8().get_data());
224+
if (c) {
225+
for (int j = 0; j < arr.size(); j++) {
226+
Ref<JavaObject> jo = arr[j];
227+
if (jo.is_valid()) {
228+
if (!env->IsInstanceOf(jo->instance, c)) {
229+
arg_expected = Variant::ARRAY;
230+
break;
231+
}
232+
} else {
233+
arg_expected = Variant::ARRAY;
234+
break;
235+
}
236+
}
237+
} else {
238+
arg_expected = Variant::ARRAY;
239+
}
240+
}
241+
} else {
242+
arg_expected = Variant::ARRAY;
243+
}
244+
} break;
135245
default: {
136246
if (p_args[i]->get_type() != Variant::ARRAY) {
137247
arg_expected = Variant::ARRAY;
@@ -307,90 +417,187 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
307417

308418
} break;
309419
case ARG_ARRAY_BIT | ARG_TYPE_BYTE: {
310-
Array arr = *p_args[i];
311-
jbyteArray a = env->NewByteArray(arr.size());
312-
for (int j = 0; j < arr.size(); j++) {
313-
jbyte val = arr[j];
314-
env->SetByteArrayRegion(a, j, 1, &val);
420+
jbyteArray a = nullptr;
421+
422+
if (p_args[i]->get_type() == Variant::ARRAY) {
423+
Array arr = *p_args[i];
424+
a = env->NewByteArray(arr.size());
425+
for (int j = 0; j < arr.size(); j++) {
426+
jbyte val = arr[j];
427+
env->SetByteArrayRegion(a, j, 1, &val);
428+
}
429+
} else if (p_args[i]->get_type() == Variant::PACKED_BYTE_ARRAY) {
430+
PackedByteArray arr = *p_args[i];
431+
a = env->NewByteArray(arr.size());
432+
for (int j = 0; j < arr.size(); j++) {
433+
jbyte val = arr[j];
434+
env->SetByteArrayRegion(a, j, 1, &val);
435+
}
315436
}
437+
316438
argv[i].l = a;
317439
to_free.push_back(a);
318440

319441
} break;
320442
case ARG_ARRAY_BIT | ARG_TYPE_CHAR: {
321-
Array arr = *p_args[i];
322-
jcharArray a = env->NewCharArray(arr.size());
323-
for (int j = 0; j < arr.size(); j++) {
324-
jchar val = arr[j];
325-
env->SetCharArrayRegion(a, j, 1, &val);
443+
jcharArray a = nullptr;
444+
445+
if (p_args[i]->get_type() == Variant::ARRAY) {
446+
Array arr = *p_args[i];
447+
a = env->NewCharArray(arr.size());
448+
for (int j = 0; j < arr.size(); j++) {
449+
jchar val = arr[j];
450+
env->SetCharArrayRegion(a, j, 1, &val);
451+
}
452+
} else if (p_args[i]->get_type() == Variant::PACKED_BYTE_ARRAY) {
453+
PackedByteArray arr = *p_args[i];
454+
a = env->NewCharArray(arr.size());
455+
for (int j = 0; j < arr.size(); j++) {
456+
jchar val = arr[j];
457+
env->SetCharArrayRegion(a, j, 1, &val);
458+
}
326459
}
460+
327461
argv[i].l = a;
328462
to_free.push_back(a);
329463

330464
} break;
331465
case ARG_ARRAY_BIT | ARG_TYPE_SHORT: {
332-
Array arr = *p_args[i];
333-
jshortArray a = env->NewShortArray(arr.size());
334-
for (int j = 0; j < arr.size(); j++) {
335-
jshort val = arr[j];
336-
env->SetShortArrayRegion(a, j, 1, &val);
466+
jshortArray a = nullptr;
467+
468+
if (p_args[i]->get_type() == Variant::ARRAY) {
469+
Array arr = *p_args[i];
470+
a = env->NewShortArray(arr.size());
471+
for (int j = 0; j < arr.size(); j++) {
472+
jshort val = arr[j];
473+
env->SetShortArrayRegion(a, j, 1, &val);
474+
}
475+
} else if (p_args[i]->get_type() == Variant::PACKED_INT32_ARRAY) {
476+
PackedInt32Array arr = *p_args[i];
477+
a = env->NewShortArray(arr.size());
478+
for (int j = 0; j < arr.size(); j++) {
479+
jshort val = arr[j];
480+
env->SetShortArrayRegion(a, j, 1, &val);
481+
}
337482
}
483+
338484
argv[i].l = a;
339485
to_free.push_back(a);
340486

341487
} break;
342488
case ARG_ARRAY_BIT | ARG_TYPE_INT: {
343-
Array arr = *p_args[i];
344-
jintArray a = env->NewIntArray(arr.size());
345-
for (int j = 0; j < arr.size(); j++) {
346-
jint val = arr[j];
347-
env->SetIntArrayRegion(a, j, 1, &val);
489+
jintArray a = nullptr;
490+
491+
if (p_args[i]->get_type() == Variant::ARRAY) {
492+
Array arr = *p_args[i];
493+
a = env->NewIntArray(arr.size());
494+
for (int j = 0; j < arr.size(); j++) {
495+
jint val = arr[j];
496+
env->SetIntArrayRegion(a, j, 1, &val);
497+
}
498+
} else if (p_args[i]->get_type() == Variant::PACKED_INT32_ARRAY) {
499+
PackedInt32Array arr = *p_args[i];
500+
a = env->NewIntArray(arr.size());
501+
for (int j = 0; j < arr.size(); j++) {
502+
jint val = arr[j];
503+
env->SetIntArrayRegion(a, j, 1, &val);
504+
}
348505
}
506+
349507
argv[i].l = a;
350508
to_free.push_back(a);
351509
} break;
352510
case ARG_ARRAY_BIT | ARG_TYPE_LONG: {
353-
Array arr = *p_args[i];
354-
jlongArray a = env->NewLongArray(arr.size());
355-
for (int j = 0; j < arr.size(); j++) {
356-
jlong val = (int64_t)arr[j];
357-
env->SetLongArrayRegion(a, j, 1, &val);
511+
jlongArray a = nullptr;
512+
513+
if (p_args[i]->get_type() == Variant::ARRAY) {
514+
Array arr = *p_args[i];
515+
a = env->NewLongArray(arr.size());
516+
for (int j = 0; j < arr.size(); j++) {
517+
jlong val = (int64_t)arr[j];
518+
env->SetLongArrayRegion(a, j, 1, &val);
519+
}
520+
} else if (p_args[i]->get_type() == Variant::PACKED_INT64_ARRAY) {
521+
PackedInt64Array arr = *p_args[i];
522+
a = env->NewLongArray(arr.size());
523+
for (int j = 0; j < arr.size(); j++) {
524+
jlong val = (int64_t)arr[j];
525+
env->SetLongArrayRegion(a, j, 1, &val);
526+
}
358527
}
528+
359529
argv[i].l = a;
360530
to_free.push_back(a);
361531

362532
} break;
363533
case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: {
364-
Array arr = *p_args[i];
365-
jfloatArray a = env->NewFloatArray(arr.size());
366-
for (int j = 0; j < arr.size(); j++) {
367-
jfloat val = arr[j];
368-
env->SetFloatArrayRegion(a, j, 1, &val);
534+
jfloatArray a = nullptr;
535+
536+
if (p_args[i]->get_type() == Variant::ARRAY) {
537+
Array arr = *p_args[i];
538+
a = env->NewFloatArray(arr.size());
539+
for (int j = 0; j < arr.size(); j++) {
540+
jfloat val = arr[j];
541+
env->SetFloatArrayRegion(a, j, 1, &val);
542+
}
543+
} else if (p_args[i]->get_type() == Variant::PACKED_FLOAT32_ARRAY) {
544+
PackedFloat32Array arr = *p_args[i];
545+
a = env->NewFloatArray(arr.size());
546+
for (int j = 0; j < arr.size(); j++) {
547+
jfloat val = arr[j];
548+
env->SetFloatArrayRegion(a, j, 1, &val);
549+
}
369550
}
551+
370552
argv[i].l = a;
371553
to_free.push_back(a);
372554

373555
} break;
374556
case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: {
375-
Array arr = *p_args[i];
376-
jdoubleArray a = env->NewDoubleArray(arr.size());
377-
for (int j = 0; j < arr.size(); j++) {
378-
jdouble val = arr[j];
379-
env->SetDoubleArrayRegion(a, j, 1, &val);
557+
jdoubleArray a = nullptr;
558+
559+
if (p_args[i]->get_type() == Variant::ARRAY) {
560+
Array arr = *p_args[i];
561+
a = env->NewDoubleArray(arr.size());
562+
for (int j = 0; j < arr.size(); j++) {
563+
jdouble val = arr[j];
564+
env->SetDoubleArrayRegion(a, j, 1, &val);
565+
}
566+
} else if (p_args[i]->get_type() == Variant::PACKED_FLOAT64_ARRAY) {
567+
PackedFloat64Array arr = *p_args[i];
568+
a = env->NewDoubleArray(arr.size());
569+
for (int j = 0; j < arr.size(); j++) {
570+
jdouble val = arr[j];
571+
env->SetDoubleArrayRegion(a, j, 1, &val);
572+
}
380573
}
574+
381575
argv[i].l = a;
382576
to_free.push_back(a);
383577

384578
} break;
385579
case ARG_ARRAY_BIT | ARG_TYPE_STRING:
386580
case ARG_ARRAY_BIT | ARG_TYPE_CHARSEQUENCE: {
387-
Array arr = *p_args[i];
388-
jobjectArray a = env->NewObjectArray(arr.size(), env->FindClass("java/lang/String"), nullptr);
389-
for (int j = 0; j < arr.size(); j++) {
390-
String s = arr[j];
391-
jstring jStr = env->NewStringUTF(s.utf8().get_data());
392-
env->SetObjectArrayElement(a, j, jStr);
393-
to_free.push_back(jStr);
581+
jobjectArray a = nullptr;
582+
583+
if (p_args[i]->get_type() == Variant::ARRAY) {
584+
Array arr = *p_args[i];
585+
a = env->NewObjectArray(arr.size(), env->FindClass("java/lang/String"), nullptr);
586+
for (int j = 0; j < arr.size(); j++) {
587+
String s = arr[j];
588+
jstring jStr = env->NewStringUTF(s.utf8().get_data());
589+
env->SetObjectArrayElement(a, j, jStr);
590+
to_free.push_back(jStr);
591+
}
592+
} else if (p_args[i]->get_type() == Variant::PACKED_STRING_ARRAY) {
593+
PackedStringArray arr = *p_args[i];
594+
a = env->NewObjectArray(arr.size(), env->FindClass("java/lang/String"), nullptr);
595+
for (int j = 0; j < arr.size(); j++) {
596+
String s = arr[j];
597+
jstring jStr = env->NewStringUTF(s.utf8().get_data());
598+
env->SetObjectArrayElement(a, j, jStr);
599+
to_free.push_back(jStr);
600+
}
394601
}
395602

396603
argv[i].l = a;
@@ -410,7 +617,22 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
410617
to_free.push_back(jarr);
411618
} break;
412619
case ARG_ARRAY_BIT | ARG_TYPE_CLASS: {
413-
argv[i].l = nullptr;
620+
String cn = method->param_sigs[i].operator String();
621+
if (cn.begins_with("[L") && cn.ends_with(";")) {
622+
cn = cn.substr(2, cn.length() - 3);
623+
}
624+
jclass c = env->FindClass(cn.utf8().get_data());
625+
if (c) {
626+
Array arr = *p_args[i];
627+
jobjectArray jarr = env->NewObjectArray(arr.size(), c, nullptr);
628+
for (int j = 0; j < arr.size(); j++) {
629+
Ref<JavaObject> jo = arr[j];
630+
env->SetObjectArrayElement(jarr, j, jo->instance);
631+
}
632+
633+
argv[i].l = jarr;
634+
to_free.push_back(jarr);
635+
}
414636
} break;
415637
}
416638
}

0 commit comments

Comments
 (0)