-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
- close();\r
- }\r
- \r
- public void executePythonStatement(String 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- checkValidName(variableName);\r
- return execute(() -> getPythonDoubleVariableImpl(contextID, variableName));\r
- }\r
- public String getPythonStringVariable(String 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
- 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
- checkValidName(variableName);\r
- return execute(() -> getPythonDoubleArrayVariableImpl(contextID, variableName));\r
- }\r
- public String[] getPythonStringArrayVariable(String variableName) {\r
- checkValidName(variableName);\r
- return execute(() -> getPythonStringArrayVariableImpl(contextID, variableName));\r
- }\r
- \r
- public void setPythonNDArrayVariable(String variableName, NDArray value) {\r
- checkValidName(variableName);\r
- execute(() -> setPythonNDArrayVariableImpl(contextID, variableName, value));\r
- }\r
- public NDArray getPythonNDArrayVariable(String 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 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 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
+package org.simantics.pythonlink;
+
+import java.io.Closeable;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.regex.Pattern;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.databoard.binding.mutable.Variant;
+
+public class PythonContext implements Closeable {
+ private long contextID;
+
+ public interface Listener {
+ void updated(String variableName);
+ void closed();
+ }
+
+ static ExecutorService pythonExecutor = Executors.newSingleThreadExecutor();
+
+ Set<Listener> listeners = new HashSet<>();
+
+ public enum VariableType {
+ NO_VARIABLE,
+ BOOLEAN,
+ LONG,
+ FLOAT,
+ STRING,
+ BYTEARRAY,
+ DICTIONARY,
+ NDARRAY,
+ SEQUENCE,
+ UNKNOWN
+ }
+
+ static Pattern namePattern = Pattern.compile("([a-zA-Z_][a-zA-Z_0-9]*)");
+
+ PythonContext() {
+ contextID = execute(() -> createContextImpl());
+ }
+
+ public void addListener(Listener listener) {
+ listeners.add(listener);
+ }
+
+ public void removeListener(Listener listener) {
+ listeners.remove(listener);
+ }
+
+ @Override
+ public void close() {
+ long id = contextID;
+ contextID = 0;
+ if (id != 0) execute(() -> deleteContextImpl(id));
+
+ for (Listener l : listeners) {
+ l.closed();
+ }
+ }
+
+ public boolean isOpen() {
+ return contextID != 0;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ close();
+ }
+
+ public void executePythonStatement(String statement) {
+ execute(() -> executePythonStatementImpl( contextID, statement ));
+ for (Listener l : listeners) { l.updated(null); }
+ }
+
+ // Setters
+
+ public void setPythonBooleanVariable(String variableName, boolean value) {
+ checkValidName(variableName);
+ execute(() -> setPythonBooleanVariableImpl(contextID, variableName, value));
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+
+ public void setPythonIntegerVariable(String variableName, int value) {
+ checkValidName(variableName);
+ execute(() -> setPythonLongVariableImpl(contextID, variableName, value));
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+ public void setPythonLongVariable(String variableName, long value) {
+ checkValidName(variableName);
+ execute(() -> setPythonLongVariableImpl(contextID, variableName, value));
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+ public void setPythonDoubleVariable(String variableName, double value) {
+ checkValidName(variableName);
+ execute(() -> setPythonDoubleVariableImpl(contextID, variableName, value));
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+ public void setPythonStringVariable(String variableName, String value) {
+ checkValidName(variableName);
+ execute(() -> setPythonStringVariableImpl(contextID, variableName, value));
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+
+ public void setPythonBooleanArrayVariable(String variableName, boolean[] value) {
+ checkValidName(variableName);
+ execute(() -> setPythonBooleanArrayVariableImpl(contextID, variableName, value));
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+ public void setPythonIntegerArrayVariable(String variableName, int[] value) {
+ checkValidName(variableName);
+ execute(() -> setPythonIntegerArrayVariableImpl(contextID, variableName, value));
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+ public void setPythonLongArrayVariable(String variableName, long[] value) {
+ checkValidName(variableName);
+ execute(() -> setPythonLongArrayVariableImpl(contextID, variableName, value));
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+ public void setPythonDoubleArrayVariable(String variableName, double[] value) {
+ checkValidName(variableName);
+ execute(() -> setPythonDoubleArrayVariableImpl(contextID, variableName, value));
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+ public void setPythonStringArrayVariable(String variableName, String[] value) {
+ checkValidName(variableName);
+ execute(() -> setPythonStringArrayVariableImpl(contextID, variableName, value));
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+
+ // Getters
+
+ public boolean getPythonBooleanVariable(String variableName) {
+ checkValidName(variableName);
+ return getPythonBooleanVariableImpl(contextID, variableName);
+ }
+ public int getPythonIntegerVariable(String variableName) {
+ checkValidName(variableName);
+ long value = execute(() -> getPythonLongVariableImpl(contextID, variableName));
+ if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE)
+ throw new RuntimeException("Python value not in integer range");
+ return (int) value;
+ }
+ public long getPythonLongVariable(String variableName) {
+ checkValidName(variableName);
+ return execute(() -> getPythonLongVariableImpl(contextID, variableName));
+ }
+ public double getPythonDoubleVariable(String variableName) {
+ checkValidName(variableName);
+ return execute(() -> getPythonDoubleVariableImpl(contextID, variableName));
+ }
+ public String getPythonStringVariable(String variableName) {
+ checkValidName(variableName);
+ return execute(() -> getPythonStringVariableImpl(contextID, variableName));
+ }
+
+ public boolean[] getPythonBooleanArrayVariable(String variableName) {
+ checkValidName(variableName);
+ return execute(() -> getPythonBooleanArrayVariableImpl(contextID, variableName));
+ }
+ public int[] getPythonIntegerArrayVariable(String variableName) {
+ checkValidName(variableName);
+ return execute(() -> getPythonIntegerArrayVariableImpl(contextID, variableName));
+ }
+ public long[] getPythonLongArrayVariable(String variableName) {
+ checkValidName(variableName);
+ return execute(() -> getPythonLongArrayVariableImpl(contextID, variableName));
+ }
+ public double[] getPythonDoubleArrayVariable(String variableName) {
+ checkValidName(variableName);
+ return execute(() -> getPythonDoubleArrayVariableImpl(contextID, variableName));
+ }
+ public String[] getPythonStringArrayVariable(String variableName) {
+ checkValidName(variableName);
+ return execute(() -> getPythonStringArrayVariableImpl(contextID, variableName));
+ }
+
+ public void setPythonNDArrayVariable(String variableName, NDArray value) {
+ checkValidName(variableName);
+ execute(() -> setPythonNDArrayVariableImpl(contextID, variableName, value));
+ }
+ public NDArray getPythonNDArrayVariable(String variableName) {
+ checkValidName(variableName);
+ return execute(() -> getPythonNDArrayVariableImpl(contextID, variableName));
+ }
+
+ public Object getPythonVariantVariable(String variableName, Binding binding) {
+ checkValidName(variableName);
+ Object result = execute(() -> getPythonVariantVariableImpl(contextID, variableName));
+ try {
+ return Bindings.OBJECT.getContent(result, binding);
+ } catch (BindingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Variant getPythonVariantVariable(String variableName) {
+ checkValidName(variableName);
+ return Variant.ofInstance(execute(() -> getPythonVariantVariableImpl(contextID, variableName)));
+ }
+
+ public void setPythonVariantVariable(String variableName, Variant value) {
+ setPythonVariantVariable(variableName, value.getValue(), value.getBinding());
+ }
+
+ public void setPythonVariantVariable(String variableName, Object value, Binding binding) {
+ checkValidName(variableName);
+ if (!binding.isInstance(value)) throw new IllegalArgumentException("Invalid object binding");
+
+ execute(() -> setPythonVariantVariableImpl(contextID, variableName, value, binding));
+
+ for (Listener l : listeners) { l.updated(variableName); }
+ }
+
+ public VariableType getPythonVariableType(String variableName) {
+ checkValidName(variableName);
+ int code = execute(() -> getPythonVariableTypeImpl(contextID, variableName));
+
+ VariableType[] values = VariableType.values();
+ if (code < 0 || code >= values.length)
+ return VariableType.UNKNOWN;
+
+ return values[code];
+ }
+
+ public String[] getPythonVariableNames() {
+ return execute(() -> getPythonVariableNamesImpl(contextID));
+ }
+
+ private static void checkValidName(String variableName) {
+ if (!namePattern.matcher(variableName).matches())
+ throw new IllegalArgumentException("Invalid Python variable name " + variableName);
+ }
+
+ static void execute(Runnable job) {
+ try {
+ pythonExecutor.submit(job).get();
+ } catch (InterruptedException | ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static <V> V execute(Callable<V> job) {
+ try {
+ return pythonExecutor.submit(job).get();
+ } catch (InterruptedException | ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // Native function declarations
+ private static native long createContextImpl();
+ private static native void deleteContextImpl(long contextID);
+
+ private static native int executePythonStatementImpl(long contextID, String statement);
+
+ private static native void setPythonBooleanVariableImpl(long contextID, String variableName, boolean value);
+ private static native void setPythonLongVariableImpl(long contextID, String variableName, long value);
+ private static native void setPythonDoubleVariableImpl(long contextID, String variableName, double value);
+ private static native void setPythonStringVariableImpl(long contextID, String variableName, String value);
+
+ private static native void setPythonBooleanArrayVariableImpl(long contextID, String variableName, boolean[] value);
+ private static native void setPythonIntegerArrayVariableImpl(long contextID, String variableName, int[] value);
+ private static native void setPythonLongArrayVariableImpl(long contextID, String variableName, long[] value);
+ private static native void setPythonDoubleArrayVariableImpl(long contextID, String variableName, double[] value);
+ private static native void setPythonStringArrayVariableImpl(long contextID, String variableName, String[] value);
+
+ private static native boolean getPythonBooleanVariableImpl(long contextID, String variableName);
+ private static native long getPythonLongVariableImpl(long contextID, String variableName);
+ private static native double getPythonDoubleVariableImpl(long contextID, String variableName);
+ private static native String getPythonStringVariableImpl(long contextID, String variableName);
+
+ private static native boolean[] getPythonBooleanArrayVariableImpl(long contextID, String variableName);
+ private static native long[] getPythonLongArrayVariableImpl(long contextID, String variableName);
+ private static native int[] getPythonIntegerArrayVariableImpl(long contextID, String variableName);
+ private static native double[] getPythonDoubleArrayVariableImpl(long contextID, String variableName);
+ private static native String[] getPythonStringArrayVariableImpl(long contextID, String variableName);
+
+ private static native void setPythonNDArrayVariableImpl(long contextID, String variableName, NDArray value);
+ private static native NDArray getPythonNDArrayVariableImpl(long contextID, String variableName);
+
+ private static native void setPythonVariantVariableImpl(long contextID, String variableName, Object value, Binding binding);
+ private static native Object getPythonVariantVariableImpl(long contextID, String variableName);
+
+ private static native int getPythonVariableTypeImpl(long contextID, String variableName);
+
+ private static native String[] getPythonVariableNamesImpl(long contextID);
+}