--- /dev/null
+package org.simantics.simulation.experiment;\r
+\r
+import java.util.Collection;\r
+import java.util.UUID;\r
+import java.util.function.Consumer;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.ui.progress.IProgressConstants2;\r
+import org.simantics.DatabaseJob;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.procedure.adapter.ProcedureAdapter;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.common.request.WriteResultRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.request.PossibleActiveExperiment;\r
+import org.simantics.db.layer0.request.PossibleActiveRun;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.procedure.Procedure;\r
+import org.simantics.db.service.VirtualGraphSupport;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public final class ExperimentUtil {\r
+\r
+ public static void stepExperiment(IExperiment experiment, double duration) {\r
+ if(experiment instanceof IDynamicExperiment)\r
+ ((IDynamicExperiment)experiment).simulateDuration(duration);\r
+ }\r
+\r
+ public static void simulateExperiment(IExperiment experiment, boolean enabled) {\r
+ if(experiment instanceof IDynamicExperiment)\r
+ ((IDynamicExperiment)experiment).simulate(enabled);\r
+ }\r
+\r
+ public static void disposeExperiment(final IExperiment experiment) {\r
+ \r
+ if(experiment instanceof IDynamicExperiment) {\r
+ \r
+ ((IDynamicExperiment)experiment).shutdown(null);\r
+ \r
+ Session session = Simantics.getSession();\r
+ VirtualGraphSupport vgs = session.getService(VirtualGraphSupport.class);\r
+ session.asyncRequest(new WriteRequest(vgs.getMemoryPersistent("experiments")) {\r
+\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+\r
+ SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+ Resource activeRun = experiment.getResource();\r
+ graph.deny(activeRun, SIMU.IsActive, activeRun);\r
+\r
+ }\r
+\r
+ });\r
+\r
+ }\r
+ \r
+ }\r
+\r
+ public static void step(double duration) {\r
+ IExperimentManager manager = \r
+ Simantics.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ IExperiment experiment = manager.getActiveExperiment();\r
+ if(experiment instanceof IDynamicExperiment)\r
+ ((IDynamicExperiment)experiment).simulateDuration(duration);\r
+ }\r
+\r
+ public static void simulate(boolean enabled) {\r
+ IExperimentManager manager =\r
+ Simantics.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ IExperiment experiment = manager.getActiveExperiment();\r
+ if(experiment instanceof IDynamicExperiment)\r
+ ((IDynamicExperiment)experiment).simulate(enabled);\r
+ }\r
+\r
+ /**\r
+ * Synchronously shutdown active experiment.\r
+ * \r
+ * @param project\r
+ */\r
+ public static void shutdownActiveExperiment(IProject project) {\r
+ shutdownActiveExperiment(project, null);\r
+ }\r
+\r
+ /**\r
+ * Synchronously shutdown active experiment.\r
+ * \r
+ * @param project\r
+ */\r
+ public static void shutdownActiveExperiment(IProject project, IProgressMonitor monitor) {\r
+ IExperimentManager manager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ IExperiment experiment = manager.getActiveExperiment();\r
+ if (experiment != null)\r
+ experiment.shutdown(monitor);\r
+ }\r
+\r
+ /**\r
+ * If there is an active experiment, schedule a job for its shutdown.\r
+ * \r
+ * @param project\r
+ */\r
+ public static void scheduleShutdownActiveExperiment(IProject project) {\r
+ scheduleShutdownActiveExperiment(project, null);\r
+ }\r
+\r
+ /**\r
+ * If there is an active experiment, schedule a job for its shutdown.\r
+ * \r
+ * @param project\r
+ */\r
+ public static void scheduleShutdownActiveExperiment(IProject project, Consumer<IExperiment> callback) {\r
+ IExperimentManager manager = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ final IExperiment experiment = manager.getActiveExperiment();\r
+ if (experiment != null) {\r
+ Job job = new DatabaseJob("Shutting down experiment") {\r
+ @Override\r
+ protected IStatus run(final IProgressMonitor monitor) {\r
+ try {\r
+ experiment.shutdown(monitor);\r
+ if (callback != null)\r
+ callback.accept(null);\r
+ return Status.OK_STATUS;\r
+ } finally {\r
+ monitor.done();\r
+ }\r
+ }\r
+ };\r
+ job.setProperty(IProgressConstants2.SHOW_IN_TASKBAR_ICON_PROPERTY, Boolean.TRUE);\r
+ job.setUser(true);\r
+ job.schedule();\r
+ }\r
+ }\r
+\r
+ public static Variable possibleActiveRunVariable(ReadGraph graph, Resource model) throws DatabaseException {\r
+ return graph.syncRequest(new PossibleActiveRun(model));\r
+ }\r
+\r
+ /**\r
+ * @param processor\r
+ * @param experiment\r
+ * @param asyncCallback\r
+ * @return\r
+ * @throws DatabaseException\r
+ */\r
+ public static Resource activateExperiment(RequestProcessor processor, Resource experiment, Procedure<Resource> asyncCallback) throws DatabaseException {\r
+ VirtualGraphSupport vgs = processor.getService(VirtualGraphSupport.class);\r
+ WriteResultRequest<Resource> w = new WriteResultRequest<Resource>(vgs.getMemoryPersistent("experiments")) {\r
+ @Override\r
+ public Resource perform(WriteGraph graph) throws DatabaseException {\r
+ return activateExperiment(graph, experiment);\r
+ }\r
+ };\r
+ if (processor instanceof WriteGraph) {\r
+ return ((WriteGraph) processor).syncRequest(w);\r
+ } else {\r
+ if (asyncCallback == null)\r
+ asyncCallback = new ProcedureAdapter<>();\r
+ processor.getSession().asyncRequest(w, asyncCallback);\r
+ return null;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @param processor\r
+ * @param run\r
+ * @throws DatabaseException\r
+ */\r
+ public static void activateRun(RequestProcessor processor, Resource run) throws DatabaseException {\r
+ VirtualGraphSupport vgs = processor.getService(VirtualGraphSupport.class);\r
+ WriteRequest w = new WriteRequest(vgs.getMemoryPersistent("experiments")) {\r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ ExperimentUtil.activateRun(graph, run);\r
+ }\r
+ };\r
+ if (processor instanceof WriteGraph) {\r
+ ((WriteGraph) processor).syncRequest(w);\r
+ } else {\r
+ processor.getSession().asyncRequest(w);\r
+ }\r
+ }\r
+\r
+ private static Resource activateExperiment(WriteGraph graph, Resource experiment) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+\r
+ Resource experimentType = graph.getPossibleType(experiment, SIMU.Experiment);\r
+ if (experimentType == null)\r
+ throw new DatabaseException("No unique experiment type was found for experiment " + graph.getPossibleURI(experiment));\r
+ Collection<Resource> runTypes = graph.sync(new ObjectsWithType(experimentType, L0.ConsistsOf, SIMU.RunType));\r
+ if (runTypes.size() != 1)\r
+ throw new DatabaseException("No unique run type was found for experiment " + graph.getPossibleURI(experiment));\r
+ final Resource runType = runTypes.iterator().next();\r
+\r
+ VirtualGraphSupport vgs = graph.getService(VirtualGraphSupport.class);\r
+ return graph.syncRequest(new WriteResultRequest<Resource>(vgs.getMemoryPersistent("experiments")) {\r
+ @Override\r
+ public Resource perform(WriteGraph graph) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ Resource run = graph.newResource();\r
+ graph.claim(run, L0.InstanceOf, runType);\r
+ graph.addLiteral(run, L0.HasName, L0.NameOf, L0.String, UUID.randomUUID().toString(), Bindings.STRING);\r
+ graph.claim(experiment, L0.ConsistsOf, run);\r
+\r
+ Resource activeRun = graph.syncRequest(new PossibleActiveExperiment(experiment));\r
+ if (activeRun != null) {\r
+ graph.deny(activeRun, SIMU.IsActive, activeRun);\r
+ }\r
+ graph.claim(run, SIMU.IsActive, run);\r
+\r
+ return run;\r
+ }\r
+ });\r
+ }\r
+\r
+ private static void activateRun(WriteGraph graph, Resource run) throws DatabaseException {\r
+ SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+ Resource activeRun = graph.syncRequest(new PossibleActiveExperiment(run));\r
+ if (activeRun != null) {\r
+ graph.deny(activeRun, SIMU.IsActive, activeRun);\r
+ }\r
+ graph.claim(run, SIMU.IsActive, run);\r
+ }\r
+\r
+}\r