From 2b772fd6aeb33d2c16e18a3756c77e0a380025ec Mon Sep 17 00:00:00 2001 From: Brandon Date: Sat, 23 Dec 2023 10:24:24 -0500 Subject: [PATCH] Fix indexing N-Dimension arrays in python. Added ability to get length of an array if the size is not already known. --- RemoteInput/Plugin/ControlCenter.cxx | 12 ++++++ RemoteInput/Plugin/Python/PythonJavaArray.cxx | 41 +++++++++++++++++-- RemoteInput/Plugin/Python/PythonJavaArray.hxx | 1 + 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/RemoteInput/Plugin/ControlCenter.cxx b/RemoteInput/Plugin/ControlCenter.cxx index d9effb6..68d73cb 100644 --- a/RemoteInput/Plugin/ControlCenter.cxx +++ b/RemoteInput/Plugin/ControlCenter.cxx @@ -671,6 +671,18 @@ void ControlCenter::send_array_response_index_length(Stream &stream, jarray arra break; case ReflectionType::OBJECT: + { + std::vector objects(length); + JNIEnv* env = main_reflector->getEnv(); + for (std::size_t i = 0; i < length; ++i) + { + jobject result = env->GetObjectArrayElement(static_cast(array), index + i); + objects[i] = result ? env->NewGlobalRef(result) : nullptr; + } + stream.write(&objects[0], objects.size() * sizeof(jobject)); + } + break; + case ReflectionType::ARRAY: { std::vector objects(length); diff --git a/RemoteInput/Plugin/Python/PythonJavaArray.cxx b/RemoteInput/Plugin/Python/PythonJavaArray.cxx index 5ae45ba..71ff84b 100644 --- a/RemoteInput/Plugin/Python/PythonJavaArray.cxx +++ b/RemoteInput/Plugin/Python/PythonJavaArray.cxx @@ -82,6 +82,7 @@ PyGetSetDef PyJavaArray_PropertyMembers[] = { }; PyMethodDef PyJavaArray_Methods[] = { + {(char*)"get_length", PYTHON_FASTCALL(Python_JavaArray_GetLength), METH_FASTCALL, (char*)""}, {(char*)"get_1d", PYTHON_FASTCALL(Python_JavaArray_Get1D), METH_FASTCALL | METH_KEYWORDS, (char*)""}, {(char*)"get_2d", PYTHON_FASTCALL(Python_JavaArray_Get2D), METH_FASTCALL | METH_KEYWORDS, (char*)""}, {(char*)"get_3d", PYTHON_FASTCALL(Python_JavaArray_Get3D), METH_FASTCALL | METH_KEYWORDS, (char*)""}, @@ -178,6 +179,14 @@ std::vector python_parse_arguments(const char* (&keywords)[keywords_s return result; } +PyObject* Python_JavaArray_GetLength(PyJavaArray* self, PyObject* args[], Py_ssize_t args_length) noexcept +{ + EIOS* eios = python_get_eios(self); + jarray array = from_python_object(self); + std::size_t length = eios->control_center->reflect_array_size(array); + return to_python_object(length); +} + PyObject* Python_JavaArray_Get1D(PyJavaArray* self, PyObject* args[], Py_ssize_t args_length, PyObject* kwnames) noexcept { static const char* kwlist[] = {"type", "indices", "index", "length", nullptr}; @@ -254,7 +263,7 @@ PyObject* Python_JavaArray_Get2D(PyJavaArray* self, PyObject* args[], Py_ssize_t std::size_t y = from_python_object(y_object); Stream &stream = eios->control_center->reflect_array(array, type, 1, x, y)->data_stream(); - return read_array_type(stream, self, type, 2); + return read_array_type(stream, self, type, 0); } // Array[][] @@ -288,7 +297,7 @@ PyObject* Python_JavaArray_Get3D(PyJavaArray* self, PyObject* args[], Py_ssize_t std::size_t z = from_python_object(z_object); Stream &stream = eios->control_center->reflect_array(array, type, 1, x, y, z)->data_stream(); - return read_array_type(stream, self, type, 3); + return read_array_type(stream, self, type, 0); } // Array[][][] @@ -324,7 +333,7 @@ PyObject* Python_JavaArray_Get4D(PyJavaArray* self, PyObject* args[], Py_ssize_t std::size_t w = from_python_object(z_object); Stream &stream = eios->control_center->reflect_array(array, type, 1, x, y, z, w)->data_stream(); - return read_array_type(stream, self, type, 4); + return read_array_type(stream, self, type, 0); } // Array[][][][] @@ -407,6 +416,32 @@ PyObject* read_array_type(Stream &stream, PyJavaArray* object) PyObject* read_array_type(Stream &stream, PyJavaArray* object, ReflectionType type, std::size_t dimensions) { + if (dimensions == 0) + { + std::size_t size = stream.read(); + if (size == 0) + { + (python->Py_INCREF)(python->Py_GetNone_Object()); + return python->Py_GetNone_Object(); + } + + switch(type) + { + case ReflectionType::CHAR: return to_python_object(stream.read()); + case ReflectionType::BYTE: return to_python_object(stream.read()); + case ReflectionType::BOOL: return to_python_object(stream.read()); + case ReflectionType::SHORT: return to_python_object(stream.read()); + case ReflectionType::INT: return to_python_object(stream.read()); + case ReflectionType::LONG: return to_python_object(stream.read()); + case ReflectionType::FLOAT: return to_python_object(stream.read()); + case ReflectionType::DOUBLE: return to_python_object(stream.read()); + case ReflectionType::STRING: return to_python_object(stream.read()); + case ReflectionType::OBJECT: return python_create_object(object, stream.read()); + case ReflectionType::ARRAY: return python_create_array(object, stream.read(), 0); + default: (python->Py_INCREF)(python->Py_GetNone_Object()); return python->Py_GetNone_Object(); + } + } + if (dimensions == 1) { switch(type) diff --git a/RemoteInput/Plugin/Python/PythonJavaArray.hxx b/RemoteInput/Plugin/Python/PythonJavaArray.hxx index 4efa0b6..72991c6 100644 --- a/RemoteInput/Plugin/Python/PythonJavaArray.hxx +++ b/RemoteInput/Plugin/Python/PythonJavaArray.hxx @@ -13,6 +13,7 @@ extern "C" { #endif +PyObject* Python_JavaArray_GetLength(PyJavaArray* self, PyObject* args[], Py_ssize_t args_length) noexcept; PyObject* Python_JavaArray_Get1D(PyJavaArray* self, PyObject* args[], Py_ssize_t args_length, PyObject* kwnames) noexcept; PyObject* Python_JavaArray_Get2D(PyJavaArray* self, PyObject* args[], Py_ssize_t args_length, PyObject* kwnames) noexcept; PyObject* Python_JavaArray_Get3D(PyJavaArray* self, PyObject* args[], Py_ssize_t args_length, PyObject* kwnames) noexcept;