// //\r
///////////////////////////////////////////////////////\r
\r
-#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\r
-#ifdef _DEBUG\r
- #undef _DEBUG\r
- #include <Python.h> //header for system python import; add include paths\r
- #include <numpy/arrayobject.h>\r
- #define _DEBUG 1\r
-#else\r
- #include <Python.h> //header for system python import; add include paths\r
- #include <numpy/arrayobject.h>\r
-#endif\r
-\r
#include "sclpy.h"\r
\r
-#include <jni.h> //java connection header\r
-\r
#include <windows.h>\r
\r
-#define JAVA_MAXINT (0x7fffffff)\r
-\r
-#define RUNTIME_EXCEPTION "java/lang/RuntimeException"\r
-#define ILLEGAL_ARGUMENT_EXCEPTION "java/lang/IllegalArgumentException"\r
-#define STRING_CLASS "java/lang/String"\r
-\r
-#define PACKAGE_PREFIX "org/simantics/pythonlink/"\r
-\r
-#define NDARRAY_CLASS (PACKAGE_PREFIX "NDArray")\r
-\r
jint throwException( JNIEnv *env, char *className, char *message )\r
{\r
jclass exClass = (*env)->FindClass( env, className);\r
}\r
\r
int moduleCount = 0;\r
+int initCalled = 0;\r
+int hasNumpy = 0;\r
\r
JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_createContextImpl(JNIEnv *env, jobject thisObj) {\r
char name[16];\r
+\r
+ if (!initCalled) {\r
+ Py_Initialize();\r
+ initCalled = 1;\r
+\r
+ hasNumpy = _import_array();\r
+ hasNumpy = hasNumpy != -1;\r
+ }\r
+\r
sprintf(name, "SCL_%d", ++moduleCount);\r
\r
{\r
PyObject *main = PyImport_AddModule("__main__");\r
\r
PyDict_Merge(PyModule_GetDict(module), PyModule_GetDict(main), 0);\r
+\r
return (jlong)module;\r
}\r
}\r
Py_XDECREF(module);\r
}\r
\r
+PyObject *getPythonBool(jboolean value) {\r
+ if (value) {\r
+ Py_RETURN_TRUE;\r
+ }\r
+ else {\r
+ Py_RETURN_FALSE;\r
+ }\r
+}\r
+\r
PyObject *getPythonString(JNIEnv *env, jstring string) {\r
jsize len = (*env)->GetStringLength(env, string);\r
const jchar *chars = (*env)->GetStringChars(env, string, NULL);\r
return result;\r
}\r
\r
+PyObject *getPythonBooleanList(JNIEnv *env, jbooleanArray value) {\r
+ jsize nitems = (*env)->GetArrayLength(env, value);\r
+ jboolean *values = (*env)->GetBooleanArrayElements(env, value, NULL);\r
+ jint i;\r
+\r
+ PyObject *result = PyList_New(nitems);\r
+ for (i = 0; i < nitems; i++) {\r
+ PyList_SetItem(result, i, getPythonBool(values[i]));\r
+ }\r
+\r
+ (*env)->ReleaseBooleanArrayElements(env, value, values, JNI_ABORT);\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonByteArray(JNIEnv *env, jbyteArray value) {\r
+ jint len = (*env)->GetArrayLength(env, value);\r
+ jbyte *values = (*env)->GetByteArrayElements(env, value, NULL);\r
+\r
+ PyObject *result = PyByteArray_FromStringAndSize(values, len);\r
+\r
+ (*env)->ReleaseByteArrayElements(env, value, values, JNI_ABORT);\r
+ return result;\r
+}\r
+\r
PyObject *getPythonIntegerList(JNIEnv *env, jintArray value) {\r
jsize nitems = (*env)->GetArrayLength(env, value);\r
jint *values = (*env)->GetIntArrayElements(env, value, NULL);\r
return result;\r
}\r
\r
+PyObject *getPythonLongList(JNIEnv *env, jlongArray value) {\r
+ jsize nitems = (*env)->GetArrayLength(env, value);\r
+ jlong *values = (*env)->GetLongArrayElements(env, value, NULL);\r
+ jint i;\r
+\r
+ PyObject *result = PyList_New(nitems);\r
+ for (i = 0; i < nitems; i++) {\r
+ PyList_SetItem(result, i, PyLong_FromLongLong(values[i]));\r
+ }\r
+\r
+ (*env)->ReleaseLongArrayElements(env, value, values, JNI_ABORT);\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonFloatList(JNIEnv *env, jfloatArray value) {\r
+ jsize nitems = (*env)->GetArrayLength(env, value);\r
+ float *values = (*env)->GetFloatArrayElements(env, value, NULL);\r
+ jint i;\r
+\r
+ PyObject *result = PyList_New(nitems);\r
+ for (i = 0; i < nitems; i++) {\r
+ PyList_SetItem(result, i, PyFloat_FromDouble((double)values[i]));\r
+ }\r
+\r
+ (*env)->ReleaseFloatArrayElements(env, value, values, JNI_ABORT);\r
+ return result;\r
+}\r
+\r
PyObject *getPythonDoubleList(JNIEnv *env, jdoubleArray value) {\r
jsize nitems = (*env)->GetArrayLength(env, value);\r
double *values = (*env)->GetDoubleArrayElements(env, value, NULL);\r
}\r
}\r
\r
+PyObject *getPythonBooleanObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, BOOLEANBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)Z");\r
+\r
+ jboolean bvalue = (*env)->CallBooleanMethod(env, binding, getValueMethod, object);\r
+ return getPythonBool(bvalue);\r
+}\r
+\r
+PyObject *getPythonByteObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, BYTEBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)B");\r
+\r
+ jbyte v = (*env)->CallByteMethod(env, binding, getValueMethod, object);\r
+ return PyLong_FromLong(v);\r
+}\r
+\r
+PyObject *getPythonIntegerObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, INTEGERBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)I");\r
+\r
+ jint v = (*env)->CallIntMethod(env, binding, getValueMethod, object);\r
+ return PyLong_FromLong(v);\r
+}\r
+\r
+PyObject *getPythonLongObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, LONGBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)J");\r
+\r
+ jlong v = (*env)->CallLongMethod(env, binding, getValueMethod, object);\r
+ return PyLong_FromLongLong(v);\r
+}\r
+\r
+PyObject *getPythonFloatObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, FLOATBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)F");\r
+\r
+ jfloat v = (*env)->CallFloatMethod(env, binding, getValueMethod, object);\r
+ return PyFloat_FromDouble(v);\r
+}\r
+\r
+PyObject *getPythonDoubleObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, DOUBLEBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue_", "(L" OBJECT_CLASS ";)D");\r
+\r
+ jdouble v = (*env)->CallDoubleMethod(env, binding, getValueMethod, object);\r
+ return PyFloat_FromDouble(v);\r
+}\r
+\r
+PyObject *getPythonStringObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, STRINGBINDING_CLASS);\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue", "(L" OBJECT_CLASS ";)L" STRING_CLASS ";");\r
+\r
+ jobject string = (*env)->CallObjectMethod(env, binding, getValueMethod, object);\r
+ jsize len = (*env)->GetStringLength(env, string);\r
+ const jchar *chars = (*env)->GetStringChars(env, string, NULL);\r
+\r
+ PyObject *value = PyUnicode_DecodeUTF16((char*)chars, 2*len, NULL, NULL);\r
+\r
+ (*env)->ReleaseStringChars(env, string, chars);\r
+ return value;\r
+}\r
+\r
+PyObject *getPythonRecordObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, RECORDBINDING_CLASS);\r
+ jmethodID typeMethod = (*env)->GetMethodID(env, bindingClass, "type", "()L" RECORDTYPE_CLASS ";");\r
+ jmethodID getComponent = (*env)->GetMethodID(env, bindingClass, "getComponent", "(L" OBJECT_CLASS ";I)L" OBJECT_CLASS ";");\r
+ jmethodID getComponentBinding = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "(I)L" BINDING_CLASS ";");\r
+\r
+ jclass recordType = (*env)->FindClass(env, RECORDTYPE_CLASS);\r
+ jmethodID getTypeComponent = (*env)->GetMethodID(env, recordType, "getComponent", "(I)L" COMPONENT_CLASS ";");\r
+ jmethodID getComponentCount = (*env)->GetMethodID(env, recordType, "getComponentCount", "()I");\r
+\r
+ jclass componentClass = (*env)->FindClass(env, COMPONENT_CLASS);\r
+ jfieldID nameField = (*env)->GetFieldID(env, componentClass, "name", "L" STRING_CLASS ";");\r
+\r
+ jobject type = (*env)->CallObjectMethod(env, binding, typeMethod);\r
+ jint n = (*env)->CallIntMethod(env, type, getComponentCount);\r
+ jint i;\r
+\r
+ PyObject *result = PyDict_New();\r
+ for (i = 0; i < n; i++) {\r
+ jobject recordTypeComponent = (*env)->CallObjectMethod(env, type, getComponent, i);\r
+ jstring fieldName = (jstring)(*env)->GetObjectField(env, recordTypeComponent, nameField);\r
+ jobject componentObject = (*env)->CallObjectMethod(env, binding, getComponent, object, i);\r
+ jobject componentBinding = (*env)->CallObjectMethod(env, binding, getComponentBinding, i);\r
+\r
+ PyObject *item = getPythonObject(env, componentObject, componentBinding);\r
+ PyDict_SetItem(result, getPythonString(env, fieldName), item);\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonArrayObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, ARRAYBINDING_CLASS);\r
+ jmethodID componentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "()L" BINDING_CLASS ";");\r
+ jmethodID sizeMethod = (*env)->GetMethodID(env, bindingClass, "size", "(L" OBJECT_CLASS ";)I");\r
+ jmethodID getMethod = (*env)->GetMethodID(env, bindingClass, "get", "(L" OBJECT_CLASS ";I)L" OBJECT_CLASS ";");\r
+\r
+ jobject componentBinding = (*env)->CallObjectMethod(env, binding, componentBindingMethod);\r
+\r
+ jint size = (*env)->CallIntMethod(env, binding, sizeMethod, object);\r
+\r
+ PyObject *result = PyList_New(size);\r
+\r
+ jint i;\r
+ for (i = 0; i < size; i++) {\r
+ jobject item = (*env)->CallObjectMethod(env, binding, getMethod, object, i);\r
+ if (item != NULL)\r
+ PyList_SetItem(result, i, getPythonObject(env, item, componentBinding));\r
+ else\r
+ PyList_SetItem(result, i, Py_None);\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonMapObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass objectClass = (*env)->FindClass(env, OBJECT_CLASS);\r
+ jclass bindingClass = (*env)->FindClass(env, MAPBINDING_CLASS);\r
+ jmethodID getKeyBindingMethod = (*env)->GetMethodID(env, bindingClass, "getKeyBinding", "()L" BINDING_CLASS ";");\r
+ jmethodID getValueBindingMethod = (*env)->GetMethodID(env, bindingClass, "getValueBinding", "()L" BINDING_CLASS ";");\r
+ jmethodID sizeMethod = (*env)->GetMethodID(env, bindingClass, "size", "(L" OBJECT_CLASS ";)I");\r
+ jmethodID getAllMethod = (*env)->GetMethodID(env, bindingClass, "getAll", "(L" OBJECT_CLASS ";[L" OBJECT_CLASS ";[L" OBJECT_CLASS ";)V");\r
+\r
+ jobject keyBinding = (*env)->CallObjectMethod(env, binding, getKeyBindingMethod);\r
+ jobject valueBinding = (*env)->CallObjectMethod(env, binding, getValueBindingMethod);\r
+\r
+ jint size = (*env)->CallIntMethod(env, binding, sizeMethod, object);\r
+ jobjectArray keys = (*env)->NewObjectArray(env, size, objectClass, NULL);\r
+ jobjectArray values = (*env)->NewObjectArray(env, size, objectClass, NULL);\r
+\r
+ PyObject *result = PyDict_New();\r
+ jint i;\r
+\r
+ (*env)->CallVoidMethod(env, binding, getAllMethod, object, keys, values);\r
+\r
+ for (i = 0; i < size; i++) {\r
+ jobject key = (*env)->GetObjectArrayElement(env, keys, i);\r
+ jobject item = (*env)->GetObjectArrayElement(env, values, i);\r
+ PyDict_SetItem(result, getPythonObject(env, key, keyBinding), getPythonObject(env, item, valueBinding));\r
+ }\r
+\r
+ (*env)->DeleteLocalRef(env, keys);\r
+ (*env)->DeleteLocalRef(env, values);\r
+\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonOptionalObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, OPTIONALBINDING_CLASS);\r
+ jmethodID hasValueMethod = (*env)->GetMethodID(env, bindingClass, "hasValue", "(L" OBJECT_CLASS ";)Z");\r
+\r
+ jboolean hasValue = (*env)->CallBooleanMethod(env, binding, hasValueMethod, object);\r
+\r
+ if (hasValue) {\r
+ jmethodID componentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "()L" BINDING_CLASS ";");\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "hasValue", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");\r
+\r
+ jobject componentBinding = (*env)->CallObjectMethod(env, binding, componentBindingMethod);\r
+ jobject value = (*env)->CallObjectMethod(env, binding, getValueMethod, object);\r
+\r
+ return getPythonObject(env, value, componentBinding);\r
+ }\r
+ else {\r
+ return Py_None;\r
+ }\r
+}\r
+\r
+PyObject *getPythonUnionObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, UNIONBINDING_CLASS);\r
+ jmethodID typeMethod = (*env)->GetMethodID(env, bindingClass, "type", "()L" RECORDTYPE_CLASS ";");\r
+ jmethodID getTagMethod = (*env)->GetMethodID(env, bindingClass, "getTag", "(L" OBJECT_CLASS ";)I");\r
+ jmethodID getValueMethod = (*env)->GetMethodID(env, bindingClass, "getValue", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");\r
+ jmethodID getComponentBinding = (*env)->GetMethodID(env, bindingClass, "getComponentBinding", "(I)L" BINDING_CLASS ";");\r
+\r
+ jclass unionType = (*env)->FindClass(env, UNIONTYPE_CLASS);\r
+ jmethodID getTypeComponent = (*env)->GetMethodID(env, unionType, "getComponent", "(I)L" COMPONENT_CLASS ";");\r
+\r
+ jclass componentClass = (*env)->FindClass(env, COMPONENT_CLASS);\r
+ jfieldID nameField = (*env)->GetFieldID(env, componentClass, "name", "L" STRING_CLASS ";");\r
+\r
+ jint tag = (*env)->CallIntMethod(env, binding, getTagMethod, object);\r
+ jobject value = (*env)->CallObjectMethod(env, binding, getValueMethod, object);\r
+\r
+ jobject type = (*env)->CallObjectMethod(env, binding, typeMethod);\r
+ jobject typeComponent = (*env)->CallObjectMethod(env, type, getTypeComponent, tag);\r
+ jstring compName = (*env)->GetObjectField(env, typeComponent, nameField);\r
+\r
+ jobject componentBinding = (*env)->CallObjectMethod(env, binding, getComponentBinding, tag);\r
+\r
+ PyObject *result = PyTuple_New(2);\r
+ PyTuple_SetItem(result, 0, getPythonString(env, compName));\r
+ PyTuple_SetItem(result, 1, getPythonObject(env, value, componentBinding));\r
+\r
+ return result;\r
+}\r
+\r
+PyObject *getPythonVariantObject(JNIEnv *env, jobject object, jobject binding) {\r
+ jclass bindingClass = (*env)->FindClass(env, VARIANTBINDING_CLASS);\r
+ jmethodID getContentMethod = (*env)->GetMethodID(env, bindingClass, "getContent", "(L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");\r
+ jmethodID getContentBindingMethod = (*env)->GetMethodID(env, bindingClass, "getContentBinding", "(L" OBJECT_CLASS ";)L" BINDING_CLASS ";");\r
+\r
+ jobject content = (*env)->CallObjectMethod(env, binding, getContentMethod, object);\r
+ jobject contentBinding = (*env)->CallObjectMethod(env, binding, getContentBindingMethod, object);\r
+\r
+ return getPythonObject(env, content, contentBinding);\r
+}\r
+\r
+PyObject *getPythonObject(JNIEnv *env, jobject value, jobject binding) {\r
+ jclass booleanBinding = (*env)->FindClass(env, BOOLEANBINDING_CLASS);\r
+ jclass byteBinding = (*env)->FindClass(env, BYTEBINDING_CLASS);\r
+ jclass integerBinding = (*env)->FindClass(env, INTEGERBINDING_CLASS);\r
+ jclass longBinding = (*env)->FindClass(env, LONGBINDING_CLASS);\r
+ jclass floatBinding = (*env)->FindClass(env, FLOATBINDING_CLASS);\r
+ jclass doubleBinding = (*env)->FindClass(env, DOUBLEBINDING_CLASS);\r
+ jclass stringBinding = (*env)->FindClass(env, STRINGBINDING_CLASS);\r
+ jclass recordBinding = (*env)->FindClass(env, RECORDBINDING_CLASS);\r
+ jclass arrayBinding = (*env)->FindClass(env, ARRAYBINDING_CLASS);\r
+ jclass mapBinding = (*env)->FindClass(env, MAPBINDING_CLASS);\r
+ jclass optionalBinding = (*env)->FindClass(env, OPTIONALBINDING_CLASS);\r
+ jclass untionBinding = (*env)->FindClass(env, UNIONBINDING_CLASS);\r
+ jclass variantBinding = (*env)->FindClass(env, VARIANTBINDING_CLASS);\r
+\r
+ if ((*env)->IsInstanceOf(env, binding, booleanBinding)) {\r
+ return getPythonBooleanObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, byteBinding)) {\r
+ return getPythonByteObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, integerBinding)) {\r
+ return getPythonIntegerObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, longBinding)) {\r
+ return getPythonLongObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, floatBinding)) {\r
+ return getPythonFloatObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, doubleBinding)) {\r
+ return getPythonDoubleObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, stringBinding)) {\r
+ return getPythonStringObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, recordBinding)) {\r
+ return getPythonRecordObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, arrayBinding)) {\r
+ return getPythonArrayObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, mapBinding)) {\r
+ return getPythonMapObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, optionalBinding)) {\r
+ return getPythonOptionalObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, untionBinding)) {\r
+ return getPythonUnionObject(env, value, binding);\r
+ }\r
+ else if ((*env)->IsInstanceOf(env, binding, variantBinding)) {\r
+ return getPythonVariantObject(env, value, binding);\r
+ }\r
+ else {\r
+ return Py_None;\r
+ }\r
+}\r
+\r
void setPythonVariable(PyObject *module, PyObject *name, PyObject *value) {\r
if (name && value) {\r
PyDict_SetItem(PyModule_GetDict(module), name, value);\r
Py_XDECREF(value);\r
}\r
\r
+static npy_intp nContiguous(int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {\r
+ if (d == nd) {\r
+ ncont[d] = 1;\r
+ return 1;\r
+ }\r
+ else {\r
+ npy_intp n = nContiguous(d+1, nd, strides, dims, ncont);\r
+ ncont[d] = n > 0 && strides[d] == sizeof(double) * n ? dims[d] * n : 0;\r
+ return ncont[d];\r
+ }\r
+}\r
+\r
+static void copyDoubleArrayValues(JNIEnv *env, jdoubleArray array, double *data, npy_intp *offset, int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {\r
+ if (ncont[d] > 0) {\r
+ (*env)->SetDoubleArrayRegion(env, array, (jint)*offset, (jint)ncont[d], data);\r
+ *offset += ncont[d];\r
+ }\r
+ else {\r
+ int i;\r
+ for (i = 0; i < dims[d]; i++) {\r
+ copyDoubleArrayValues(env, array, (double*)((char*)data + strides[d] * i), offset, d+1, nd, strides, dims, ncont);\r
+ }\r
+ }\r
+}\r
+\r
+jobject pythonBoolAsBooleanObject(JNIEnv *env, PyObject *value) {\r
+ jclass booleanClass = (*env)->FindClass(env, "java/lang/Boolean");\r
+ jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, booleanClass, "valueOf", "(Z)Ljava/lang/Boolean;");\r
+\r
+ return (*env)->CallStaticObjectMethod(env, booleanClass, valueOfMethod, (jboolean)(value == Py_True));\r
+}\r
+\r
+jobject pythonLongAsLongObject(JNIEnv *env, PyObject *value) {\r
+ jclass longClass = (*env)->FindClass(env, "java/lang/Long");\r
+ jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, longClass, "valueOf", "(J)Ljava/lang/Long;");\r
+\r
+ return (*env)->CallStaticObjectMethod(env, longClass, valueOfMethod, PyLong_AsLongLong(value));\r
+}\r
+\r
+jobject pythonFloatAsDoubleObject(JNIEnv *env, PyObject *value) {\r
+ jclass doubleClass = (*env)->FindClass(env, "java/lang/Double");\r
+ jmethodID valueOfMethod = (*env)->GetStaticMethodID(env, doubleClass, "valueOf", "(D)Ljava/lang/Double;");\r
+\r
+ return (*env)->CallStaticObjectMethod(env, doubleClass, valueOfMethod, PyFloat_AsDouble(value));\r
+}\r
+\r
+jobject pythonByteArrayAsByteArray(JNIEnv *env, PyObject *value) {\r
+ Py_ssize_t size = PyByteArray_Size(value);\r
+ jbyteArray result = (*env)->NewByteArray(env, (jsize)size);\r
+ char *bytes = PyByteArray_AsString(value);\r
+\r
+ (*env)->SetByteArrayRegion(env, result, 0, size, bytes);\r
+\r
+ return result;\r
+}\r
+\r
jstring pythonStringAsJavaString(JNIEnv *env, PyObject *string) {\r
PyObject *utf16Value = PyUnicode_AsUTF16String(string);\r
Py_ssize_t len = PyBytes_Size(utf16Value) / 2;\r
return result;\r
}\r
\r
-jobjectArray pythonStringListAsJavaArray(JNIEnv *env, PyObject *list) {\r
- Py_ssize_t len = PyList_Size(list);\r
+jobjectArray pythonSequenceAsStringArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
jobjectArray array = (*env)->NewObjectArray(env, jlen, (*env)->FindClass(env, STRING_CLASS), NULL);\r
\r
jint i;\r
\r
for (i = 0; i < jlen; i++) {\r
- PyObject *item = PyList_GetItem(list, i);\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
if (PyUnicode_Check(item)) {\r
jstring value = pythonStringAsJavaString(env, item);\r
(*env)->SetObjectArrayElement(env, array, i, value);\r
return array;\r
}\r
\r
-jdoubleArray pythonListAsDoubleArray(JNIEnv *env, PyObject *list) {\r
- Py_ssize_t len = PyList_Size(list);\r
+jdoubleArray pythonSequenceAsDoubleArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
jdoubleArray array = (*env)->NewDoubleArray(env, jlen);\r
\r
jint i;\r
\r
for (i = 0; i < jlen; i++) {\r
- PyObject *item = PyList_GetItem(list, i);\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
if (PyFloat_Check(item)) {\r
double value = PyFloat_AsDouble(item);\r
(*env)->SetDoubleArrayRegion(env, array, i, 1, &value);\r
return array;\r
}\r
\r
-npy_intp nContiguous(int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {\r
- if (d == nd) {\r
- ncont[d] = 1;\r
- return 1;\r
+jobject pythonObjectAsObject(JNIEnv *env, PyObject *value) {\r
+ if (PyBool_Check(value))\r
+ return pythonBoolAsBooleanObject(env, value);\r
+ else if (PyLong_Check(value))\r
+ return pythonLongAsLongObject(env, value);\r
+ else if (PyFloat_Check(value))\r
+ return pythonFloatAsDoubleObject(env, value);\r
+ else if (PyUnicode_Check(value))\r
+ return pythonStringAsJavaString(env, value);\r
+ else if (PyByteArray_Check(value))\r
+ return pythonByteArrayAsByteArray(env, value);\r
+ else if (PyDict_Check(value))\r
+ return pythonDictionaryAsMap(env, value);\r
+ else if (hasNumpy && PyArray_Check(value))\r
+ return pythonArrayAsNDArray(env, (PyArrayObject *)value);\r
+ else if (PySequence_Check(value))\r
+ return pythonSequenceAsObjectArray(env, value);\r
+ else\r
+ return NULL;\r
+}\r
+\r
+jobjectArray pythonSequenceAsObjectArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
+ jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
+ jobjectArray array = (*env)->NewObjectArray(env, jlen, (*env)->FindClass(env, OBJECT_CLASS), NULL);\r
+\r
+ jint i;\r
+\r
+ for (i = 0; i < jlen; i++) {\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
+ jobject object = pythonObjectAsObject(env, item);\r
+ (*env)->SetObjectArrayElement(env, array, i, object);\r
}\r
- else {\r
- npy_intp n = nContiguous(d+1, nd, strides, dims, ncont);\r
- ncont[d] = n > 0 && strides[d] == sizeof(double) * n ? dims[d] * n : 0;\r
- return ncont[d];\r
+\r
+ return array;\r
+}\r
+\r
+jbooleanArray pythonSequenceAsBooleanArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
+ jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
+ jbooleanArray array = (*env)->NewBooleanArray(env, jlen);\r
+\r
+ jint i;\r
+\r
+ for (i = 0; i < jlen; i++) {\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
+ if (PyBool_Check(item)) {\r
+ jboolean value = item == Py_True;\r
+ (*env)->SetBooleanArrayRegion(env, array, i, 1, &value);\r
+ }\r
+ else {\r
+ throwException(env, RUNTIME_EXCEPTION, "List item not a boolean");\r
+ return NULL;\r
+ }\r
}\r
+\r
+ return array;\r
}\r
\r
-void copyDoubleArrayValues(JNIEnv *env, jdoubleArray array, double *data, npy_intp *offset, int d, int nd, npy_intp *strides, npy_intp *dims, npy_intp *ncont) {\r
- if (ncont[d] > 0) {\r
- (*env)->SetDoubleArrayRegion(env, array, (jint)*offset, (jint)ncont[d], data);\r
- *offset += ncont[d];\r
+jintArray pythonSequenceAsIntegerArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
+ jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
+ jintArray array = (*env)->NewIntArray(env, jlen);\r
+\r
+ jint i;\r
+\r
+ for (i = 0; i < jlen; i++) {\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
+ if (PyLong_Check(item)) {\r
+ jint value = PyLong_AsLong(item);\r
+ (*env)->SetIntArrayRegion(env, array, i, 1, &value);\r
+ }\r
+ else {\r
+ throwException(env, RUNTIME_EXCEPTION, "List item not an integer");\r
+ return NULL;\r
+ }\r
}\r
- else {\r
- int i;\r
- for (i = 0; i < dims[d]; i++) {\r
- copyDoubleArrayValues(env, array, (double*)((char*)data + strides[d] * i), offset, d+1, nd, strides, dims, ncont);\r
+\r
+ return array;\r
+}\r
+\r
+jlongArray pythonSequenceAsLongArray(JNIEnv *env, PyObject *seq) {\r
+ Py_ssize_t len = PySequence_Size(seq);\r
+ jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
+ jlongArray array = (*env)->NewLongArray(env, jlen);\r
+\r
+ jint i;\r
+\r
+ for (i = 0; i < jlen; i++) {\r
+ PyObject *item = PySequence_GetItem(seq, i);\r
+ if (PyLong_Check(item)) {\r
+ jlong value = PyLong_AsLongLong(item);\r
+ (*env)->SetLongArrayRegion(env, array, i, 1, &value);\r
+ }\r
+ else {\r
+ throwException(env, RUNTIME_EXCEPTION, "List item not an integer");\r
+ return NULL;\r
}\r
}\r
+\r
+ return array;\r
}\r
\r
jobject pythonArrayAsNDArray(JNIEnv *env, PyArrayObject *array) {\r
}\r
}\r
\r
-jintArray pythonListAsIntegerArray(JNIEnv *env, PyObject *list) {\r
- Py_ssize_t len = PyList_Size(list);\r
- jsize jlen = (jsize)min(len, JAVA_MAXINT);\r
- jdoubleArray array = (*env)->NewIntArray(env, jlen);\r
+jobject pythonDictionaryAsMap(JNIEnv *env, PyObject *dict) {\r
+ jclass hashmapClass = (*env)->FindClass(env, "java/util/HashMap");\r
+ jmethodID constructor = (*env)->GetMethodID(env, hashmapClass, "<init>", "(I)V");\r
+ jmethodID putMethod = (*env)->GetMethodID(env, hashmapClass, "put", "(L" OBJECT_CLASS ";L" OBJECT_CLASS ";)L" OBJECT_CLASS ";");\r
\r
- jint i;\r
+ Py_ssize_t size = PyDict_Size(dict);\r
+ jobject map = (*env)->NewObject(env, hashmapClass, constructor, (jint)size);\r
\r
- for (i = 0; i < jlen; i++) {\r
- PyObject *item = PyList_GetItem(list, i);\r
- if (PyLong_Check(item)) {\r
- jint value = PyLong_AsLong(item);\r
- (*env)->SetIntArrayRegion(env, array, i, 1, &value);\r
- }\r
- else {\r
- throwException(env, RUNTIME_EXCEPTION, "List item not an integer");\r
- return NULL;\r
- }\r
+ PyObject *key, *value;\r
+ Py_ssize_t pos = 0;\r
+\r
+ while (PyDict_Next(dict, &pos, &key, &value)) {\r
+ jobject keyObject = pythonObjectAsObject(env, key);\r
+ jobject valueObject = pythonObjectAsObject(env, value);\r
+ (*env)->CallObjectMethod(env, map, putMethod, keyObject, valueObject);\r
}\r
\r
- return array;\r
+ return map;\r
}\r
\r
-JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonIntegerVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jint value) {\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonBooleanVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jboolean value) {\r
PyObject *module = (PyObject*)contextID;\r
\r
PyObject *pythonName = getPythonString(env, variableName);\r
- PyObject *val = PyLong_FromLong(value);\r
+ PyObject *val = getPythonBool(value);\r
+\r
+ setPythonVariable(module, pythonName, val);\r
+}\r
+\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonBooleanArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jbooleanArray value) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+ PyObject *val = getPythonBooleanList(env, value);\r
+\r
+ setPythonVariable(module, pythonName, val);\r
+}\r
+\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonLongVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jlong value) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+ PyObject *val = PyLong_FromLongLong(value);\r
\r
setPythonVariable(module, pythonName, val);\r
}\r
setPythonVariable(module, pythonName, val);\r
}\r
\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonLongArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jlongArray value) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+ PyObject *val = getPythonLongList(env, value);\r
+\r
+ setPythonVariable(module, pythonName, val);\r
+}\r
+\r
JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonDoubleVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jdouble value) {\r
PyObject *module = (PyObject*)contextID;\r
\r
setPythonVariable(module, pythonName, val);\r
}\r
\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonFloatArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jfloatArray value) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+ PyObject *val = getPythonFloatList(env, value);\r
+\r
+ setPythonVariable(module, pythonName, val);\r
+}\r
+\r
JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonDoubleArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jdoubleArray value) {\r
PyObject *module = (PyObject*)contextID;\r
\r
JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonNDArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jobject value) {\r
PyObject *module = (PyObject*)contextID;\r
\r
- if (_import_array() < 0) {\r
+ if (!hasNumpy) {\r
throwException(env, RUNTIME_EXCEPTION, "Importing numpy failed");\r
return;\r
}\r
}\r
}\r
\r
+JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_setPythonVariantVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, jobject value, jobject binding) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+ PyObject *val = getPythonObject(env, value, binding);\r
+\r
+ setPythonVariable(module, pythonName, val);\r
+}\r
+\r
JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring statement) {\r
PyObject *module = (PyObject*)contextID;\r
\r
throwException(env, RUNTIME_EXCEPTION, message);\r
}\r
\r
- // Py_XDECREF(globals);\r
-\r
(*env)->ReleaseStringUTFChars(env, statement, utfchars);\r
\r
return result != NULL ? 0 : 1;\r
return 0;\r
}\r
\r
- return pythonStringAsJavaString(env, value);\r
+ {\r
+ jstring result = pythonStringAsJavaString(env, value);\r
+ return result;\r
+ }\r
}\r
\r
JNIEXPORT jobjectArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonStringArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
return 0;\r
}\r
\r
- if (!PyList_Check(value)) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not a list");\r
+ if (!PySequence_Check(value)) {\r
+ throwException(env, RUNTIME_EXCEPTION, "Python variable not a sequence");\r
+ return 0;\r
+ }\r
+\r
+ {\r
+ jobjectArray result = pythonSequenceAsStringArray(env, value);\r
+ return result;\r
+ }\r
+}\r
+\r
+JNIEXPORT jboolean JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonBooleanVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+\r
+ PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
+ if (value == NULL) {\r
+ throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ return 0;\r
+ }\r
+\r
+ if (!PyBool_Check(value)) {\r
+ throwException(env, RUNTIME_EXCEPTION, "Python variable not a boolean");\r
return 0;\r
}\r
\r
- return pythonStringListAsJavaArray(env, value);\r
+ return value == Py_True;\r
}\r
\r
-JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonIntegerVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+JNIEXPORT jbooleanArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonBooleanArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+\r
+ PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
+ if (value == NULL) {\r
+ throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ return 0;\r
+ }\r
+\r
+ if (!PySequence_Check(value)) {\r
+ throwException(env, RUNTIME_EXCEPTION, "Python variable not a sequence");\r
+ return 0;\r
+ }\r
+\r
+ {\r
+ jbooleanArray result = pythonSequenceAsBooleanArray(env, value);\r
+ return result;\r
+ }\r
+}\r
+\r
+JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonLongVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
PyObject *module = (PyObject*)contextID;\r
\r
PyObject *pythonName = getPythonString(env, variableName);\r
return 0;\r
}\r
\r
- return PyLong_AsLong(value);\r
+ {\r
+ jlong result = PyLong_AsLongLong(value);\r
+ return result;\r
+ }\r
}\r
\r
JNIEXPORT jintArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonIntegerArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
return NULL;\r
}\r
\r
- if (!PyList_Check(value)) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not a list");\r
+ if (!PySequence_Check(value)) {\r
+ throwException(env, RUNTIME_EXCEPTION, "Python variable not a sequence");\r
return NULL;\r
}\r
\r
- return pythonListAsIntegerArray(env, value);\r
+ {\r
+ jintArray result = pythonSequenceAsIntegerArray(env, value);\r
+ return result;\r
+ }\r
+}\r
+\r
+JNIEXPORT jlongArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonLongArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+\r
+ PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
+ if (value == NULL) {\r
+ throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ return NULL;\r
+ }\r
+\r
+ if (!PySequence_Check(value)) {\r
+ throwException(env, RUNTIME_EXCEPTION, "Python variable not a sequence");\r
+ return NULL;\r
+ }\r
+\r
+ {\r
+ jlongArray result = pythonSequenceAsLongArray(env, value);\r
+ return result;\r
+ }\r
}\r
\r
JNIEXPORT jdouble JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonDoubleVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
return 0.0;\r
}\r
\r
- return PyFloat_AsDouble(value);\r
+ {\r
+ jdouble result = PyFloat_AsDouble(value);\r
+ return result;\r
+ }\r
}\r
\r
JNIEXPORT jdoubleArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonDoubleArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
return NULL;\r
}\r
\r
- if (!PyList_Check(value)) {\r
- throwException(env, RUNTIME_EXCEPTION, "Python variable not a list");\r
+ if (!PySequence_Check(value)) {\r
+ throwException(env, RUNTIME_EXCEPTION, "Python variable not a sequence");\r
return NULL;\r
}\r
\r
- return pythonListAsDoubleArray(env, value);\r
+ {\r
+ jdoubleArray result = pythonSequenceAsDoubleArray(env, value);\r
+ return result;\r
+ }\r
}\r
\r
JNIEXPORT jobject JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonNDArrayVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
PyObject *module = (PyObject*)contextID;\r
\r
- if (_import_array() < 0) {\r
+ if (!hasNumpy) {\r
throwException(env, RUNTIME_EXCEPTION, "Importing numpy failed");\r
return NULL;\r
}\r
return NULL;\r
}\r
\r
- return pythonArrayAsNDArray(env, (PyArrayObject *)value);\r
+ {\r
+ jobject result = pythonArrayAsNDArray(env, (PyArrayObject *)value);\r
+ return result;\r
+ }\r
+ }\r
+}\r
+\r
+JNIEXPORT jobject JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariantVariableImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+ PyObject *module = (PyObject*)contextID;\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+\r
+ PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);\r
+ if (value == NULL) {\r
+ throwException(env, RUNTIME_EXCEPTION, "Python variable not found");\r
+ return NULL;\r
}\r
+\r
+ hasNumpy = _import_array() != -1;\r
+\r
+ {\r
+ jobject result = pythonObjectAsObject(env, value);\r
+ return result;\r
+ }\r
+}\r
+\r
+JNIEXPORT jint JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariableTypeImpl(JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName) {\r
+ PyObject *module = (PyObject*)contextID;\r
+ PyObject *dict = PyModule_GetDict(module);\r
+\r
+ PyObject *pythonName = getPythonString(env, variableName);\r
+\r
+ if (!PyDict_Contains(dict, pythonName)) {\r
+ return 0;\r
+ }\r
+\r
+ {\r
+ PyObject *value = PyDict_GetItem(dict, pythonName);\r
+\r
+ jint result;\r
+\r
+ if (PyBool_Check(value))\r
+ result = 1;\r
+ else if (PyLong_Check(value))\r
+ result = 2;\r
+ else if (PyFloat_Check(value))\r
+ result = 3;\r
+ else if (PyUnicode_Check(value))\r
+ result = 4;\r
+ else if (PyByteArray_Check(value))\r
+ result = 5;\r
+ else if (PyDict_Check(value))\r
+ result = 6;\r
+ else if (hasNumpy && PyArray_Check(value))\r
+ result = 7;\r
+ else if (PySequence_Check(value))\r
+ result = 8;\r
+ else\r
+ result = -1;\r
+\r
+ return result;\r
+ }\r
+}\r
+\r
+JNIEXPORT jobjectArray JNICALL Java_org_simantics_pythonlink_PythonContext_getPythonVariableNamesImpl(JNIEnv *env, jobject thisObj, jlong contextID) {\r
+ PyObject *module = (PyObject*)contextID;\r
+ PyObject *dict = PyModule_GetDict(module);\r
+\r
+ PyObject *keys = PyDict_Keys(dict);\r
+ Py_ssize_t size = PyList_Size(keys);\r
+\r
+ jobjectArray result = (*env)->NewObjectArray(env, (jsize)size, (*env)->FindClass(env, STRING_CLASS), NULL);\r
+\r
+ Py_ssize_t i;\r
+ for (i = 0; i < size; i++) {\r
+ jstring javaName = pythonStringAsJavaString(env, PyList_GetItem(keys, i));\r
+ (*env)->SetObjectArrayElement(env, result, (jint)i, javaName);\r
+ }\r
+\r
+ Py_XDECREF(keys);\r
+\r
+ return result;\r
}\r
\r
BOOL __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)\r
case DLL_PROCESS_ATTACH:\r
// attach to process\r
// return FALSE to fail DLL load\r
- Py_Initialize();\r
break;\r
\r
case DLL_PROCESS_DETACH:\r
// detach from process\r
- Py_Finalize();\r
break;\r
\r
case DLL_THREAD_ATTACH:\r
#ifndef __MAIN_H__\r
#define __MAIN_H__\r
\r
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\r
+#ifdef _DEBUG\r
+ #undef _DEBUG\r
+ #include <Python.h> //header for system python import; add include paths\r
+ #include <numpy/arrayobject.h>\r
+ #define _DEBUG 1\r
+#else\r
+ #include <Python.h> //header for system python import; add include paths\r
+ #include <numpy/arrayobject.h>\r
+#endif\r
+\r
+#include <jni.h> //java connection header\r
+\r
/* To use this exported function of dll, include this header\r
* in your project.\r
*/\r
#define DLL_EXPORT __declspec(dllimport)\r
#endif\r
\r
+\r
+#define JAVA_MAXINT (0x7fffffff)\r
+\r
+#define RUNTIME_EXCEPTION "java/lang/RuntimeException"\r
+#define ILLEGAL_ARGUMENT_EXCEPTION "java/lang/IllegalArgumentException"\r
+#define OBJECT_CLASS "java/lang/Object"\r
+#define STRING_CLASS "java/lang/String"\r
+#define MAP_CLASS "java/util/Map"\r
+#define SET_CLASS "java/util/Set"\r
+\r
+#define PACKAGE_PREFIX "org/simantics/pythonlink/"\r
+\r
+#define NDARRAY_CLASS (PACKAGE_PREFIX "NDArray")\r
+\r
+#define VARIANT_CLASS "org/simantics/databoard/binding/mutable/Variant"\r
+#define BINDINGS_CLASS "org/simantics/databoard/Bindings"\r
+#define BINDING_CLASS "org/simantics/databoard/binding/Binding"\r
+#define DATATYPE_CLASS "org/simantics/databoard/type/Datatype"\r
+\r
+#define BOOLEANTYPE_CLASS "org/simantics/databoard/type/BooleanType"\r
+#define BYTETYPE_CLASS "org/simantics/databoard/type/ByteType"\r
+#define INTEGERTYPE_CLASS "org/simantics/databoard/type/IntegerType"\r
+#define LONGTYPE_CLASS "org/simantics/databoard/type/LongType"\r
+#define FLOATTYPE_CLASS "org/simantics/databoard/type/FloatType"\r
+#define DOUBLETYPE_CLASS "org/simantics/databoard/type/DoubleType"\r
+#define STRINGTYPE_CLASS "org/simantics/databoard/type/StringType"\r
+#define RECORDTYPE_CLASS "org/simantics/databoard/type/RecordType"\r
+#define ARRAYTYPE_CLASS "org/simantics/databoard/type/ArrayType"\r
+#define MAPTYPE_CLASS "org/simantics/databoard/type/MapType"\r
+#define OPTIONALTYPE_CLASS "org/simantics/databoard/type/OptionalType"\r
+#define UNIONTYPE_CLASS "org/simantics/databoard/type/UnionType"\r
+#define VARIANTTYPE_CLASS "org/simantics/databoard/type/VariantType"\r
+\r
+#define BOOLEANBINDING_CLASS "org/simantics/databoard/binding/BooleanBinding"\r
+#define BYTEBINDING_CLASS "org/simantics/databoard/binding/ByteBinding"\r
+#define INTEGERBINDING_CLASS "org/simantics/databoard/binding/IntegerBinding"\r
+#define LONGBINDING_CLASS "org/simantics/databoard/binding/LongBinding"\r
+#define FLOATBINDING_CLASS "org/simantics/databoard/binding/FloatBinding"\r
+#define DOUBLEBINDING_CLASS "org/simantics/databoard/binding/DoubleBinding"\r
+#define STRINGBINDING_CLASS "org/simantics/databoard/binding/StringBinding"\r
+#define RECORDBINDING_CLASS "org/simantics/databoard/binding/RecordBinding"\r
+#define ARRAYBINDING_CLASS "org/simantics/databoard/binding/ArrayBinding"\r
+#define MAPBINDING_CLASS "org/simantics/databoard/binding/MapBinding"\r
+#define OPTIONALBINDING_CLASS "org/simantics/databoard/binding/OptionalBinding"\r
+#define UNIONBINDING_CLASS "org/simantics/databoard/binding/UnionBinding"\r
+#define VARIANTBINDING_CLASS "org/simantics/databoard/binding/VariantBinding"\r
+\r
+#define COMPONENT_CLASS "org/simantics/databoard/type/Component"\r
+#define TAGGEDOBJECT_CLASS "org/simantics/databoard/binding/mutable/TaggedObject"\r
+\r
+PyObject *getPythonBooleanList(JNIEnv *env, jbooleanArray value);\r
+PyObject *getPythonByteArray(JNIEnv *env, jbyteArray value);\r
+PyObject *getPythonIntegerList(JNIEnv *env, jintArray value);\r
+PyObject *getPythonLongList(JNIEnv *env, jlongArray value);\r
+PyObject *getPythonFloatList(JNIEnv *env, jfloatArray value);\r
+PyObject *getPythonDoubleList(JNIEnv *env, jdoubleArray value);\r
+\r
+PyObject *getPythonObject(JNIEnv *env, jobject object, jobject binding);\r
+\r
+PyObject *getPythonBooleanObject(JNIEnv *env, jobject object, jobject binding);\r
+PyObject *getPythonByteObject(JNIEnv *env, jobject object, jobject binding);\r
+PyObject *getPythonIntegerObject(JNIEnv *env, jobject object, jobject binding);\r
+PyObject *getPythonLongObject(JNIEnv *env, jobject object, jobject binding);\r
+PyObject *getPythonFloatObject(JNIEnv *env, jobject object, jobject binding);\r
+PyObject *getPythonDoubleObject(JNIEnv *env, jobject object, jobject binding);\r
+PyObject *getPythonRecordObject(JNIEnv *env, jobjectArray object, jobject binding);\r
+PyObject *getPythonArrayObject(JNIEnv *env, jobject object, jobject binding);\r
+PyObject *getPythonMapObject(JNIEnv *env, jobject object, jobject binding);\r
+PyObject *getPythonOptionalObject(JNIEnv *env, jobject object, jobject binding);\r
+PyObject *getPythonUnionObject(JNIEnv *env, jobject object, jobject binding);\r
+PyObject *getPythonVariantObject(JNIEnv *env, jobject object, jobject binding);\r
+\r
+void setPythonVariable(PyObject *module, PyObject *name, PyObject *value);\r
+\r
+jobject pythonBoolAsBooleanObject(JNIEnv *env, PyObject *value);\r
+jobject pythonLongAsLongObject(JNIEnv *env, PyObject *value);\r
+jobject pythonFloatAsDoubleObject(JNIEnv *env, PyObject *value);\r
+jobject pythonByteArrayAsByteArray(JNIEnv *env, PyObject *value);\r
+jstring pythonStringAsJavaString(JNIEnv *env, PyObject *string);\r
+jobjectArray pythonSequenceAsObjectArray(JNIEnv *env, PyObject *seq);\r
+jobjectArray pythonSequenceAsStringArray(JNIEnv *env, PyObject *list);\r
+jintArray pythonSequenceAsIntegerArray(JNIEnv *env, PyObject *list);\r
+jlongArray pythonSequenceAsLongArray(JNIEnv *env, PyObject *list);\r
+jdoubleArray pythonSequenceAsDoubleArray(JNIEnv *env, PyObject *list);\r
+jobject pythonDictionaryAsMap(JNIEnv *env, PyObject *dict);\r
+jobject pythonArrayAsNDArray(JNIEnv *env, PyArrayObject *array);\r
+jobject pythonObjectAsObject(JNIEnv *env, PyObject *value);\r
+\r
#endif // __MAIN_H__\r
org.simantics.scl.runtime,\r
gnu.trove3;bundle-version="3.0.3",\r
org.simantics.scl.compiler,\r
- org.simantics.scl.osgi\r
+ org.simantics.scl.osgi,\r
+ org.simantics.db.layer0;bundle-version="1.1.0",\r
+ org.simantics.simulator.variable,\r
+ org.simantics,\r
+ org.simantics.application,\r
+ org.simantics.db.management,\r
+ org.simantics.scl.db;bundle-version="0.1.3",\r
+ org.simantics.modeling;bundle-version="1.1.1"\r
Export-Package: org.simantics.pythonlink\r
Bundle-Activator: org.simantics.pythonlink.Activator\r
Bundle-ActivationPolicy: lazy\r
<booleanAttribute key="clearwslog" value="false"/>\r
<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/pde-junit"/>\r
<booleanAttribute key="default" value="false"/>\r
+<stringAttribute key="deselected_workspace_plugins" value="com.famfamfam.silk,org.simantics.acorn,org.simantics.annotation.ui,org.simantics.backup,org.simantics.backup.db,org.simantics.backup.ontology,org.simantics.basicexpression,org.simantics.browsing.ui,org.simantics.browsing.ui.common,org.simantics.browsing.ui.graph,org.simantics.browsing.ui.graph.impl,org.simantics.browsing.ui.model,org.simantics.browsing.ui.nattable,org.simantics.browsing.ui.platform,org.simantics.browsing.ui.swt,org.simantics.charts,org.simantics.db.procore.ui,org.simantics.debug.browser,org.simantics.debug.browser.ui,org.simantics.debug.graphical,org.simantics.debug.ui,org.simantics.desktop.product,org.simantics.desktop.ui,org.simantics.desktop.ui.ontology,org.simantics.diagram,org.simantics.diagram.connection,org.simantics.diagram.profile,org.simantics.diagram.svg,org.simantics.document,org.simantics.document.linking.ontology,org.simantics.document.linking.ui,org.simantics.document.server,org.simantics.document.server.io,org.simantics.document.swt.core,org.simantics.document.ui,org.simantics.document.ui.ontology,org.simantics.dublincore.ontology,org.simantics.editors,org.simantics.editors.win32,org.simantics.equation,org.simantics.event,org.simantics.excel,org.simantics.export.core,org.simantics.export.ui,org.simantics.fileimport,org.simantics.fileimport.ui,org.simantics.g2d,org.simantics.graphfile,org.simantics.graphviz,org.simantics.graphviz.ui,org.simantics.help.base,org.simantics.help.core,org.simantics.help.files,org.simantics.help.ontology,org.simantics.help.ui,org.simantics.history,org.simantics.image.ui,org.simantics.issues,org.simantics.issues.common,org.simantics.issues.ui,org.simantics.issues.ui.ontology,org.simantics.mapping,org.simantics.matlablink,org.simantics.matlablink.win32.x86_64,org.simantics.message,org.simantics.message.ui,org.simantics.migration.ui,org.simantics.modeling,org.simantics.modeling.template2d.ui,org.simantics.modeling.ui,org.simantics.nativemem,org.simantics.objmap2,org.simantics.scenegraph,org.simantics.scenegraph.loader,org.simantics.scenegraph.profile,org.simantics.scenegraph.swing,org.simantics.scenegraph.ui,org.simantics.scl.commands,org.simantics.scl.compiler.dummy,org.simantics.scl.compiler.tests,org.simantics.scl.data,org.simantics.scl.db,org.simantics.scl.expressions,org.simantics.scl.osgi.tests,org.simantics.scl.ui,org.simantics.scl.ui.editor,org.simantics.selectionview,org.simantics.simulation,org.simantics.simulation.sequences,org.simantics.simulation.ui,org.simantics.spreadsheet,org.simantics.spreadsheet.common,org.simantics.spreadsheet.fileimport,org.simantics.spreadsheet.graph,org.simantics.spreadsheet.ui,org.simantics.structural.synchronization,org.simantics.structural.synchronization.client,org.simantics.structural.ui,org.simantics.structural2,org.simantics.team.ui,org.simantics.threadlog,org.simantics.trend,org.simantics.ui,org.simantics.utils.thread.swt,org.simantics.utils.ui,org.simantics.utils.ui.workbench,org.simantics.views,org.simantics.views.swt,org.simantics.views.swt.client,org.simantics.wiki.ui,org.simantics.workbench,org.simantics.workbench.ontology,org.simantics.workbench.search,winterwell.markdown"/>\r
<stringAttribute key="featureDefaultLocation" value="workspace"/>\r
<stringAttribute key="featurePluginResolution" value="workspace"/>\r
<booleanAttribute key="includeOptional" value="true"/>\r
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.simantics.pythonlink"/>\r
<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>\r
<stringAttribute key="pde.version" value="3.3"/>\r
-<stringAttribute key="product" value="fi.vtt.apros.bootstrap.product"/>\r
+<stringAttribute key="product" value="org.simantics.project.headless"/>\r
<booleanAttribute key="run_in_ui_thread" value="true"/>\r
<setAttribute key="selected_features">\r
+<setEntry value="com.lowagie.text:default"/>\r
+<setEntry value="org.apache.lucene4:default"/>\r
+<setEntry value="org.jfree:default"/>\r
+<setEntry value="org.simantics.browsing.ui:default"/>\r
+<setEntry value="org.simantics.charts:default"/>\r
+<setEntry value="org.simantics.db.client:default"/>\r
+<setEntry value="org.simantics.document.base:default"/>\r
+<setEntry value="org.simantics.document.swt:default"/>\r
+<setEntry value="org.simantics.event.feature:default"/>\r
+<setEntry value="org.simantics.g2d:default"/>\r
+<setEntry value="org.simantics.layer0:default"/>\r
+<setEntry value="org.simantics.migration:default"/>\r
+<setEntry value="org.simantics.modeling:default"/>\r
<setEntry value="org.simantics.pythonlink:default"/>\r
<setEntry value="org.simantics.scl:default"/>\r
+<setEntry value="org.simantics.selectionview:default"/>\r
+<setEntry value="org.simantics.simulation:default"/>\r
+<setEntry value="org.simantics.spreadsheet.ui:default"/>\r
+<setEntry value="org.simantics.spreadsheet:default"/>\r
+<setEntry value="org.simantics.structural:default"/>\r
+<setEntry value="org.simantics.views.swt.client.feature:default"/>\r
+<setEntry value="org.simantics.views.swt.feature:default"/>\r
</setAttribute>\r
+<stringAttribute key="selected_target_plugins" value="ch.qos.logback.classic@default:default,ch.qos.logback.core@default:default,com.ibm.icu@default:default,freemarker@default:default,gnu.trove3@default:default,jakarta-regexp@default:default,javax.annotation@default:default,javax.el@default:default,javax.inject@default:default,javax.servlet.jsp@default:default,javax.servlet@default:default,javax.xml@default:default,org.antlr.runtime@default:default,org.apache.ant@default:default,org.apache.batik.css@default:default,org.apache.batik.util.gui@default:default,org.apache.batik.util@default:default,org.apache.commons.collections@default:default,org.apache.commons.io@default:default,org.apache.commons.jxpath@default:default,org.apache.commons.logging*1.2.0@default:default,org.apache.log4j@default:default,org.apache.lucene4.analyzers-common@default:default,org.apache.lucene4.core@default:default,org.apache.lucene4.queries@default:default,org.apache.lucene4.queryparser@default:default,org.apache.lucene4.sandbox@default:default,org.eclipse.ant.core@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.java7@default:false,org.eclipse.core.filesystem.win32.x86_64@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.net.win32.x86_64@default:false,org.eclipse.core.net@default:default,org.eclipse.core.resources.win32.x86_64@default:false,org.eclipse.core.resources@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.ecf.filetransfer@default:default,org.eclipse.ecf.identity@default:default,org.eclipse.ecf.provider.filetransfer.ssl@default:false,org.eclipse.ecf.provider.filetransfer@default:default,org.eclipse.ecf.ssl@default:false,org.eclipse.ecf@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.concurrent@default:default,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:default,org.eclipse.equinox.frameworkadmin.equinox@default:default,org.eclipse.equinox.frameworkadmin@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,org.eclipse.equinox.p2.console@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.director.app@default:default,org.eclipse.equinox.p2.director@default:default,org.eclipse.equinox.p2.directorywatcher@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.extensionlocation@default:default,org.eclipse.equinox.p2.garbagecollector@default:default,org.eclipse.equinox.p2.jarprocessor@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.p2.operations@default:default,org.eclipse.equinox.p2.publisher.eclipse@default:default,org.eclipse.equinox.p2.publisher@default:default,org.eclipse.equinox.p2.reconciler.dropins@default:default,org.eclipse.equinox.p2.repository.tools@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.p2.touchpoint.eclipse@default:default,org.eclipse.equinox.p2.touchpoint.natives@default:default,org.eclipse.equinox.p2.transport.ecf@default:default,org.eclipse.equinox.p2.updatechecker@default:default,org.eclipse.equinox.p2.updatesite@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.region@default:false,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.security.win32.x86_64@default:false,org.eclipse.equinox.security@default:default,org.eclipse.equinox.simpleconfigurator.manipulator@default:default,org.eclipse.equinox.simpleconfigurator@1:true,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.equinox.util@default:default,org.eclipse.equinox.weaving.hook@default:false,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.win32.win32.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.team.core@default:default,org.eclipse.ui.trace@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.hamcrest.core@default:default,org.junit@default:default,org.mozilla.rhino@default:default,org.objectweb.asm.analysis@default:default,org.objectweb.asm.commons@default:default,org.objectweb.asm.tree@default:default,org.objectweb.asm.util@default:default,org.objectweb.asm@default:default,org.sat4j.core@default:default,org.sat4j.pb@default:default,org.slf4j.api*1.7.20@default:default,org.tukaani.xz@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil@default:default,org.w3c.dom.svg@default:default"/>\r
+<stringAttribute key="selected_workspace_plugins" value="org.apache.batik@default:default,org.simantics.action.ontology@default:default,org.simantics.annotation.ontology@default:default,org.simantics.application@default:default,org.simantics.browsing.ui.ontology@default:default,org.simantics.charts.ontology@default:default,org.simantics.color.ontology@default:default,org.simantics.common@default:default,org.simantics.compressions@default:default,org.simantics.databoard@default:default,org.simantics.datatypes.ontology@default:default,org.simantics.datatypes@default:default,org.simantics.db.common@default:default,org.simantics.db.impl@default:default,org.simantics.db.indexing@default:default,org.simantics.db.layer0@default:default,org.simantics.db.management@default:default,org.simantics.db.procore.server.environment@default:default,org.simantics.db.procore@default:default,org.simantics.db.server@default:default,org.simantics.db.services@default:default,org.simantics.db@default:default,org.simantics.diagram.ontology@default:default,org.simantics.document.base.ontology@default:default,org.simantics.document.ontology@default:default,org.simantics.document.swt.ontology@default:default,org.simantics.event.ontology@default:default,org.simantics.fastlz@default:default,org.simantics.g2d.ontology@default:default,org.simantics.graph.compiler@default:default,org.simantics.graph.db@default:default,org.simantics.graph@default:default,org.simantics.graphfile.ontology@default:default,org.simantics.image.ontology@default:default,org.simantics.image2.ontology@default:default,org.simantics.issues.ontology@default:default,org.simantics.layer0.utils@default:default,org.simantics.layer0@default:default,org.simantics.layer0x.ontology@default:default,org.simantics.logback.configuration@default:false,org.simantics.ltk.antlr@default:default,org.simantics.ltk@default:default,org.simantics.lz4@default:default,org.simantics.modeling.ontology@default:default,org.simantics.modeling.template2d.ontology@default:default,org.simantics.platform.ui.ontology@default:default,org.simantics.project.ontology@default:default,org.simantics.project@default:default,org.simantics.pythonlink.win32.x86_64@default:false,org.simantics.pythonlink@default:default,org.simantics.scenegraph.ontology@default:default,org.simantics.scl.compiler@default:default,org.simantics.scl.osgi@default:default,org.simantics.scl.reflection@default:default,org.simantics.scl.runtime@default:default,org.simantics.selectionview.ontology@default:default,org.simantics.selectionview.ui.ontology@default:default,org.simantics.silk.ontology@default:default,org.simantics.simulation.ontology@default:default,org.simantics.simulator.variable@default:default,org.simantics.softwareconfiguration.ontology@default:default,org.simantics.spreadsheet.ontology@default:default,org.simantics.structural.ontology@default:default,org.simantics.user.ontology@default:default,org.simantics.utils.datastructures@default:default,org.simantics.utils.thread@default:default,org.simantics.utils@default:default,org.simantics.viewpoint.ontology@default:default,org.simantics.views.ontology@default:default,org.simantics@default:default"/>\r
<booleanAttribute key="show_selected_only" value="false"/>\r
<booleanAttribute key="tracing" value="false"/>\r
<booleanAttribute key="useCustomFeatures" value="true"/>\r
<stringAttribute key="pde.version" value="3.3"/>\r
<stringAttribute key="product" value="fi.vtt.apros.bootstrap.product"/>\r
<booleanAttribute key="run_in_ui_thread" value="true"/>\r
-<setAttribute key="selected_features"/>\r
-<stringAttribute key="selected_target_plugins" value="com.ibm.icu@default:default,gnu.trove3@default:default,javax.annotation@default:default,javax.inject@default:default,javax.servlet@default:default,javax.xml@default:default,org.apache.commons.collections@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.runtime@default:true,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.util@default:default,org.eclipse.help@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.win32.win32.x86_64@default:false,org.eclipse.swt@default:default,org.hamcrest.core@default:default,org.junit@default:default,org.objectweb.asm.analysis@default:default,org.objectweb.asm.commons@default:default,org.objectweb.asm.tree@default:default,org.objectweb.asm.util@default:default,org.objectweb.asm@default:default"/>\r
-<stringAttribute key="selected_workspace_plugins" value="org.simantics.common@default:default,org.simantics.databoard@default:default,org.simantics.pythonlink.win32.x86_64*1.0.0.qualifier@default:false,org.simantics.pythonlink@default:default,org.simantics.scl.compiler@default:default,org.simantics.scl.osgi@default:default,org.simantics.scl.runtime@default:default"/>\r
+<setAttribute key="selected_features">\r
+<setEntry value="com.lowagie.text:default"/>\r
+<setEntry value="org.apache.lucene4:default"/>\r
+<setEntry value="org.eclipse.e4.rcp:default"/>\r
+<setEntry value="org.eclipse.ecf.core.feature:default"/>\r
+<setEntry value="org.eclipse.ecf.core.ssl.feature:default"/>\r
+<setEntry value="org.eclipse.ecf.filetransfer.feature:default"/>\r
+<setEntry value="org.eclipse.ecf.filetransfer.httpclient4.feature:default"/>\r
+<setEntry value="org.eclipse.ecf.filetransfer.httpclient4.ssl.feature:default"/>\r
+<setEntry value="org.eclipse.ecf.filetransfer.ssl.feature:default"/>\r
+<setEntry value="org.eclipse.emf.common:default"/>\r
+<setEntry value="org.eclipse.emf.ecore:default"/>\r
+<setEntry value="org.eclipse.rcp:default"/>\r
+<setEntry value="org.jfree:default"/>\r
+<setEntry value="org.simantics.browsing.ui:default"/>\r
+<setEntry value="org.simantics.charts:default"/>\r
+<setEntry value="org.simantics.data:default"/>\r
+<setEntry value="org.simantics.db.client:default"/>\r
+<setEntry value="org.simantics.document.base:default"/>\r
+<setEntry value="org.simantics.document.swt:default"/>\r
+<setEntry value="org.simantics.event.feature:default"/>\r
+<setEntry value="org.simantics.g2d:default"/>\r
+<setEntry value="org.simantics.layer0:default"/>\r
+<setEntry value="org.simantics.migration:default"/>\r
+<setEntry value="org.simantics.modeling:default"/>\r
+<setEntry value="org.simantics.pythonlink:default"/>\r
+<setEntry value="org.simantics.rcp:default"/>\r
+<setEntry value="org.simantics.scl:default"/>\r
+<setEntry value="org.simantics.selectionview:default"/>\r
+<setEntry value="org.simantics.simulation:default"/>\r
+<setEntry value="org.simantics.spreadsheet.ui:default"/>\r
+<setEntry value="org.simantics.spreadsheet:default"/>\r
+<setEntry value="org.simantics.structural:default"/>\r
+<setEntry value="org.simantics.ui.workbench:default"/>\r
+<setEntry value="org.simantics.views.swt.client.feature:default"/>\r
+<setEntry value="org.simantics.views.swt.feature:default"/>\r
+</setAttribute>\r
+<stringAttribute key="selected_target_plugins" value="ch.qos.logback.classic@default:default,ch.qos.logback.core@default:default,com.ibm.icu@default:default,com.lowagie.text@default:default,freemarker@default:default,gnu.trove2@default:default,gnu.trove3@default:default,jakarta-regexp@default:default,javax.annotation@default:default,javax.el@default:default,javax.inject@default:default,javax.servlet.jsp@default:default,javax.servlet@default:default,javax.vecmath@default:default,javax.xml@default:default,org.antlr.runtime@default:default,org.apache.ant@default:default,org.apache.batik.css@default:default,org.apache.batik.util.gui@default:default,org.apache.batik.util@default:default,org.apache.commons.collections@default:default,org.apache.commons.compress@default:default,org.apache.commons.io@default:default,org.apache.commons.jxpath@default:default,org.apache.commons.logging*1.2.0@default:default,org.apache.log4j@default:default,org.apache.lucene4.analyzers-common@default:default,org.apache.lucene4.core@default:default,org.apache.lucene4.queries@default:default,org.apache.lucene4.queryparser@default:default,org.apache.lucene4.sandbox@default:default,org.bouncycastle.bcmail-jdk14@default:default,org.bouncycastle.bcprov-jdk14@default:default,org.bouncycastle.bctsp-jdk14@default:default,org.eclipse.ant.core@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filebuffers@default:default,org.eclipse.core.filesystem.java7@default:false,org.eclipse.core.filesystem.win32.x86_64@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.net.win32.x86_64@default:false,org.eclipse.core.net@default:default,org.eclipse.core.resources.win32.x86_64@default:false,org.eclipse.core.resources@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.ecf.filetransfer@default:default,org.eclipse.ecf.identity@default:default,org.eclipse.ecf.provider.filetransfer.ssl@default:false,org.eclipse.ecf.provider.filetransfer@default:default,org.eclipse.ecf.ssl@default:false,org.eclipse.ecf@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.bidi@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.concurrent@default:default,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:default,org.eclipse.equinox.frameworkadmin.equinox@default:default,org.eclipse.equinox.frameworkadmin@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,org.eclipse.equinox.p2.console@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.director.app@default:default,org.eclipse.equinox.p2.director@default:default,org.eclipse.equinox.p2.directorywatcher@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.extensionlocation@default:default,org.eclipse.equinox.p2.garbagecollector@default:default,org.eclipse.equinox.p2.jarprocessor@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.p2.operations@default:default,org.eclipse.equinox.p2.publisher.eclipse@default:default,org.eclipse.equinox.p2.publisher@default:default,org.eclipse.equinox.p2.reconciler.dropins@default:default,org.eclipse.equinox.p2.repository.tools@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.p2.touchpoint.eclipse@default:default,org.eclipse.equinox.p2.touchpoint.natives@default:default,org.eclipse.equinox.p2.transport.ecf@default:default,org.eclipse.equinox.p2.updatechecker@default:default,org.eclipse.equinox.p2.updatesite@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.region@default:false,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.security.win32.x86_64@default:false,org.eclipse.equinox.security@default:default,org.eclipse.equinox.simpleconfigurator.manipulator@default:default,org.eclipse.equinox.simpleconfigurator@1:true,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.equinox.util@default:default,org.eclipse.equinox.weaving.hook@default:false,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface.text@default:default,org.eclipse.jface@default:default,org.eclipse.nebula.widgets.pgroup@default:default,org.eclipse.nebula.widgets.tablecombo@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.win32.win32.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.text@default:default,org.eclipse.ui.editors@default:default,org.eclipse.ui.forms@default:default,org.eclipse.ui.ide@default:default,org.eclipse.ui.views@default:default,org.eclipse.ui.win32@default:false,org.eclipse.ui.workbench.texteditor@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.hamcrest.core@default:default,org.jfree.jchart@default:default,org.jfree.jcommon@default:default,org.junit@default:default,org.mozilla.rhino@default:default,org.objectweb.asm.analysis@default:default,org.objectweb.asm.commons@default:default,org.objectweb.asm.tree@default:default,org.objectweb.asm.util@default:default,org.objectweb.asm@default:default,org.sat4j.core@default:default,org.sat4j.pb@default:default,org.slf4j.api*1.7.20@default:default,org.tukaani.xz@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil@default:default,org.w3c.dom.svg@default:default"/>\r
+<stringAttribute key="selected_workspace_plugins" value="org.apache.batik@default:default,org.simantics.action.ontology@default:default,org.simantics.annotation.ontology@default:default,org.simantics.application@default:default,org.simantics.basicexpression@default:default,org.simantics.browsing.ui.common@default:default,org.simantics.browsing.ui.model@default:default,org.simantics.browsing.ui.ontology@default:default,org.simantics.browsing.ui@default:default,org.simantics.charts.ontology@default:default,org.simantics.color.ontology@default:default,org.simantics.common@default:default,org.simantics.compressions@default:default,org.simantics.databoard@default:default,org.simantics.datatypes.ontology@default:default,org.simantics.datatypes@default:default,org.simantics.db.common@default:default,org.simantics.db.impl@default:default,org.simantics.db.indexing@default:default,org.simantics.db.layer0@default:default,org.simantics.db.management@default:default,org.simantics.db.procore.server.environment@default:default,org.simantics.db.procore@default:default,org.simantics.db.server@default:default,org.simantics.db.services@default:default,org.simantics.db@default:default,org.simantics.diagram.connection@default:default,org.simantics.diagram.ontology@default:default,org.simantics.diagram@default:default,org.simantics.document.base.ontology@default:default,org.simantics.document.ontology@default:default,org.simantics.document.swt.ontology@default:default,org.simantics.event.ontology@default:default,org.simantics.export.core@default:default,org.simantics.fastlz@default:default,org.simantics.g2d.ontology@default:default,org.simantics.g2d@default:default,org.simantics.graph.compiler@default:default,org.simantics.graph.db@default:default,org.simantics.graph@default:default,org.simantics.graphfile.ontology@default:default,org.simantics.graphviz.ui@default:default,org.simantics.graphviz@default:default,org.simantics.history@default:default,org.simantics.image.ontology@default:default,org.simantics.image2.ontology@default:default,org.simantics.issues.common@default:default,org.simantics.issues.ontology@default:default,org.simantics.issues.ui.ontology@default:default,org.simantics.issues@default:default,org.simantics.layer0.utils@default:default,org.simantics.layer0@default:default,org.simantics.layer0x.ontology@default:default,org.simantics.logback.configuration@default:false,org.simantics.ltk.antlr@default:default,org.simantics.ltk@default:default,org.simantics.lz4@default:default,org.simantics.mapping@default:default,org.simantics.modeling.ontology@default:default,org.simantics.modeling.template2d.ontology@default:default,org.simantics.modeling@default:default,org.simantics.platform.ui.ontology@default:default,org.simantics.project.ontology@default:default,org.simantics.project@default:default,org.simantics.pythonlink.win32.x86_64@default:false,org.simantics.pythonlink@default:default,org.simantics.scenegraph.loader@default:default,org.simantics.scenegraph.ontology@default:default,org.simantics.scenegraph.profile@default:default,org.simantics.scenegraph@default:default,org.simantics.scl.commands@default:default,org.simantics.scl.compiler@default:default,org.simantics.scl.db@default:default,org.simantics.scl.osgi@default:default,org.simantics.scl.reflection@default:default,org.simantics.scl.runtime@default:default,org.simantics.scl.ui@default:default,org.simantics.selectionview.ontology@default:default,org.simantics.selectionview.ui.ontology@default:default,org.simantics.silk.ontology@default:default,org.simantics.simulation.ontology@default:default,org.simantics.simulation@default:default,org.simantics.simulator.variable@default:default,org.simantics.softwareconfiguration.ontology@default:default,org.simantics.spreadsheet.ontology@default:default,org.simantics.structural.ontology@default:default,org.simantics.structural2@default:default,org.simantics.threadlog@default:default,org.simantics.trend@default:default,org.simantics.ui@default:default,org.simantics.user.ontology@default:default,org.simantics.utils.datastructures@default:default,org.simantics.utils.thread.swt@default:default,org.simantics.utils.thread@default:default,org.simantics.utils.ui.workbench@default:default,org.simantics.utils.ui@default:default,org.simantics.utils@default:default,org.simantics.viewpoint.ontology@default:default,org.simantics.views.ontology@default:default,org.simantics@default:default"/>\r
<booleanAttribute key="show_selected_only" value="false"/>\r
<booleanAttribute key="tracing" value="false"/>\r
-<booleanAttribute key="useCustomFeatures" value="false"/>\r
+<booleanAttribute key="useCustomFeatures" value="true"/>\r
<booleanAttribute key="useDefaultConfig" value="true"/>\r
<booleanAttribute key="useDefaultConfigArea" value="false"/>\r
<booleanAttribute key="useProduct" value="false"/>\r
-import "Vector"\r
-\r
effect Python\r
"Simantics/Python/Python"\r
"org.simantics.pythonlink.PythonContext"\r
@JavaName equals\r
ndarrayEquals :: NDArray -> NDArray -> Boolean\r
\r
+class NDArrayInput a where\r
+ ndarrayInput :: a -> ([Integer], [Double])\r
+ \r
+instance NDArrayInput [Double] where\r
+ ndarrayInput v = ([length v], v)\r
+ \r
+instance (NDArrayInput [a]) => NDArrayInput [[a]] where\r
+ ndarrayInput v = let\r
+ inp = map ndarrayInput v\r
+ dims = map fst inp\r
+ vals = join $ map snd inp\r
+ in\r
+ if not (all (== (dims!0)) dims) then\r
+ fail "List of lists not of uniform dimension"\r
+ else\r
+ ([length v] + (dims!0), vals)\r
+\r
+ndarrayFromList :: NDArrayInput a => a -> NDArray\r
+ndarrayFromList v = ndarrayN (vector dims) (vector vals) where\r
+ (dims, vals) = ndarrayInput v\r
+\r
instance Show NDArray where\r
show = ndarrayToString\r
\r
\r
executePythonStatement :: String -> <Python> ()\r
\r
+ setPythonBooleanVariable :: String -> Boolean -> <Python> ()\r
setPythonIntegerVariable :: String -> Integer -> <Python> ()\r
- setPythonIntegerArrayVariable :: String -> Vector Integer -> <Python> ()\r
+ setPythonLongVariable :: String -> Long -> <Python> ()\r
setPythonDoubleVariable :: String -> Double -> <Python> ()\r
- setPythonDoubleArrayVariable :: String -> Vector Double -> <Python> ()\r
setPythonStringVariable :: String -> String -> <Python> ()\r
+ \r
+ setPythonBooleanArrayVariable :: String -> Vector Boolean -> <Python> ()\r
+ setPythonIntegerArrayVariable :: String -> Vector Integer -> <Python> ()\r
+ setPythonLongArrayVariable :: String -> Vector Long -> <Python> ()\r
+ setPythonDoubleArrayVariable :: String -> Vector Double -> <Python> ()\r
setPythonStringArrayVariable :: String -> Vector String -> <Python> ()\r
setPythonNDArrayVariable :: String -> NDArray -> <Python> ()\r
\r
+ getPythonBooleanVariable :: String -> <Python> Boolean\r
getPythonIntegerVariable :: String -> <Python> Integer\r
- getPythonIntegerArrayVariable :: String -> <Python> Vector Integer\r
+ getPythonLongVariable :: String -> <Python> Long\r
getPythonDoubleVariable :: String -> <Python> Double\r
- getPythonDoubleArrayVariable :: String -> <Python> Vector Double\r
getPythonStringVariable :: String -> <Python> String\r
+ \r
+ getPythonBooleanArrayVariable :: String -> <Python> Vector Boolean\r
+ getPythonIntegerArrayVariable :: String -> <Python> Vector Integer\r
+ getPythonLongArrayVariable :: String -> <Python> Vector Long\r
+ getPythonDoubleArrayVariable :: String -> <Python> Vector Double\r
getPythonStringArrayVariable :: String -> <Python> Vector String\r
getPythonNDArrayVariable :: String -> <Python> NDArray\r
\r
+ setPythonVariantVariable :: String -> Variant -> <Python> ()\r
+ getPythonVariantVariable :: String -> <Python> Variant\r
+\r
importJava "org.simantics.pythonlink.Python" where\r
openPythonContext :: <Proc> PythonContext\r
\r
--- /dev/null
+include "Python"\r
+include "Simantics/Variables"\r
+\r
+importJava "org.simantics.pythonlink.Python" where\r
+ getPythonContextVariable :: PythonContext -> <Proc> Variable\r
package org.simantics.pythonlink;\r
\r
+import java.util.List;\r
+import java.util.concurrent.TimeUnit;\r
+\r
+import org.simantics.db.layer0.variable.NodeSupport;\r
+import org.simantics.db.layer0.variable.StandardGraphChildVariable;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.VariableNode;\r
+import org.simantics.pythonlink.PythonContext.Listener;\r
+import org.simantics.pythonlink.variable.PythonNode;\r
+import org.simantics.pythonlink.variable.PythonNodeManager;\r
import org.simantics.scl.runtime.SCLContext;\r
import org.simantics.scl.runtime.function.Function;\r
import org.simantics.scl.runtime.tuple.Tuple0;\r
+import org.simantics.simulator.variable.NodeManager;\r
+import org.simantics.simulator.variable.exceptions.NodeManagerException;\r
\r
public class Python {\r
private static final String PYTHON_CONTEXT = "Simantics/Python/Python";\r
return new PythonContext();\r
}\r
\r
+ public static Variable getPythonContextVariable(PythonContext context) {\r
+ NodeManager<PythonNode> nodeManager = new PythonNodeManager(context);\r
+ PythonNode root;\r
+ try {\r
+ root = nodeManager.getNode("/");\r
+ } catch (NodeManagerException e) {\r
+ // Should not happen\r
+ throw new RuntimeException("Getting root Python node failed");\r
+ }\r
+ \r
+ final NodeSupport<PythonNode> support = new NodeSupport<PythonNode>(nodeManager, 0, TimeUnit.NANOSECONDS);\r
+ \r
+ context.addListener(new Listener() {\r
+ @Override\r
+ public void updated(String variableName) {\r
+ try {\r
+ PythonNode root = nodeManager.getNode("/");\r
+ if (variableName != null) {\r
+ PythonNode node = nodeManager.getNode(variableName);\r
+ if (node != null) support.valueCache.removeListening(node);\r
+ support.structureCache.removeListening(root);\r
+ }\r
+ else {\r
+ List<PythonNode> props = nodeManager.getProperties(root);\r
+ for (PythonNode p : props)\r
+ support.valueCache.removeListening(p);\r
+ support.structureCache.removeListening(root);\r
+ }\r
+ \r
+ support.valueCache.clearExpired();\r
+ support.structureCache.clearExpired();\r
+ } catch (NodeManagerException e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public void closed() {\r
+ }\r
+ });\r
+ \r
+ return new StandardGraphChildVariable(null, new VariableNode<PythonNode>(support, root), null);\r
+ }\r
+ \r
@SuppressWarnings( { "unchecked", "rawtypes" } )\r
public static Object runPythonF(Function f) {\r
SCLContext sclContext = SCLContext.getCurrent();\r
package org.simantics.pythonlink;\r
\r
import java.io.Closeable;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+import java.util.concurrent.Callable;\r
+import java.util.concurrent.ExecutionException;\r
+import java.util.concurrent.ExecutorService;\r
+import java.util.concurrent.Executors;\r
+import java.util.regex.Pattern;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
\r
public class PythonContext implements Closeable {\r
private long contextID;\r
\r
+ public interface Listener {\r
+ void updated(String variableName);\r
+ void closed();\r
+ }\r
+ \r
+ static ExecutorService pythonExecutor = Executors.newSingleThreadExecutor();\r
+ \r
+ Set<Listener> listeners = new HashSet<>();\r
+ \r
+ public enum VariableType {\r
+ NO_VARIABLE,\r
+ BOOLEAN,\r
+ LONG,\r
+ FLOAT,\r
+ STRING,\r
+ BYTEARRAY,\r
+ DICTIONARY,\r
+ NDARRAY,\r
+ SEQUENCE,\r
+ UNKNOWN\r
+ }\r
+ \r
+ static Pattern namePattern = Pattern.compile("([a-zA-Z_][a-zA-Z_0-9]*)");\r
+ \r
PythonContext() {\r
contextID = createContextImpl();\r
}\r
\r
+ public void addListener(Listener listener) {\r
+ listeners.add(listener);\r
+ }\r
+ \r
+ public void removeListener(Listener listener) {\r
+ listeners.remove(listener);\r
+ }\r
+ \r
@Override\r
public void close() {\r
long id = contextID;\r
contextID = 0;\r
if (id != 0) deleteContextImpl(id);\r
+ \r
+ for (Listener l : listeners) {\r
+ l.closed();\r
+ }\r
}\r
\r
+ public boolean isOpen() {\r
+ return contextID != 0;\r
+ }\r
+ \r
@Override\r
protected void finalize() throws Throwable {\r
super.finalize();\r
}\r
\r
public void executePythonStatement(String statement) {\r
- executePythonStatementImpl( contextID, statement );\r
+ execute(() -> executePythonStatementImpl( contextID, statement ));\r
+ for (Listener l : listeners) { l.updated(null); }\r
}\r
\r
// Setters\r
\r
+ public void setPythonBooleanVariable(String variableName, boolean value) {\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonBooleanVariableImpl(contextID, variableName, value));\r
+ for (Listener l : listeners) { l.updated(variableName); }\r
+ }\r
+\r
public void setPythonIntegerVariable(String variableName, int value) {\r
- setPythonIntegerVariableImpl(contextID, variableName, value);\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonLongVariableImpl(contextID, variableName, value));\r
+ for (Listener l : listeners) { l.updated(variableName); }\r
+ }\r
+ public void setPythonLongVariable(String variableName, long value) {\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonLongVariableImpl(contextID, variableName, value));\r
+ for (Listener l : listeners) { l.updated(variableName); }\r
}\r
public void setPythonDoubleVariable(String variableName, double value) {\r
- setPythonDoubleVariableImpl(contextID, variableName, value);\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonDoubleVariableImpl(contextID, variableName, value));\r
+ for (Listener l : listeners) { l.updated(variableName); }\r
}\r
public void setPythonStringVariable(String variableName, String value) {\r
- setPythonStringVariableImpl(contextID, variableName, value);\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonStringVariableImpl(contextID, variableName, value));\r
+ for (Listener l : listeners) { l.updated(variableName); }\r
}\r
\r
+ public void setPythonBooleanArrayVariable(String variableName, boolean[] value) {\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonBooleanArrayVariableImpl(contextID, variableName, value));\r
+ for (Listener l : listeners) { l.updated(variableName); }\r
+ }\r
public void setPythonIntegerArrayVariable(String variableName, int[] value) {\r
- setPythonIntegerArrayVariableImpl(contextID, variableName, value);\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonIntegerArrayVariableImpl(contextID, variableName, value));\r
+ for (Listener l : listeners) { l.updated(variableName); }\r
+ }\r
+ public void setPythonLongArrayVariable(String variableName, long[] value) {\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonLongArrayVariableImpl(contextID, variableName, value));\r
+ for (Listener l : listeners) { l.updated(variableName); }\r
}\r
public void setPythonDoubleArrayVariable(String variableName, double[] value) {\r
- setPythonDoubleArrayVariableImpl(contextID, variableName, value);\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonDoubleArrayVariableImpl(contextID, variableName, value));\r
+ for (Listener l : listeners) { l.updated(variableName); }\r
}\r
public void setPythonStringArrayVariable(String variableName, String[] value) {\r
- setPythonStringArrayVariableImpl(contextID, variableName, value);\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonStringArrayVariableImpl(contextID, variableName, value));\r
+ for (Listener l : listeners) { l.updated(variableName); }\r
}\r
\r
// Getters\r
\r
+ public boolean getPythonBooleanVariable(String variableName) {\r
+ checkValidName(variableName);\r
+ return getPythonBooleanVariableImpl(contextID, variableName);\r
+ }\r
public int getPythonIntegerVariable(String variableName) {\r
- return getPythonIntegerVariableImpl(contextID, variableName);\r
+ checkValidName(variableName);\r
+ long value = execute(() -> getPythonLongVariableImpl(contextID, variableName));\r
+ if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE)\r
+ throw new RuntimeException("Python value not in integer range");\r
+ return (int) value;\r
+ }\r
+ public long getPythonLongVariable(String variableName) {\r
+ checkValidName(variableName);\r
+ return execute(() -> getPythonLongVariableImpl(contextID, variableName));\r
}\r
public double getPythonDoubleVariable(String variableName) {\r
- return getPythonDoubleVariableImpl(contextID, variableName);\r
+ checkValidName(variableName);\r
+ return execute(() -> getPythonDoubleVariableImpl(contextID, variableName));\r
}\r
public String getPythonStringVariable(String variableName) {\r
- return getPythonStringVariableImpl(contextID, variableName);\r
+ checkValidName(variableName);\r
+ return execute(() -> getPythonStringVariableImpl(contextID, variableName));\r
}\r
\r
+ public boolean[] getPythonBooleanArrayVariable(String variableName) {\r
+ checkValidName(variableName);\r
+ return execute(() -> getPythonBooleanArrayVariableImpl(contextID, variableName));\r
+ }\r
public int[] getPythonIntegerArrayVariable(String variableName) {\r
- return getPythonIntegerArrayVariableImpl(contextID, variableName);\r
+ checkValidName(variableName);\r
+ return execute(() -> getPythonIntegerArrayVariableImpl(contextID, variableName));\r
+ }\r
+ public long[] getPythonLongArrayVariable(String variableName) {\r
+ checkValidName(variableName);\r
+ return execute(() -> getPythonLongArrayVariableImpl(contextID, variableName));\r
}\r
public double[] getPythonDoubleArrayVariable(String variableName) {\r
- return getPythonDoubleArrayVariableImpl(contextID, variableName);\r
+ checkValidName(variableName);\r
+ return execute(() -> getPythonDoubleArrayVariableImpl(contextID, variableName));\r
}\r
public String[] getPythonStringArrayVariable(String variableName) {\r
- return getPythonStringArrayVariableImpl(contextID, variableName);\r
+ checkValidName(variableName);\r
+ return execute(() -> getPythonStringArrayVariableImpl(contextID, variableName));\r
}\r
\r
public void setPythonNDArrayVariable(String variableName, NDArray value) {\r
- setPythonNDArrayVariableImpl(contextID, variableName, value);\r
+ checkValidName(variableName);\r
+ execute(() -> setPythonNDArrayVariableImpl(contextID, variableName, value));\r
}\r
public NDArray getPythonNDArrayVariable(String variableName) {\r
- return getPythonNDArrayVariableImpl(contextID, variableName);\r
+ checkValidName(variableName);\r
+ return execute(() -> getPythonNDArrayVariableImpl(contextID, variableName));\r
}\r
\r
+ public Object getPythonVariantVariable(String variableName, Binding binding) {\r
+ checkValidName(variableName);\r
+ Object result = execute(() -> getPythonVariantVariableImpl(contextID, variableName));\r
+ try {\r
+ return Bindings.OBJECT.getContent(result, binding);\r
+ } catch (BindingException e) {\r
+ throw new RuntimeException(e);\r
+ }\r
+ }\r
+ \r
+ public Variant getPythonVariantVariable(String variableName) {\r
+ checkValidName(variableName);\r
+ return Variant.ofInstance(execute(() -> getPythonVariantVariableImpl(contextID, variableName)));\r
+ }\r
+\r
+ public void setPythonVariantVariable(String variableName, Variant value) {\r
+ setPythonVariantVariable(variableName, value.getValue(), value.getBinding());\r
+ }\r
+ \r
+ public void setPythonVariantVariable(String variableName, Object value, Binding binding) {\r
+ checkValidName(variableName);\r
+ if (!binding.isInstance(value)) throw new IllegalArgumentException("Invalid object binding");\r
+ \r
+ execute(() -> setPythonVariantVariableImpl(contextID, variableName, value, binding));\r
+ \r
+ for (Listener l : listeners) { l.updated(variableName); }\r
+ }\r
+ \r
+ public VariableType getPythonVariableType(String variableName) {\r
+ checkValidName(variableName);\r
+ int code = execute(() -> getPythonVariableTypeImpl(contextID, variableName));\r
+ \r
+ VariableType[] values = VariableType.values();\r
+ if (code < 0 || code >= values.length)\r
+ return VariableType.UNKNOWN;\r
+ \r
+ return values[code];\r
+ }\r
+ \r
+ public String[] getPythonVariableNames() {\r
+ return execute(() -> getPythonVariableNamesImpl(contextID));\r
+ }\r
+ \r
+ private static void checkValidName(String variableName) {\r
+ if (!namePattern.matcher(variableName).matches())\r
+ throw new IllegalArgumentException("Invalid Python variable name " + variableName);\r
+ }\r
+ \r
+ static void execute(Runnable job) {\r
+ try {\r
+ pythonExecutor.submit(job).get();\r
+ } catch (InterruptedException | ExecutionException e) {\r
+ throw new RuntimeException(e);\r
+ }\r
+ }\r
+ \r
+ static <V> V execute(Callable<V> job) {\r
+ try {\r
+ return pythonExecutor.submit(job).get();\r
+ } catch (InterruptedException | ExecutionException e) {\r
+ throw new RuntimeException(e);\r
+ }\r
+ }\r
+ \r
// Native function declarations\r
private static native long createContextImpl();\r
private static native void deleteContextImpl(long contextID);\r
\r
private static native int executePythonStatementImpl(long contextID, String statement);\r
\r
- private static native void setPythonIntegerVariableImpl(long contextID, String variableName, int value);\r
+ private static native void setPythonBooleanVariableImpl(long contextID, String variableName, boolean value);\r
+ private static native void setPythonLongVariableImpl(long contextID, String variableName, long value);\r
private static native void setPythonDoubleVariableImpl(long contextID, String variableName, double value);\r
private static native void setPythonStringVariableImpl(long contextID, String variableName, String value);\r
\r
+ private static native void setPythonBooleanArrayVariableImpl(long contextID, String variableName, boolean[] value);\r
private static native void setPythonIntegerArrayVariableImpl(long contextID, String variableName, int[] value);\r
+ private static native void setPythonLongArrayVariableImpl(long contextID, String variableName, long[] value);\r
private static native void setPythonDoubleArrayVariableImpl(long contextID, String variableName, double[] value);\r
private static native void setPythonStringArrayVariableImpl(long contextID, String variableName, String[] value);\r
\r
- private static native int getPythonIntegerVariableImpl(long contextID, String variableName);\r
+ private static native boolean getPythonBooleanVariableImpl(long contextID, String variableName);\r
+ private static native long getPythonLongVariableImpl(long contextID, String variableName);\r
private static native double getPythonDoubleVariableImpl(long contextID, String variableName);\r
private static native String getPythonStringVariableImpl(long contextID, String variableName);\r
\r
+ private static native boolean[] getPythonBooleanArrayVariableImpl(long contextID, String variableName);\r
+ private static native long[] getPythonLongArrayVariableImpl(long contextID, String variableName);\r
private static native int[] getPythonIntegerArrayVariableImpl(long contextID, String variableName);\r
private static native double[] getPythonDoubleArrayVariableImpl(long contextID, String variableName);\r
private static native String[] getPythonStringArrayVariableImpl(long contextID, String variableName);\r
\r
private static native void setPythonNDArrayVariableImpl(long contextID, String variableName, NDArray value);\r
private static native NDArray getPythonNDArrayVariableImpl(long contextID, String variableName);\r
+ \r
+ private static native void setPythonVariantVariableImpl(long contextID, String variableName, Object value, Binding binding);\r
+ private static native Object getPythonVariantVariableImpl(long contextID, String variableName);\r
+ \r
+ private static native int getPythonVariableTypeImpl(long contextID, String variableName);\r
+ \r
+ private static native String[] getPythonVariableNamesImpl(long contextID);\r
}\r
--- /dev/null
+package org.simantics.pythonlink.variable;\r
+\r
+public class PythonNode {\r
+ public PythonNode(String variableName) {\r
+ super();\r
+ this.variableName = variableName;\r
+ }\r
+ \r
+ private String variableName;\r
+ \r
+ public String getName() {\r
+ return variableName;\r
+ }\r
+}\r
--- /dev/null
+package org.simantics.pythonlink.variable;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Datatypes;\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.databoard.type.MapType;\r
+import org.simantics.databoard.type.RecordType;\r
+import org.simantics.pythonlink.NDArray;\r
+import org.simantics.pythonlink.PythonContext;\r
+import org.simantics.pythonlink.PythonContext.Listener;\r
+import org.simantics.pythonlink.PythonContext.VariableType;\r
+import org.simantics.simulator.variable.Realm;\r
+import org.simantics.simulator.variable.exceptions.NodeManagerException;\r
+import org.simantics.simulator.variable.impl.AbstractNodeManager;\r
+\r
+public class PythonNodeManager extends AbstractNodeManager<PythonNode> {\r
+ PythonContext context;\r
+ \r
+ static Realm realm = new Realm() {\r
+ public void asyncExec(Runnable runnable) {\r
+ runnable.run();\r
+ };\r
+ \r
+ public void syncExec(Runnable runnable) {\r
+ runnable.run();\r
+ };\r
+ };\r
+ \r
+ Map<String, Set<Runnable>> listeners = new HashMap<>();\r
+ Map<String, PythonNode> nodes = new HashMap<>();\r
+ \r
+ PythonNode root = new PythonNode("/");\r
+ \r
+ static Pattern namePattern = Pattern.compile("/?([a-zA-Z_][a-zA-Z_0-9]*)");\r
+ \r
+ static MapType dictionaryType = new MapType(Datatypes.VARIANT, Datatypes.VARIANT);\r
+ static RecordType ndarrayType = (RecordType)Bindings.getBindingUnchecked(NDArray.class).type();\r
+ \r
+ public PythonNodeManager(PythonContext context) {\r
+ super();\r
+ this.context = context;\r
+ \r
+ context.addListener(new Listener() {\r
+ @Override\r
+ public void updated(String variableName) {\r
+ if (variableName != null) {\r
+ Set<Runnable> lis = listeners.get(variableName);\r
+ if (lis != null) {\r
+ for (Runnable r : lis)\r
+ r.run();\r
+ }\r
+ lis = listeners.get("/");\r
+ if (lis != null) {\r
+ for (Runnable r : lis)\r
+ r.run();\r
+ }\r
+ }\r
+ else {\r
+ Set<Runnable> allRunnables = new HashSet<>();\r
+ for (Collection<Runnable> s : listeners.values())\r
+ allRunnables.addAll(s);\r
+ for (Runnable r : allRunnables)\r
+ r.run();\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public void closed() {\r
+ nodes.clear();\r
+ Set<Runnable> allRunnables = new HashSet<>();\r
+ for (Collection<Runnable> s : listeners.values())\r
+ allRunnables.addAll(s);\r
+ for (Runnable r : allRunnables)\r
+ r.run();\r
+ }\r
+ });\r
+ }\r
+ \r
+ @Override\r
+ public Realm getRealm() {\r
+ return realm;\r
+ }\r
+\r
+ @Override\r
+ public String getName(PythonNode node) {\r
+ return node.getName();\r
+ }\r
+\r
+ @Override\r
+ public void addNodeListener(PythonNode node, Runnable listener) {\r
+ synchronized(listeners) {\r
+ if (!listeners.containsKey(node.getName())) listeners.put(node.getName(), new HashSet<>());\r
+ listeners.get(node.getName()).add(listener);\r
+ } \r
+ }\r
+\r
+ @Override\r
+ public void removeNodeListener(PythonNode node, Runnable listener) {\r
+ synchronized(listeners) {\r
+ if (!listeners.containsKey(node.getName()))\r
+ listeners.get(node.getName()).remove(listener);\r
+ } \r
+ }\r
+\r
+ @Override\r
+ public PythonNode getNode(String path) throws NodeManagerException {\r
+ if (!context.isOpen())\r
+ return null;\r
+ \r
+ if ("/".equals(path))\r
+ return root; \r
+ \r
+ Matcher match = namePattern.matcher(path);\r
+ if (!match.matches())\r
+ return null;\r
+ \r
+ String name = match.group(1);\r
+ \r
+ if (nodes.containsKey(name))\r
+ return nodes.get(name);\r
+ \r
+ VariableType type = context.getPythonVariableType(name);\r
+ if (type == VariableType.NO_VARIABLE)\r
+ return null;\r
+ \r
+ PythonNode node = new PythonNode(name);\r
+ nodes.put(path, node);\r
+ \r
+ return node;\r
+ }\r
+\r
+ @Override\r
+ public PythonNode getChild(PythonNode node, String name) throws NodeManagerException {\r
+ return null;\r
+ }\r
+\r
+ @Override\r
+ public PythonNode getProperty(PythonNode node, String name) throws NodeManagerException {\r
+ if (node != root || !context.isOpen()) return null;\r
+ \r
+ return getNode(name);\r
+ }\r
+ \r
+ @Override\r
+ public List<String> getChildNames(PythonNode node) throws NodeManagerException {\r
+ return Collections.emptyList();\r
+ }\r
+\r
+ @Override\r
+ public List<PythonNode> getChildren(PythonNode node) throws NodeManagerException {\r
+ return Collections.emptyList();\r
+ }\r
+ \r
+ @Override\r
+ public List<String> getPropertyNames(PythonNode node) throws NodeManagerException {\r
+ if (node != root || !context.isOpen()) return Collections.emptyList(); \r
+ return Arrays.asList(context.getPythonVariableNames());\r
+ }\r
+\r
+ @Override\r
+ public List<PythonNode> getProperties(PythonNode node) throws NodeManagerException {\r
+ if (node != root || !context.isOpen()) return Collections.emptyList();\r
+ \r
+ String[] names = context.getPythonVariableNames();\r
+ List<PythonNode> result = new ArrayList<>(names.length);\r
+ \r
+ for (String name : names) {\r
+ result.add(getNode(name));\r
+ }\r
+ \r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public Datatype getDatatype(PythonNode node) throws NodeManagerException {\r
+ String name = node.getName();\r
+ VariableType type;\r
+ try {\r
+ type = context.getPythonVariableType(name);\r
+ } catch (RuntimeException e) {\r
+ throw new NodeManagerException("Failed to get type of variable " + name, e); \r
+ }\r
+ \r
+ switch (type) {\r
+ case NO_VARIABLE: return Datatypes.VOID;\r
+ case BOOLEAN: return Datatypes.BOOLEAN;\r
+ case LONG: return Datatypes.LONG;\r
+ case FLOAT: return Datatypes.DOUBLE;\r
+ case STRING: return Datatypes.STRING;\r
+ case BYTEARRAY: return Datatypes.BYTE_ARRAY;\r
+ case DICTIONARY: return dictionaryType;\r
+ case NDARRAY: return ndarrayType;\r
+ case SEQUENCE: return Datatypes.VARIANT_ARRAY;\r
+ case UNKNOWN: return Datatypes.VOID;\r
+ default: throw new RuntimeException("Unknown python variable type");\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public Variant getValue(PythonNode node, String propertyName) throws NodeManagerException {\r
+ if (node == root && context.isOpen())\r
+ return context.getPythonVariantVariable(propertyName);\r
+ \r
+ throw new NodeManagerException("No value available for " + node.getName() + "#" + propertyName);\r
+ }\r
+\r
+ @Override\r
+ public Object getValue(PythonNode node, String propertyName, Binding binding)\r
+ throws NodeManagerException, BindingException {\r
+ Variant value = getValue(node, propertyName);\r
+ \r
+ try {\r
+ return value.getValue(binding);\r
+ } catch (AdaptException e) {\r
+ throw new BindingException(e);\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public Variant getValue(PythonNode node) throws NodeManagerException {\r
+ if (node == root || !context.isOpen())\r
+ throw new NodeManagerException("No value available for " + node.getName());\r
+ \r
+ String name = node.getName();\r
+ \r
+ try {\r
+ return context.getPythonVariantVariable(name);\r
+ } catch (RuntimeException e) {\r
+ throw new NodeManagerException("Failed to get value of variable " + name, e);\r
+ }\r
+ }\r
+ \r
+ @Override\r
+ public Object getValue(PythonNode node, Binding binding) throws NodeManagerException, BindingException {\r
+ Variant value = getValue(node);\r
+ \r
+ try {\r
+ return value.getValue(binding);\r
+ } catch (AdaptException e) {\r
+ throw new BindingException(e);\r
+ }\r
+ }\r
+\r
+ @Override\r
+ public void setValue(PythonNode node, String propertyName, Object value, Binding binding)\r
+ throws NodeManagerException, BindingException {\r
+ if (node != root || !context.isOpen()) throw new NodeManagerException("No property " + node.getName() + "#" + propertyName);\r
+ \r
+ context.setPythonVariantVariable(propertyName, value, binding); \r
+ }\r
+ \r
+ @Override\r
+ public void setValue(PythonNode node, Object value, Binding binding) throws NodeManagerException, BindingException { \r
+ if (node == root || !context.isOpen()) throw new NodeManagerException("No property " + node.getName());\r
+ String name = node.getName();\r
+ \r
+ context.setPythonVariantVariable(name, value, binding);\r
+ }\r
+ \r
+ @Override\r
+ public Set<String> getClassifications(PythonNode node) throws NodeManagerException {\r
+ return Collections.emptySet();\r
+ }\r
+ \r
+}\r
import org.junit.runners.Suite.SuiteClasses;\r
\r
@RunWith( Suite.class )\r
-@SuiteClasses( { ScriptTests.class, TestPythonlink.class } )\r
+@SuiteClasses( { ScriptTests.class, TestPythonlink.class, TestPythonVariable.class } )\r
public class AllTests {\r
\r
}\r
package org.simantics.pythonlink.test;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
import org.junit.Test;
+import org.simantics.PlatformException;
+import org.simantics.Simantics;
+import org.simantics.application.arguments.Arguments;
+import org.simantics.pythonlink.PythonContext;
public class ScriptTests extends ScriptTestBase {
+ static IProgressMonitor progress = new NullProgressMonitor();
+ PythonContext python;
+
+ @BeforeClass
+ public static void SetUpClass() throws PlatformException {
+ Simantics.startUpHeadless(Arguments.parse(new String[] {}), progress);
+ }
+
+ @AfterClass
+ public static void TearDownClass() throws PlatformException {
+ Simantics.shutdown(progress);
+ }
+
public ScriptTests() {
super("scripts");
}
@Test public void Python() throws Exception { test(); }
+ @Test public void Matplotlib() throws Exception { test(); }
+ @Test public void NDArray() throws Exception { test(); }
+ @Test public void Variant() throws Exception { test(); }
+ @Test public void Variable() throws Exception { test(); }
}
--- /dev/null
+package org.simantics.pythonlink.test;\r
+\r
+import static org.junit.Assert.assertArrayEquals;\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNotNull;\r
+import static org.junit.Assert.assertTrue;\r
+\r
+import java.util.Map;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.NullProgressMonitor;\r
+import org.junit.After;\r
+import org.junit.AfterClass;\r
+import org.junit.Before;\r
+import org.junit.BeforeClass;\r
+import org.junit.Test;\r
+import org.simantics.PlatformException;\r
+import org.simantics.Simantics;\r
+import org.simantics.application.arguments.Arguments;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Datatypes;\r
+import org.simantics.databoard.type.MapType;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.pythonlink.Python;\r
+import org.simantics.pythonlink.PythonContext;\r
+\r
+public class TestPythonVariable {\r
+ static IProgressMonitor progress = new NullProgressMonitor();\r
+ \r
+ PythonContext python;\r
+\r
+ @BeforeClass\r
+ public static void SetUpClass() throws PlatformException {\r
+ Simantics.startUpHeadless(Arguments.parse(new String[] {}), progress); \r
+ }\r
+ \r
+ @AfterClass\r
+ public static void TearDownClass() throws PlatformException {\r
+ Simantics.shutdown(progress); \r
+ }\r
+ \r
+ @Before\r
+ public void setUp() throws Exception {\r
+ python = Python.openPythonContext();\r
+ }\r
+\r
+ @After\r
+ public void tearDown() throws Exception {\r
+ python.close();\r
+ }\r
+ \r
+ @Test\r
+ public void test() throws DatabaseException {\r
+ Simantics.getSession().syncRequest(new Read<Void>() {\r
+ @Override\r
+ public Void perform(ReadGraph graph) throws DatabaseException {\r
+ python.setPythonDoubleArrayVariable("foo", new double[] { 1, 2, 3 });\r
+ \r
+ Variable var = Python.getPythonContextVariable(python);\r
+ \r
+ Object value = var.getPossiblePropertyValue(graph, "foo");\r
+ \r
+ assertNotNull(value);\r
+ assertTrue(value instanceof Object[]);\r
+ assertArrayEquals(new Object[] {1.0, 2.0, 3.0}, (Object[])value);\r
+ \r
+ return null;\r
+ }\r
+ });\r
+ }\r
+ \r
+ @Test\r
+ public void test2() throws DatabaseException {\r
+ Simantics.getSession().syncRequest(new Read<Void>() {\r
+ @Override\r
+ public Void perform(ReadGraph graph) throws DatabaseException {\r
+ python.setPythonDoubleArrayVariable("foo", new double[] { 1, 2, 3 });\r
+ \r
+ Variable var = Python.getPythonContextVariable(python);\r
+ \r
+ Object value = var.getPossiblePropertyValue(graph, "foo", Bindings.DOUBLE_ARRAY);\r
+ \r
+ assertNotNull(value);\r
+ assertTrue(value instanceof double[]);\r
+ assertArrayEquals(new double[] {1.0, 2.0, 3.0}, (double[])value, 0.0);\r
+ \r
+ return null;\r
+ }\r
+ });\r
+ }\r
+ \r
+ @Test\r
+ public void test3() throws DatabaseException {\r
+ Simantics.getSession().syncRequest(new Read<Void>() {\r
+ @Override\r
+ public Void perform(ReadGraph graph) throws DatabaseException {\r
+ python.executePythonStatement("foo = (1, 2, 3)");\r
+ \r
+ Variable var = Python.getPythonContextVariable(python);\r
+ Variable foo = var.browse(graph, "#foo");\r
+ \r
+ Object value = foo.getPossibleValue(graph, Bindings.LONG_ARRAY);\r
+ \r
+ assertNotNull(value);\r
+ assertTrue(value instanceof long[]);\r
+ assertArrayEquals(new long[] {1,2,3}, (long[])value);\r
+ \r
+ return null;\r
+ }\r
+ });\r
+ }\r
+ \r
+ @Test\r
+ public void test4() throws DatabaseException {\r
+ Simantics.getSession().syncRequest(new Read<Void>() {\r
+ @Override\r
+ public Void perform(ReadGraph graph) throws DatabaseException {\r
+ python.executePythonStatement("foo = {1:'foo', 2:'bar'}");\r
+ \r
+ Variable var = Python.getPythonContextVariable(python);\r
+ Variable foo = var.getPossibleProperty(graph, "foo");\r
+ \r
+ Object value = foo.getPossibleValue(graph, Bindings.getBinding(new MapType(Datatypes.LONG, Datatypes.STRING)));\r
+ \r
+ assertNotNull(value);\r
+ assertTrue(value instanceof Map<?,?>);\r
+ assertEquals(2, ((Map<?,?>)value).size());\r
+ assertEquals("foo", ((Map<?,?>)value).get(1L));\r
+ assertEquals("bar", ((Map<?,?>)value).get(2L));\r
+ \r
+ return null;\r
+ }\r
+ });\r
+ }\r
+ \r
+}\r
--- /dev/null
+> import "Python"\r
+> \r
+> code = """\r
+> import matplotlib\r
+> import matplotlib.pyplot as plt\r
+> import numpy as np\r
+> import io\r
+> \r
+> x, y = np.random.randn(2, 100)\r
+> fig = plt.figure()\r
+> ax1 = fig.add_subplot(211)\r
+> ax1.xcorr(x, y, usevlines=True, maxlags=50, normed=True, lw=2)\r
+> ax1.grid(True)\r
+> ax1.axhline(0, color='black', lw=2)\r
+> \r
+> ax2 = fig.add_subplot(212, sharex=ax1)\r
+> ax2.acorr(x, usevlines=True, normed=True, maxlags=50, lw=2)\r
+> ax2.grid(True)\r
+> ax2.axhline(0, color='black', lw=2)\r
+> \r
+> imgdata = io.StringIO()\r
+> fig.savefig(imgdata, format='svg')\r
+> svg_data = imgdata.getvalue()[0:5]\r
+> """\r
+> runPython do\r
+> executePythonStatement code\r
+> getPythonStringVariable "svg_data"\r
+"<?xml"\r
--- /dev/null
+> import "Python"\r
+> ndarray (vector [1, 2, 3])\r
+ndarray(3) [1.0, 2.0, 3.0]\r
+> ndarrayM 2 2 (vector [1, 2, 3, 4])\r
+ndarray(2x2) [[1.0, 2.0], [3.0, 4.0]]\r
+> a = ndarrayN (vector [2, 2, 3]) (vector [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])\r
+> a\r
+ndarray(2x2x3) [[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], [[7.0, 8.0, 9.0], [10.0, 11.0, 12.0]]]\r
+> ndarrayDims a\r
+vector [2, 2, 3]\r
+> ndarrayValues a\r
+vector [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]\r
+> ndarrayElement a 5\r
+6.0\r
+> ndarrayElementN a (vector [0, 1, 2])\r
+6.0\r
+> b = ndarrayFromList ([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]] :: [[[Double]]])\r
+> b\r
+ndarray(2x2x3) [[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], [[7.0, 8.0, 9.0], [10.0, 11.0, 12.0]]]\r
+> runPython do\r
+> setPythonNDArrayVariable "foo" (ndarrayM 2 3 (vector [1, 2, 3, 4, 5, 6]))\r
+> executePythonStatement "bar = foo.cumsum(1)"\r
+> getPythonNDArrayVariable "bar"\r
+ndarray(2x3) [[1.0, 3.0, 6.0], [4.0, 9.0, 15.0]]\r
> getPythonStringArrayVariable "d"\r
vector ["__builtins__", "__doc__", "__loader__", "__name__", "__package__", "__spec__", "foo"]\r
> runPython do\r
+> getPythonStringVariable "__name__"\r
+"SCL_2"\r
+> runPython do\r
> setPythonDoubleVariable "foo" 1\r
> executePythonStatement "foo = foo + 1"\r
> getPythonDoubleVariable "foo"\r
> executePythonStatement "foo.append(sum(foo))"\r
> getPythonIntegerArrayVariable "foo"\r
vector [1, 2, 3, 4, 10]\r
-> ndarray (vector [1, 2, 3])\r
-ndarray(3) [1.0, 2.0, 3.0]\r
-> ndarrayM 2 2 (vector [1, 2, 3, 4])\r
-ndarray(2x2) [[1.0, 2.0], [3.0, 4.0]]\r
-> a = ndarrayN (vector [2, 2, 3]) (vector [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])\r
-> a\r
-ndarray(2x2x3) [[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]], [[7.0, 8.0, 9.0], [10.0, 11.0, 12.0]]]\r
-> ndarrayDims a\r
-vector [2, 2, 3]\r
-> ndarrayValues a\r
-vector [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0]\r
-> ndarrayElement a 5\r
-6.0\r
-> ndarrayElementN a (vector [0, 1, 2])\r
-6.0\r
-> runPython do\r
-> setPythonNDArrayVariable "foo" (ndarrayM 2 3 (vector [1, 2, 3, 4, 5, 6]))\r
-> executePythonStatement "bar = foo.cumsum(1)"\r
-> getPythonNDArrayVariable "bar"\r
-ndarray(2x3) [[1.0, 3.0, 6.0], [4.0, 9.0, 15.0]]\r
+> runPython do\r
+> setPythonBooleanVariable "foo" False\r
+> executePythonStatement "foo = not(foo)"\r
+> getPythonBooleanVariable "foo"\r
+True\r
> runPython do\r
> setPythonVariable "foo" ([1.0, 2.0, 3.0, 4.0] :: [Double])\r
> executePythonStatement "foo.append(sum(foo))"\r
> getPythonVariable "foo" :: [Double]\r
[1.0, 2.0, 3.0, 4.0, 10.0]\r
+> py = openPythonContext\r
+> runWithPythonContext py $ setPythonIntegerVariable "foo" 4\r
+> runWithPythonContext py $ setPythonDoubleArrayVariable "bar" (vector [1.0, 2.0, 3.0])\r
+> runWithPythonContext py $ executePythonStatement "bar.append(float(foo))"\r
+> bar = runWithPythonContext py $ getPythonDoubleArrayVariable "bar"\r
+> closePythonContext py\r
+> bar\r
+vector [1.0, 2.0, 3.0, 4.0]\r
--- /dev/null
+> import "PythonVariable"\r
+> import "Simantics/DB"\r
+> import "String"\r
+> \r
+> py = openPythonContext\r
+> runWithPythonContext py do\r
+> setPythonIntegerVariable "foo" 4\r
+> setPythonDoubleArrayVariable "bar" (vector [1.0, 2.0, 3.0])\r
+> \r
+> var = getPythonContextVariable py\r
+> sort $ map nameOf $ properties var\r
+["__builtins__", "__doc__", "__loader__", "__name__", "__package__", "__spec__", "bar", "foo"]\r
+> foo = property var "foo"\r
+> bar = property var "bar" \r
+> datatype foo\r
+Long\r
+> datatype bar\r
+Variant[]\r
+> value bar :: Variant\r
+[1.0 : Double, 2.0 : Double, 3.0 : Double] : Variant[]\r
+> value bar :: [Double]\r
+[1.0, 2.0, 3.0]\r
+> possibleChild var "foo"\r
+Nothing\r
+> possibleProperty var "dummy"\r
+Nothing \r
+> runWithPythonContext py do\r
+> executePythonStatement "baz = (1.0, 'string_value', [2.0, 3.0])"\r
+> sort $ map nameOf $ properties var\r
+["__builtins__", "__doc__", "__loader__", "__name__", "__package__", "__spec__", "bar", "baz", "foo"]\r
+> v = propertyValue var "baz" :: Variant\r
+> v\r
+[1.0 : Double, "string_value" : String, [2.0 : Double, 3.0 : Double] : Variant[]] : Variant[]\r
+> variantElement v 1 :: String\r
+"string_value"\r
--- /dev/null
+> import "Python"\r
+> a = variant ([1.0, 2.0, 3.0])\r
+> b = runPython do\r
+> setPythonVariantVariable "foo" a\r
+> executePythonStatement "foo.append(4.0)"\r
+> getPythonVariantVariable "foo"\r
+> b\r
+[1.0 : Double, 2.0 : Double, 3.0 : Double, 4.0 : Double] : Variant[]\r
+> variantValue b :: [Double]\r
+[1.0, 2.0, 3.0, 4.0]\r
+> import "MMap" as MMap\r
+> runPython do\r
+> foo = MMap.create () :: MMap.T String Dynamic\r
+> MMap.put foo "c1" (toDynamic (vector [True, True, False, True]))\r
+> MMap.put foo "c2" (toDynamic ["foo", "bar", "baz"])\r
+> MMap.put foo "c3" (toDynamic 25.0)\r
+> setPythonVariantVariable "foo" (variant foo)\r
+> executePythonStatement "c1 = foo['c1']"\r
+> executePythonStatement "c2 = foo['c2']"\r
+> executePythonStatement "c3 = foo['c3']"\r
+> (getPythonBooleanArrayVariable "c1", getPythonStringArrayVariable "c2", getPythonDoubleVariable "c3")\r
+(vector [True, True, False, True], vector ["foo", "bar", "baz"], 25.0)\r