]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.simulator.toolkit/src/org/simantics/simulator/toolkit/DynamicExperimentThreadSequenceRunner.java
Simulator toolkit enhancements
[simantics/platform.git] / bundles / org.simantics.simulator.toolkit / src / org / simantics / simulator / toolkit / DynamicExperimentThreadSequenceRunner.java
diff --git a/bundles/org.simantics.simulator.toolkit/src/org/simantics/simulator/toolkit/DynamicExperimentThreadSequenceRunner.java b/bundles/org.simantics.simulator.toolkit/src/org/simantics/simulator/toolkit/DynamicExperimentThreadSequenceRunner.java
new file mode 100644 (file)
index 0000000..2143e5a
--- /dev/null
@@ -0,0 +1,72 @@
+package org.simantics.simulator.toolkit;
+
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.simantics.scl.runtime.SCLContext;
+import org.simantics.scl.runtime.function.Function;
+import org.simantics.simulator.IDynamicExperimentLocal;
+
+/**
+ * @author Antti Villberg
+ * @since 1.34.0
+ */
+public class DynamicExperimentThreadSequenceRunner {
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public static DynamicExperimentActionContext runAction(IDynamicExperimentLocal experiment, DynamicExperimentThread thread, Function action, final boolean simulateAndWaitCompletion) {
+        final DynamicExperimentActionContext context = new DynamicExperimentActionContext(experiment);
+        context.scheduleNextStep(action);
+        final Object sync = new Object();
+        final SCLContext sclContext = SCLContext.getCurrent();
+
+        thread.addListener(new DynamicExperimentThreadListener() {
+
+            @Override
+            public void beforeStep() {
+                if(!context.isStopped()) {
+                    SCLContext.push(sclContext);
+                    context.handleStep(experiment.getSimulationTime());
+                    SCLContext.pop();
+                }
+                removeIfStopped();
+            }
+
+            public void removeIfStopped() {
+                if(context.isStopped()) {
+                    thread.removeListener(this);
+                    if(simulateAndWaitCompletion) {
+                        experiment.simulate(false);
+                        synchronized(sync) {
+                            sync.notify();
+                        }
+                    }
+                    experiment.shutdown(new NullProgressMonitor());
+                }
+            }
+
+        });
+
+        if(simulateAndWaitCompletion) {
+            experiment.simulate(true);
+
+            try {
+                synchronized(sync) {
+                    while(!context.isStopped())
+                        sync.wait(1000L);
+                }
+            } catch(InterruptedException e) {
+                context.stop();
+            }
+
+            if (context.exceptions != null && !context.exceptions.isEmpty()) {
+                StringBuilder builder = new StringBuilder();
+                builder.append("Action failures:");
+                for (Exception e : context.exceptions) {
+                    builder.append("\n");
+                    builder.append(e.getMessage());
+                }
+
+                throw new RuntimeException(builder.toString());
+            }
+        }
+        return context;
+    }
+}