Browse Source

Improve support for 64-bit types on Android.

This update mappings in the JNI functions to better support 64-bit integers, and adds support for 64-bit float arrays.
The code is mostly reused from 32-bit types.
TechnoPorg 2 years ago
parent
commit
df4597c9ab
2 changed files with 56 additions and 2 deletions
  1. 22 1
      platform/android/api/jni_singleton.h
  2. 34 1
      platform/android/jni_utils.cpp

+ 22 - 1
platform/android/api/jni_singleton.h

@@ -137,6 +137,18 @@ public:
 				ret = sarr;
 				env->DeleteLocalRef(arr);
 			} break;
+			case Variant::PACKED_INT64_ARRAY: {
+				jlongArray arr = (jlongArray)env->CallObjectMethodA(instance, E->get().method, v);
+
+				int fCount = env->GetArrayLength(arr);
+				Vector<int64_t> sarr;
+				sarr.resize(fCount);
+
+				int64_t *w = sarr.ptrw();
+				env->GetLongArrayRegion(arr, 0, fCount, w);
+				ret = sarr;
+				env->DeleteLocalRef(arr);
+			} break;
 			case Variant::PACKED_FLOAT32_ARRAY: {
 				jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v);
 
@@ -149,9 +161,18 @@ public:
 				ret = sarr;
 				env->DeleteLocalRef(arr);
 			} break;
+			case Variant::PACKED_FLOAT64_ARRAY: {
+				jdoubleArray arr = (jdoubleArray)env->CallObjectMethodA(instance, E->get().method, v);
 
-				// TODO: This is missing 64 bits arrays, I have no idea how to do it in JNI.
+				int fCount = env->GetArrayLength(arr);
+				Vector<double> sarr;
+				sarr.resize(fCount);
 
+				double *w = sarr.ptrw();
+				env->GetDoubleArrayRegion(arr, 0, fCount, w);
+				ret = sarr;
+				env->DeleteLocalRef(arr);
+			} break;
 			case Variant::DICTIONARY: {
 				jobject obj = env->CallObjectMethodA(instance, E->get().method, v);
 				ret = _jobject_to_variant(env, obj);

+ 34 - 1
platform/android/jni_utils.cpp

@@ -148,6 +148,15 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
 			v.val.l = arr;
 			v.obj = arr;
 
+		} break;
+		case Variant::PACKED_INT64_ARRAY: {
+			Vector<int64_t> array = *p_arg;
+			jlongArray arr = env->NewLongArray(array.size());
+			const int64_t *r = array.ptr();
+			env->SetLongArrayRegion(arr, 0, array.size(), r);
+			v.val.l = arr;
+			v.obj = arr;
+
 		} break;
 		case Variant::PACKED_BYTE_ARRAY: {
 			Vector<uint8_t> array = *p_arg;
@@ -167,8 +176,15 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
 			v.obj = arr;
 
 		} break;
+		case Variant::PACKED_FLOAT64_ARRAY: {
+			Vector<double> array = *p_arg;
+			jdoubleArray arr = env->NewDoubleArray(array.size());
+			const double *r = array.ptr();
+			env->SetDoubleArrayRegion(arr, 0, array.size(), r);
+			v.val.l = arr;
+			v.obj = arr;
 
-			// TODO: This is missing 64 bits arrays, I have no idea how to do it in JNI.
+		} break;
 
 		default: {
 			v.val.i = 0;
@@ -244,6 +260,17 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
 		return sarr;
 	}
 
+	if (name == "[J") {
+		jlongArray arr = (jlongArray)obj;
+		int fCount = env->GetArrayLength(arr);
+		Vector<int64_t> sarr;
+		sarr.resize(fCount);
+
+		int64_t *w = sarr.ptrw();
+		env->GetLongArrayRegion(arr, 0, fCount, w);
+		return sarr;
+	}
+
 	if (name == "[B") {
 		jbyteArray arr = (jbyteArray)obj;
 		int fCount = env->GetArrayLength(arr);
@@ -344,12 +371,15 @@ Variant::Type get_jni_type(const String &p_type) {
 		{ "void", Variant::NIL },
 		{ "boolean", Variant::BOOL },
 		{ "int", Variant::INT },
+		{ "long", Variant::INT },
 		{ "float", Variant::FLOAT },
 		{ "double", Variant::FLOAT },
 		{ "java.lang.String", Variant::STRING },
 		{ "[I", Variant::PACKED_INT32_ARRAY },
+		{ "[J", Variant::PACKED_INT64_ARRAY },
 		{ "[B", Variant::PACKED_BYTE_ARRAY },
 		{ "[F", Variant::PACKED_FLOAT32_ARRAY },
+		{ "[D", Variant::PACKED_FLOAT64_ARRAY },
 		{ "[Ljava.lang.String;", Variant::PACKED_STRING_ARRAY },
 		{ "org.godotengine.godot.Dictionary", Variant::DICTIONARY },
 		{ nullptr, Variant::NIL }
@@ -376,13 +406,16 @@ const char *get_jni_sig(const String &p_type) {
 		{ "void", "V" },
 		{ "boolean", "Z" },
 		{ "int", "I" },
+		{ "long", "J" },
 		{ "float", "F" },
 		{ "double", "D" },
 		{ "java.lang.String", "Ljava/lang/String;" },
 		{ "org.godotengine.godot.Dictionary", "Lorg/godotengine/godot/Dictionary;" },
 		{ "[I", "[I" },
+		{ "[J", "[J" },
 		{ "[B", "[B" },
 		{ "[F", "[F" },
+		{ "[D", "[D" },
 		{ "[Ljava.lang.String;", "[Ljava/lang/String;" },
 		{ nullptr, "V" }
 	};