]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
First functional prototype for the simulation playback feature: Separate experiment...
authorlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 12 Oct 2011 11:39:46 +0000 (11:39 +0000)
committerlempinen <lempinen@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 12 Oct 2011 11:39:46 +0000 (11:39 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@22681 ac1ea38d-2e2b-0410-8846-a27921b304fc

19 files changed:
org.simantics.sysdyn.ontology/graph.tg
org.simantics.sysdyn.ontology/graph/Sysdyn.pgraph
org.simantics.sysdyn.ontology/src/org/simantics/sysdyn/SysdynResource.java
org.simantics.sysdyn.ui/plugin.xml
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/profiles/SimulationPlaybackStyle.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewExperimentNodeHandler.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewPlaybackExperimentNodeHandler.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ModelUtils.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ProfileEntries.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/DependencyFunction.java
org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/HistoryVariable.java
org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/PropertyProvider.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableValueSubscription.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynExperiment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java [new file with mode: 0644]
org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynResult.java

index 11db7b9ecb1886238ea91dd3e64d258ac166866d..ecd1bcebcac4fc74b0b874d50d5dcf47ba90f0a5 100644 (file)
Binary files a/org.simantics.sysdyn.ontology/graph.tg and b/org.simantics.sysdyn.ontology/graph.tg differ
index 8592edaff1352501379e2aaa467505b4d54c331d..7974a94b5e6c8f17028b2998385ee06286eafd84 100644 (file)
@@ -350,6 +350,8 @@ SYSDYN.GameExperiment <T SYSDYN.Experiment
 
 SYSDYN.SimulateOnChangeExperiment <T SYSDYN.Experiment
 
+SYSDYN.PlaybackExperiment <T SYSDYN.Experiment
+
 SYSDYN.HasResult <R L0.IsComposedOf
     L0.HasRange SYSDYN.Result
 
index 77000eb8f62c44b22b95668532aa7eb0ab9f2a2f..1b16443f8601e9332de395ae6307b8ccbe4bdcaf 100644 (file)
@@ -139,6 +139,7 @@ public class SysdynResource {
     public final Resource ModuleSymbol;\r
     public final Resource NormalExpression;\r
     public final Resource ParameterExpression;\r
+    public final Resource PlaybackExperiment;\r
     public final Resource Polarity;\r
     public final Resource Polarity_Inverse;\r
     public final Resource Profiles;\r
@@ -334,6 +335,7 @@ public class SysdynResource {
         public static final String ModuleSymbol = "http://www.simantics.org/Sysdyn-1.0/ModuleSymbol";\r
         public static final String NormalExpression = "http://www.simantics.org/Sysdyn-1.0/NormalExpression";\r
         public static final String ParameterExpression = "http://www.simantics.org/Sysdyn-1.0/ParameterExpression";\r
+        public static final String PlaybackExperiment = "http://www.simantics.org/Sysdyn-1.0/PlaybackExperiment";\r
         public static final String Polarity = "http://www.simantics.org/Sysdyn-1.0/Polarity";\r
         public static final String Polarity_Inverse = "http://www.simantics.org/Sysdyn-1.0/Polarity/Inverse";\r
         public static final String Profiles = "http://www.simantics.org/Sysdyn-1.0/Profiles";\r
@@ -539,6 +541,7 @@ public class SysdynResource {
         ModuleSymbol = getResourceOrNull(graph, URIs.ModuleSymbol);\r
         NormalExpression = getResourceOrNull(graph, URIs.NormalExpression);\r
         ParameterExpression = getResourceOrNull(graph, URIs.ParameterExpression);\r
+        PlaybackExperiment = getResourceOrNull(graph, URIs.PlaybackExperiment);\r
         Polarity = getResourceOrNull(graph, URIs.Polarity);\r
         Polarity_Inverse = getResourceOrNull(graph, URIs.Polarity_Inverse);\r
         Profiles = getResourceOrNull(graph, URIs.Profiles);\r
index bec90398a04bd40ef4959ea92b6a08fce0e19780..9179e5173e1836d32b2f704e716d1e43cdd51427 100644 (file)
             id="org.simantics.sysdyn.ui.basicExperiment"\r
             name="Basic Experiment">\r
       </context>\r
+      <context\r
+            id="org.simantics.sysdyn.ui.playbackExperiment"\r
+            name="Playback experiment">\r
+      </context>\r
    </extension>\r
    <extension\r
          point="org.eclipse.ui.menus">\r
                </visibleWhen>\r
             </command>\r
          </toolbar>\r
+         <toolbar\r
+               id="org.simantics.sysdyn.ui.playbackControlToolbar">\r
+            <dynamic\r
+                  class="org.simantics.sysdyn.ui.menu.PlaybackSliderContribution"\r
+                  id="org.simantics.sysdyn.ui.playbackSlider">\r
+               <visibleWhen>\r
+                  <with\r
+                        variable="activeContexts">\r
+                     <iterate\r
+                           ifEmpty="false"\r
+                           operator="or">\r
+                        <equals\r
+                              value="org.simantics.sysdyn.ui.playbackExperiment">\r
+                        </equals>\r
+                     </iterate>\r
+                  </with>\r
+               </visibleWhen>\r
+            </dynamic>\r
+         </toolbar>\r
       </menuContribution>\r
       <menuContribution\r
             locationURI="toolbar:org.simantics.sysdyn.ui.trend.view">\r
                   </with>\r
                </visibleWhen>\r
             </command>\r
+            <command\r
+                  commandId="org.simantics.sysdyn.ui.newPlaybackExperiment"\r
+                  id="org.simantics.sysdyn.ui.browser.newPlaybackExperiment"\r
+                  label="Playback Experiment"\r
+                  style="push">\r
+               <visibleWhen\r
+                     checkEnabled="true">\r
+                  <with\r
+                        variable="selection">\r
+                     <test\r
+                           args="org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder"\r
+                           property="org.simantics.sysdyn.ui.nodeClass">\r
+                     </test>\r
+                  </with>\r
+               </visibleWhen>\r
+            </command>\r
             <command\r
                   commandId="org.simantics.sysdyn.ui.newEnumeration"\r
                   id="org.simantics.sysdyn.ui.browser.newEnumeration"\r
             id="org.simantics.sysdyn.ui.newModel"\r
             name="New System Dynamics Model">\r
       </command>\r
+      <command\r
+            id="org.simantics.sysdyn.ui.newPlaybackExperiment"\r
+            name="New Playback Experiment">\r
+      </command>\r
    </extension>\r
    <extension\r
          point="org.eclipse.ui.handlers">\r
             class="org.simantics.sysdyn.ui.handlers.NewModelHandler"\r
             commandId="org.simantics.sysdyn.ui.newModel">\r
       </handler>\r
+      <handler\r
+            class="org.simantics.sysdyn.ui.handlers.NewPlaybackExperimentNodeHandler"\r
+            commandId="org.simantics.sysdyn.ui.newPlaybackExperiment">\r
+      </handler>\r
    </extension>\r
    <extension\r
          point="org.simantics.browsing.ui.common.viewpointContributionBinding">\r
index 26aa36821f83f475dbd9f8f8410adacf01fbe7b0..1dcf494e32444368afbc037d283f461d9cd1b1d8 100644 (file)
 package org.simantics.sysdyn.ui.elements2.profiles;\r
 \r
-import java.awt.BasicStroke;\r
 import java.awt.Color;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.Rectangle2D;\r
+import java.util.HashMap;\r
 \r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.accessor.ArrayAccessor;\r
+import org.simantics.databoard.accessor.RecordAccessor;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.databoard.type.DoubleType;\r
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
-import org.simantics.db.common.request.ObjectsWithType;\r
-import org.simantics.db.common.utils.NameUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.diagram.elements.TextNode;\r
 import org.simantics.diagram.profile.StyleBase;\r
-import org.simantics.diagram.stubs.G2DResource;\r
-import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\r
-import org.simantics.issues.ontology.IssueResource;\r
-import org.simantics.layer0.Layer0;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
 import org.simantics.modeling.ModelingResources;\r
+import org.simantics.project.IProject;\r
 import org.simantics.scenegraph.INode;\r
-import org.simantics.scenegraph.g2d.nodes.ShapeNode;\r
+import org.simantics.scenegraph.g2d.nodes.SingleElementNode;\r
 import org.simantics.scenegraph.profile.EvaluationContext;\r
 import org.simantics.scenegraph.profile.Observer;\r
-import org.simantics.scenegraph.profile.common.ProfileVariables;\r
-import org.simantics.scenegraph.utils.GeometryUtils;\r
 import org.simantics.scenegraph.utils.NodeUtil;\r
-import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.ui.SimanticsUI;\r
 \r
-public class SimulationPlaybackStyle extends StyleBase<AffineTransform> {\r
-\r
-    public static class A extends ShapeNode {\r
-\r
-        private static final long serialVersionUID = -5273246617906214956L;\r
-\r
-        @Override\r
-        public Rectangle2D getBoundsInLocal() {\r
-            return null;\r
-        }\r
-\r
-        @Override\r
-        public Rectangle2D getBoundsInLocal(boolean b) {\r
-            return null;\r
-        }\r
-\r
-        @Override\r
-        public Rectangle2D getBounds() {\r
-            return null;\r
-        }\r
-        \r
-    }\r
+public class SimulationPlaybackStyle extends StyleBase<Double> {\r
     \r
+    HashMap<INode, Runnable> timeListeners = new HashMap<INode, Runnable>();\r
+\r
     @Override\r
-    public AffineTransform calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {\r
-//        TODO: Get results from variable\r
-//        DiagramResource dr = DiagramResource.getInstance(graph);\r
-//        String rvi = graph.getPossibleRelatedValue(runtimeDiagram, dr.RuntimeDiagram_HasRVI, Bindings.STRING);\r
+    public Double calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {\r
         \r
-        Layer0 l0 = Layer0.getInstance(graph);\r
-        SysdynResource sr = SysdynResource.getInstance(graph);\r
-        ModelingResources mr = ModelingResources.getInstance(graph);\r
-        IssueResource issue = IssueResource.getInstance(graph);\r
+        IProject project = SimanticsUI.getProject();\r
+        IExperimentManager em = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+        IExperiment experiment = em.getActiveExperiment();\r
+        if(!(experiment instanceof SysdynPlaybackExperiment))\r
+            return null;\r
         \r
+        ModelingResources mr = ModelingResources.getInstance(graph);\r
+        DiagramResource dr = DiagramResource.getInstance(graph);\r
+\r
         Resource component = graph.getPossibleObject(element, mr.ElementToComponent);\r
         if (component == null)\r
             return null;\r
-        \r
-        Resource config = graph.getPossibleObject(component, l0.PartOf);\r
-        \r
-        Resource model = graph.getPossibleObject(config, l0.PartOf);\r
-        if(!graph.isInstanceOf(model, sr.SysdynModel))\r
-            return null;\r
-        \r
-        for(Resource i : graph.syncRequest(new ObjectsWithType(model, l0.ConsistsOf, issue.Issue))) {\r
-            System.out.println(NameUtils.getSafeName(graph, graph.getSingleObject(i, issue.HasIssueContext)));\r
-            if(graph.getSingleObject(i, issue.HasIssueContext).equals(component)) {\r
-                AffineTransform at = DiagramGraphUtil.getAffineTransform(graph, element,  G2DResource.getInstance(graph).HasTransform, true);\r
-                return at;\r
+\r
+        try {\r
+\r
+            String dv = graph.getPossibleRelatedValue(runtimeDiagram, dr.RuntimeDiagram_HasVariable);\r
+            Variable rootVariable = graph.getPossibleAdapter(graph.getRootLibrary(), Variable.class);\r
+            if (rootVariable == null) \r
+                return null;\r
+            Variable diagramVariable = rootVariable.browsePossible(graph, dv.substring(6));\r
+            if(diagramVariable == null) \r
+                return null;\r
+\r
+            Variable var = diagramVariable.browsePossible(graph, component);\r
+            if(var == null)\r
+                return null;\r
+            \r
+            Double time = var.getPossiblePropertyValue(graph, Variables.DISPLAY_VALUE, Bindings.DOUBLE);\r
+            if(time == null)\r
+                return null;\r
+\r
+            \r
+            final RecordAccessor acc = var.getInterface(graph, RecordAccessor.class);\r
+            if(acc == null) \r
+                return null;\r
+            \r
+            \r
+            ArrayAccessor timeAccessor, valueAccessor;\r
+            timeAccessor = acc.getFieldAccessor(1);\r
+            valueAccessor = acc.getFieldAccessor(2);\r
+            Datatype dt = new org.simantics.databoard.type.ArrayType(new DoubleType());\r
+\r
+            double[] ta = (double[]) timeAccessor.getValue(Bindings.getBinding(dt));\r
+            double[] va = (double[]) valueAccessor.getValue(Bindings.getBinding(dt));\r
+            if(va.length == 0 || va.length == 2)\r
+                return null;\r
+            \r
+            double min = va[0], max = va[0];\r
+            for(double d : va) {\r
+                if(d < min) \r
+                    min = d;\r
+                if(d > max)\r
+                    max = d;\r
+            }\r
+            \r
+            int index = 0;\r
+            if(ta[ta.length - 1] - time > ta[ta.length / 2] ) {\r
+                index = ta.length - 1;\r
+                while(ta[index] > time)\r
+                    index--;\r
+            } else {\r
+                while(ta[index] < time)\r
+                    index++;\r
             }\r
+            \r
+            double value = va[index];\r
+            \r
+            double multiplier = (value - min) / (max - min);\r
+\r
+//            AffineTransform at = (AffineTransform) DiagramGraphUtil.getAffineTransform(graph, element,  G2DResource.getInstance(graph).HasTransform, true).clone();\r
+//            at.translate(0, 10);\r
+            return multiplier;\r
+            \r
+        } catch(Exception ignore) {\r
+            System.err.println("POIKKEUS SimulationPlaybackStyle");\r
+            ignore.printStackTrace();\r
         }\r
-        \r
         return null;\r
-//        String name = graph.getPossibleRelatedValue(config, l0.HasName, Bindings.STRING);\r
-//        if(name == null)\r
-//            return null;\r
-//        if(name.startsWith("A")) {\r
-//            AffineTransform at = DiagramGraphUtil.getAffineTransform(graph, element,  G2DResource.getInstance(graph).HasTransform, true);\r
-//            return at;\r
-//        } else {\r
-//            return null;\r
-//        }\r
     }\r
 \r
     @Override\r
-    public void styleResultChanged(Observer observer, Resource element, AffineTransform result) {\r
+    public void styleResultChanged(Observer observer, Resource element, Double result) {\r
         if (result != null)\r
             values.put(element, result);\r
         else\r
@@ -100,19 +125,13 @@ public class SimulationPlaybackStyle extends StyleBase<AffineTransform> {
     }\r
 \r
     @Override\r
-    public void applyStyleForNode(EvaluationContext observer, INode _node, AffineTransform transform) {\r
-        if (transform != null) {\r
-            A node = ProfileVariables.claimChild(_node, "", "simulationPlaybackColour", A.class, observer);\r
-            if (node == null)\r
-                return;\r
-\r
-            Rectangle2D expandedElementBounds = GeometryUtils.expandRectangle( NodeUtil.getLocalElementBounds(_node), 0.5 );\r
-            node.setTransform(transform);\r
-            node.setZIndex(-1000);\r
-            node.setFill(true);\r
-            node.setColor(Color.LIGHT_GRAY);\r
-            node.setStroke(new BasicStroke(0.2f));\r
-            node.setValue("shape", expandedElementBounds);\r
+    public void applyStyleForNode(EvaluationContext observer, INode _node, Double multiplier) {\r
+        if (multiplier != null) {\r
+            TextNode n = NodeUtil.getNearestChildByClass((SingleElementNode)_node, TextNode.class);\r
+            Color c = new Color(multiplier.floatValue(), (float)(0), (float) (1 - multiplier));\r
+            if(n != null) {\r
+                n.setBackgroundColor(c);\r
+            }\r
         } else {\r
             cleanupStyleForNode(_node);\r
         }\r
@@ -120,8 +139,11 @@ public class SimulationPlaybackStyle extends StyleBase<AffineTransform> {
 \r
     @Override\r
     protected void cleanupStyleForNode(INode node) {\r
-        ProfileVariables.denyChild(node, "", "simulationPlaybackColour");\r
+        if(node instanceof SingleElementNode) {\r
+            TextNode n = NodeUtil.getNearestChildByClass((SingleElementNode)node, TextNode.class);\r
+            if(n != null)\r
+                n.setBackgroundColor(null);\r
+        }\r
     }\r
-\r
 }\r
 
index 412a4251af5a8bb73c0793a548a4476ac09eca8c..16bcd5ec83d59255b7327356146b3150bf5f67d5 100644 (file)
@@ -16,6 +16,7 @@ import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;\r
 import org.eclipse.jface.viewers.ISelection;\r
 import org.eclipse.ui.handlers.HandlerUtil;\r
+import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
 import org.simantics.db.WriteGraph;\r
 import org.simantics.db.common.request.WriteRequest;\r
@@ -24,7 +25,7 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.document.DocumentResource;\r
 import org.simantics.layer0.Layer0;\r
 import org.simantics.layer0.utils.direct.GraphUtils;\r
-import org.simantics.simulation.ontology.SimulationResource;\r
+import org.simantics.sysdyn.SysdynResource;\r
 import org.simantics.sysdyn.ui.browser.nodes.ExperimentsFolder;\r
 import org.simantics.ui.SimanticsUI;\r
 import org.simantics.ui.utils.AdaptionUtils;\r
@@ -51,10 +52,10 @@ public class NewExperimentNodeHandler extends AbstractHandler {
                 DocumentResource DOC = DocumentResource.getInstance(g);\r
                 Resource report = GraphUtils.create2(g, DOC.Report,  DOC.HasDocumentation, "===Report===");\r
 \r
-                String name = NameUtils.findFreshName(g, "Experiment", model, l0.ConsistsOf, "%s%d");\r
+                String name = NameUtils.findFreshName(g, getNameSuggestion(), model, l0.ConsistsOf, "%s%d");\r
 \r
                 @SuppressWarnings("unused")\r
-                Resource experiment = GraphUtils.create2(g, SimulationResource.getInstance(g).Experiment,\r
+                Resource experiment = GraphUtils.create2(g, getExperimentType(g),\r
                         l0.HasName, name,\r
                         l0.HasLabel, name,\r
                         DOC.HasReportFactory, report,\r
@@ -63,5 +64,13 @@ public class NewExperimentNodeHandler extends AbstractHandler {
         });\r
         return null;\r
     }\r
+    \r
+    protected Resource getExperimentType(ReadGraph g) {\r
+        return SysdynResource.getInstance(g).BasicExperiment;\r
+    }\r
+    \r
+    protected String getNameSuggestion() {\r
+        return "Experiment";\r
+    }\r
 \r
 }\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewPlaybackExperimentNodeHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewPlaybackExperimentNodeHandler.java
new file mode 100644 (file)
index 0000000..417f326
--- /dev/null
@@ -0,0 +1,17 @@
+package org.simantics.sysdyn.ui.handlers;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+\r
+public class NewPlaybackExperimentNodeHandler  extends NewExperimentNodeHandler  {\r
+    \r
+    protected Resource getExperimentType(ReadGraph g) {\r
+        return SysdynResource.getInstance(g).PlaybackExperiment;\r
+    }\r
+    \r
+    protected String getNameSuggestion() {\r
+        return "Playback Experiment";\r
+    }\r
+}
\ No newline at end of file
index ba27f53abcec0fd9453017357c81f535f0ca116d..d631a2d5c2d6e515e196ae1f97ba49013c718fcb 100644 (file)
@@ -23,11 +23,14 @@ import org.eclipse.ui.contexts.IContextService;
 import org.simantics.simulation.experiment.IExperiment;\r
 import org.simantics.simulation.project.IExperimentManager;\r
 import org.simantics.simulation.project.IExperimentManagerListener;\r
+import org.simantics.sysdyn.manager.SysdynExperiment;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
 \r
 public class SysdynExperimentManagerListener implements IExperimentManagerListener{\r
 \r
     public static final String BASIC_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.basicExperiment";\r
-    \r
+    public static final String PLAYBACK_EXPERIMENT_CONTEXT = "org.simantics.sysdyn.ui.playbackExperiment";\r
+   \r
     static Set<IExperimentManager> managers = \r
         new HashSet<IExperimentManager>();\r
     \r
@@ -63,7 +66,10 @@ public class SysdynExperimentManagerListener implements IExperimentManagerListen
                     (IContextService)PlatformUI.getWorkbench()\r
                     .getActiveWorkbenchWindow().getService(IContextService.class);\r
                 synchronized(contextActivations) {\r
-                    contextActivations.add(contextService.activateContext(BASIC_EXPERIMENT_CONTEXT));\r
+                    if(experiment instanceof SysdynPlaybackExperiment)\r
+                        contextActivations.add(contextService.activateContext(PLAYBACK_EXPERIMENT_CONTEXT));\r
+                    else if(experiment instanceof SysdynExperiment)\r
+                        contextActivations.add(contextService.activateContext(BASIC_EXPERIMENT_CONTEXT));\r
                 }\r
             }\r
             \r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java
new file mode 100644 (file)
index 0000000..04596c1
--- /dev/null
@@ -0,0 +1,98 @@
+package org.simantics.sysdyn.ui.menu;\r
+\r
+import org.eclipse.jface.action.ToolBarContributionItem;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.widgets.Composite;\r
+import org.eclipse.swt.widgets.Label;\r
+import org.eclipse.swt.widgets.Slider;\r
+import org.eclipse.swt.widgets.ToolBar;\r
+import org.eclipse.swt.widgets.ToolItem;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class PlaybackSliderContribution extends ToolBarContributionItem {\r
+\r
+\r
+    @Override\r
+    public void fill(ToolBar parent, int index)\r
+    {\r
+        if (parent != null) {\r
+\r
+            IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+            IExperiment experiment = manager.getActiveExperiment();\r
+            if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) \r
+                return;\r
+            final SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment;\r
+            \r
+            Double[] numbers = new Double[3];\r
+            try {\r
+                numbers = SimanticsUI.getSession().syncRequest(new Read<Double[]>() {\r
+                    @Override\r
+                    public Double[] perform(ReadGraph graph) throws DatabaseException {\r
+                        Double[] numbers = new Double[3];\r
+                        Resource model = spe.getModel();\r
+                        SysdynResource sr = SysdynResource.getInstance(graph);\r
+                        numbers[0] = graph.getRelatedValue(model, sr.HasStartTime);\r
+                        numbers[1] = graph.getRelatedValue(model, sr.HasStopTime);\r
+                        numbers[2] = graph.getPossibleRelatedValue(model, sr.HasOutputInterval);\r
+                        return numbers;\r
+                    }\r
+                });\r
+            } catch (DatabaseException e1) {\r
+                e1.printStackTrace();\r
+            }\r
+            \r
+            ToolItem ti = new ToolItem(parent, SWT.SEPARATOR);\r
+            \r
+            Composite composite = new Composite(parent, SWT.NONE);\r
+            GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite);\r
+            GridDataFactory.fillDefaults().applyTo(composite);\r
+\r
+            Slider s = new Slider(composite, SWT.NONE);\r
+            s.setMinimum(0);\r
+            s.setMaximum(100);\r
+            s.setIncrement(1);\r
+            s.setPageIncrement(1);\r
+            s.setThumb(1);\r
+            \r
+            final Label label = new Label(composite, SWT.NONE);\r
+            GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).applyTo(label);\r
+            label.setText("0.0");\r
+\r
+            ti.setWidth(250);\r
+            ti.setControl(composite);\r
+            \r
+            final Double startTime = numbers[0];\r
+            final Double endTime = numbers[1];\r
+            \r
+\r
+            s.addSelectionListener(new SelectionListener() {\r
+\r
+                @Override\r
+                public void widgetSelected(SelectionEvent e) {\r
+                    Slider s = (Slider)e.widget;\r
+                    Double time = s.getSelection() / 99.0 * (endTime - startTime) + startTime;\r
+                    spe.setTime(time);\r
+                    if(!label.isDisposed()) {\r
+                        label.setText(time.toString());\r
+                    }\r
+                }\r
+\r
+                @Override\r
+                public void widgetDefaultSelected(SelectionEvent e) {\r
+                }\r
+            });\r
+        }\r
+    }\r
+}\r
index 05a1b500204b309845575fdbb7ca22f4684d386e..cfa0f15fb62da677858a6f2dca892dfe497a60a7 100644 (file)
@@ -116,7 +116,7 @@ public class ModelUtils {
 \r
             Resource report = GraphUtils.create2(g, DOC.Report,  DOC.HasDocumentation, "===Report===");\r
 \r
-            GraphUtils.create2(g, mu.SIMU.Experiment,\r
+            GraphUtils.create2(g, sr.BasicExperiment,\r
                     l0.HasName, "Experiment",\r
                     l0.HasLabel, "Experiment",\r
                     DOC.HasReportFactory, report,\r
index d285d393ef7d5e2b466057bfa9e7e1635c37641c..597f07b3add1fd5cdff861818fce967c01a00bb5 100644 (file)
@@ -24,7 +24,7 @@ public class ProfileEntries  {
         Layer0 L0 = Layer0.getInstance(graph);\r
         DiagramResource DIA = DiagramResource.getInstance(graph);\r
 \r
-        final Resource a = createWorkProfile(graph, "A");\r
+        final Resource a = createWorkProfile(graph, "Simulation Playback");\r
 \r
         Resource plain = Profiles.createProfile(graph, "Plain");\r
 \r
index 828f722d795deac6a274d2fbb4a353093ca4c209..edd32658a54042b0b2f88fdef53dfe2f5f26a455 100644 (file)
@@ -84,7 +84,6 @@ public class DependencyFunction {
                 return Boolean.FALSE;\r
             }\r
         }\r
-        System.out.println("NOTHING");\r
         return Boolean.TRUE;\r
     }\r
 \r
@@ -104,11 +103,8 @@ public class DependencyFunction {
         \r
         String name = graph.getRelatedValue(variable, L0.HasName, Bindings.STRING);\r
         \r
-        System.out.println("SOME CHANGE IN " + name + "(existing: " + existing.size() + ")");\r
-        \r
         Set<String> labels = new HashSet<String>();\r
         String label;\r
-        Resource issue;\r
         \r
         for(String reference : references) {\r
             label = getMissingLinkLabel(name, reference);\r
@@ -159,7 +155,6 @@ public class DependencyFunction {
     }\r
     \r
     private static Resource createIssue(WriteGraph graph, Resource model, Resource source, Resource variable, String label) throws DatabaseException {\r
-        System.out.println("CREATE ISSUE: " + label);\r
         Layer0 L0 = Layer0.getInstance(graph);\r
         IssueResource ISSUE = IssueResource.getInstance(graph);\r
         \r
@@ -178,7 +173,6 @@ public class DependencyFunction {
     }\r
     \r
     private static void removeIssue(WriteGraph graph, Resource model, Resource source, Resource variable, Resource issue, Collection<Resource> existing) throws DatabaseException {\r
-        System.out.println("REMOVE ISSUE: " + graph.getRelatedValue(issue, Layer0.getInstance(graph).HasLabel));\r
         graph.deny(issue, Layer0.getInstance(graph).PartOf);\r
         graph.deny(source, IssueResource.getInstance(graph).Manages, issue);\r
         existing.remove(issue);\r
index 1b0dfe75682440e222e05e856455f5d6d5df832f..76c98f91c8f79950e07f58cb1c628107d00388b2 100644 (file)
@@ -17,6 +17,7 @@ import java.util.Map;
 \r
 import org.simantics.databoard.Accessors;\r
 import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Datatypes;\r
 import org.simantics.databoard.accessor.Accessor;\r
 import org.simantics.databoard.accessor.RecordAccessor;\r
 import org.simantics.databoard.accessor.error.AccessorConstructionException;\r
@@ -24,25 +25,34 @@ import org.simantics.databoard.accessor.error.AccessorException;
 import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;\r
 import org.simantics.db.ReadGraph;\r
 import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ParametrizedPrimitiveRead;\r
 import org.simantics.db.common.uri.UnescapedChildMapOfResource;\r
 import org.simantics.db.common.utils.NameUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.db.layer0.exception.MissingVariableException;\r
+import org.simantics.db.layer0.variable.ConstantPropertyVariable;\r
 import org.simantics.db.layer0.variable.Variable;\r
 import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.ExternalRead;\r
 import org.simantics.layer0.Layer0;\r
 import org.simantics.simulation.ontology.SimulationResource;\r
 import org.simantics.structural.stubs.StructuralResource2;\r
 import org.simantics.sysdyn.SysdynResource;\r
 import org.simantics.sysdyn.manager.SysdynDataSet;\r
+import org.simantics.sysdyn.manager.SysdynExperiment;\r
 import org.simantics.sysdyn.manager.SysdynModel;\r
 import org.simantics.sysdyn.manager.SysdynModelManager;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
 import org.simantics.sysdyn.manager.SysdynResult;\r
 \r
-public class HistoryVariable extends ChildVariable {\r
+public class HistoryVariable extends ChildVariable implements PropertyProvider {\r
 \r
+    SysdynExperiment experiment;\r
+    \r
        public HistoryVariable(Variable parent, Resource resource) {\r
                super(parent, resource);\r
+               experiment = SysdynExperiment.INSTANCE;\r
        }\r
        \r
        \r
@@ -143,5 +153,54 @@ public class HistoryVariable extends ChildVariable {
                } else {\r
                        return super.browseChildren(graph);\r
                }\r
-       }       \r
+       }\r
+       \r
+       \r
+       @Override\r
+       public Variable getPossibleExtraProperty(ReadGraph graph, final String name) throws DatabaseException {\r
+           if(Variables.DISPLAY_VALUE.equals(name)) {\r
+               return graph.syncRequest(new ParametrizedPrimitiveRead<Variable, Variable>(this) {\r
+                   VariableValueSubscription subscription;\r
+                   @Override\r
+                   public void register(Listener<Variable> procedure) {\r
+                       subscription = registerSubscription(this, procedure, name);\r
+                   }\r
+                   @Override\r
+                   public void unregistered() {\r
+                       unregisterSubscription(subscription);\r
+                       subscription = null;\r
+                   }\r
+               });\r
+           }\r
+           return super.getPossibleExtraProperty(graph, name);\r
+       }\r
+\r
+       protected VariableValueSubscription registerSubscription(ExternalRead<?> request, Listener<Variable> procedure, String property) {\r
+           if(experiment instanceof SysdynPlaybackExperiment) {\r
+               VariableValueSubscription subscription = new VariableValueSubscription(request, this, property, procedure);\r
+               experiment.addVariableValueSubscription(subscription);\r
+               subscription.update();\r
+               return subscription;\r
+           } else {\r
+               return null;\r
+           }\r
+    }\r
+\r
+    protected void unregisterSubscription(VariableValueSubscription subscription) {\r
+        subscription.setListener(null);\r
+        experiment.removeVariableValueSubscription(subscription);\r
+    }\r
+\r
+    @Override\r
+    public Variable getProperty(String name) {\r
+        if(Variables.DISPLAY_VALUE.equals(name)){\r
+            if(experiment instanceof SysdynPlaybackExperiment) {\r
+                SysdynPlaybackExperiment exp = (SysdynPlaybackExperiment) experiment;\r
+                return new ConstantPropertyVariable(parent, name, exp.getTime(), Datatypes.DOUBLE);\r
+            } else {\r
+                return new ConstantPropertyVariable(parent, name, 0, Datatypes.DOUBLE);\r
+            }\r
+        }        \r
+        return null;\r
+    }\r
 }\r
diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/PropertyProvider.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/PropertyProvider.java
new file mode 100644 (file)
index 0000000..2a7bcd0
--- /dev/null
@@ -0,0 +1,10 @@
+package org.simantics.sysdyn.adapter;\r
+\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+\r
+public interface PropertyProvider {\r
+\r
+    Variable getProperty(String name)  throws DatabaseException, AdaptException;\r
+}\r
diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableValueSubscription.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/VariableValueSubscription.java
new file mode 100644 (file)
index 0000000..e04aed7
--- /dev/null
@@ -0,0 +1,103 @@
+package org.simantics.sysdyn.adapter;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
+\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.procedure.Listener;\r
+import org.simantics.db.request.ExternalRead;\r
+import org.simantics.db.service.QueryControl;\r
+import org.simantics.utils.datastructures.Callback;\r
+\r
+public class VariableValueSubscription {\r
+    \r
+    public static final long SUBSCRIPTION_COLLECTION_INTERVAL = 2000L;\r
+\r
+    protected ExternalRead<?>  request;\r
+    protected PropertyProvider provider;\r
+    protected String           property;\r
+    protected Listener<Variable> listener;\r
+\r
+    /**\r
+     * To protect against invoking listener.exception multiple times which is\r
+     * forbidden.\r
+     */\r
+    protected AtomicBoolean    excepted = new AtomicBoolean(false);\r
+\r
+    public VariableValueSubscription(ExternalRead<?> request, PropertyProvider variable, String property, Listener<Variable> listener) {\r
+        this.request = request;\r
+        this.provider = variable;\r
+        this.property = property;\r
+        this.listener = listener;\r
+    }\r
+\r
+    public ExternalRead<?> getRequest() {\r
+        return request;\r
+    }\r
+\r
+    public void update() {\r
+        update(property);\r
+    }\r
+\r
+    public void update(String property) {\r
+        try {\r
+            Variable value = provider.getProperty(property);\r
+            fireValue(value);\r
+        } catch (DatabaseException e) {\r
+            fireException(e);\r
+        } catch (AdaptException e) {\r
+            fireException(e);\r
+        }\r
+    }\r
+\r
+    void fireValue(Variable value) {\r
+        if (listener != null)\r
+            listener.execute(value);\r
+    }\r
+\r
+    void fireException(Throwable t) {\r
+        if (listener != null && excepted.compareAndSet(false, true))\r
+            listener.exception(t);\r
+    }\r
+\r
+    public void setListener(Listener<Variable> listener) {\r
+        this.listener = listener;\r
+    }\r
+\r
+    /**\r
+     * This makes sure that subscriptions regarding performed DB external reads\r
+     * are abolished from DB client caches when no longer needed.\r
+     * \r
+     * @param session \r
+     * @param subscriptions\r
+     */\r
+    public static void collectSubscriptions(Session session, final VariableValueSubscription[] subscriptions, final ExternalRead<?>... extraReads) {\r
+        if (subscriptions.length == 0 && extraReads.length == 0)\r
+            return;\r
+\r
+        session.asyncRequest(new WriteRequest() {\r
+            @Override\r
+            public void perform(WriteGraph graph) throws DatabaseException {\r
+                Collection<ExternalRead<?>> requests = new ArrayList<ExternalRead<?>>(subscriptions.length + extraReads.length);\r
+                for (VariableValueSubscription subscription : subscriptions)\r
+                    requests.add(subscription.getRequest());\r
+                for (ExternalRead<?> read : extraReads)\r
+                    requests.add(read);\r
+                graph.getService(QueryControl.class).gc(graph, requests);\r
+            }\r
+        }, new Callback<DatabaseException>() {\r
+            @Override\r
+            public void run(DatabaseException e) {\r
+                if (e != null)\r
+                    e.printStackTrace();\r
+            }\r
+        });\r
+    }\r
+\r
+}\r
index 8fc4baa83c25864988e9fce1d38feea7788b1d5b..2dbe53d533021ed3f0273a33843b6ef5e22a895c 100644 (file)
@@ -11,6 +11,8 @@
  *******************************************************************************/\r
 package org.simantics.sysdyn.manager;\r
 \r
+import gnu.trove.set.hash.THashSet;\r
+\r
 import java.io.File;\r
 import java.util.UUID;\r
 import java.util.concurrent.locks.Lock;\r
@@ -34,26 +36,29 @@ import org.simantics.simulation.experiment.ExperimentState;
 import org.simantics.simulation.experiment.IDynamicExperiment;\r
 import org.simantics.simulation.ontology.SimulationResource;\r
 import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.adapter.VariableValueSubscription;\r
 import org.simantics.sysdyn.simulation.SimulationScheduler;\r
 \r
 public class SysdynExperiment extends Experiment implements IDynamicExperiment {\r
 \r
-       Session session;\r
-       Runnable modificationListener;\r
-       Resource experiment;\r
-       SysdynModel sysdynModel;\r
-       boolean toggled = false;\r
+       protected Session session;\r
+       protected Runnable modificationListener;\r
+       protected SysdynModel sysdynModel;\r
+       protected boolean toggled = false;\r
+    protected THashSet<VariableValueSubscription> variableValueSubscriptions = new THashSet<VariableValueSubscription>();\r
+    protected volatile VariableValueSubscription[] variableValueSubscriptionsSnapshot = null;\r
+       \r
+       public static SysdynExperiment INSTANCE;\r
 \r
        public SysdynExperiment(Resource experiment, Resource model) {\r
-               super(model);\r
-               this.experiment = experiment;\r
-               // TODO Auto-generated constructor stub\r
+               super(experiment, model);\r
+               INSTANCE = this;\r
        }\r
-\r
-       public Resource getResource() {\r
-               return this.experiment;\r
+       \r
+       public static SysdynExperiment getInstance() {\r
+           return INSTANCE;\r
        }\r
-\r
+       \r
        @Override\r
        public void rewindTo(double time) {\r
                // TODO Auto-generated method stub\r
@@ -108,7 +113,7 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment {
        }\r
 \r
 \r
-       private void startSimulation() {\r
+       protected void startSimulation() {\r
                session.asyncRequest(new ReadRequest() {\r
 \r
                        @Override\r
@@ -231,7 +236,7 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment {
        }\r
 \r
 \r
-       private void toggleActivation(ReadGraph graph, final boolean activate) {\r
+       protected void toggleActivation(ReadGraph graph, final boolean activate) {\r
                VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);\r
                final Session session = graph.getSession();\r
                session.asyncRequest(new WriteRequest(support.getWorkspacePersistent("experiments")) {\r
@@ -266,6 +271,76 @@ public class SysdynExperiment extends Experiment implements IDynamicExperiment {
         // TODO Auto-generated method stub\r
         return null;\r
     }\r
+    \r
+    /**\r
+     * Copy from AprosExperiment\r
+     * @param subscription\r
+     */\r
+    public void addVariableValueSubscription(VariableValueSubscription subscription) {\r
+        assert subscription != null;\r
+        synchronized (variableValueSubscriptions) {\r
+            //System.out.println("ADD listener " + subscription);\r
+            variableValueSubscriptions.add(subscription);\r
+            variableValueSubscriptionsSnapshot = null;\r
+        }\r
+    }\r
+    \r
+    /**\r
+     * Copy from AprosExperiment\r
+     * @param subscription\r
+     */\r
+    public void removeVariableValueSubscription(VariableValueSubscription subscription) {\r
+        assert subscription != null;\r
+        synchronized (variableValueSubscriptions) {\r
+            //System.out.println("REMOVE listener " + subscription);\r
+            variableValueSubscriptions.remove(subscription);\r
+            variableValueSubscriptionsSnapshot = null;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Copy from AprosExperiment\r
+     * @return\r
+     */\r
+    private VariableValueSubscription[] getListenerSnapshot() {\r
+        VariableValueSubscription[] snapshot = variableValueSubscriptionsSnapshot;\r
+        if (snapshot == null) {\r
+            synchronized (variableValueSubscriptions) {\r
+                snapshot = variableValueSubscriptionsSnapshot;\r
+                if (snapshot == null) {\r
+                    snapshot = variableValueSubscriptionsSnapshot = variableValueSubscriptions.toArray(new VariableValueSubscription[variableValueSubscriptions.size()]);\r
+                }\r
+            }\r
+            //System.out.println("listener count: " + snapshot.length);\r
+        }\r
+        return snapshot;\r
+    }\r
+    \r
+   volatile long previousVariableUpdateTime = 0;\r
+   volatile boolean skippedVariableUpdate = true;\r
+   \r
+   \r
+    /**\r
+     * Modified copy from AprosExperiment\r
+     */\r
+    public void fireValuesChanged() {\r
+        long time = System.nanoTime(); \r
+        if(time - previousVariableUpdateTime > 100000000) {\r
+            updateSubscriptions();\r
+            previousVariableUpdateTime = time;\r
+        }\r
+        else\r
+            skippedVariableUpdate = true;\r
+    }\r
+\r
+    /**\r
+     * Modified copy from AporsExperiment\r
+     */\r
+    private void updateSubscriptions() {\r
+        for(VariableValueSubscription subscription : getListenerSnapshot())\r
+            subscription.update();\r
+        skippedVariableUpdate = false;\r
+    }\r
 \r
 }\r
 \r
index c6f74ef09f4532690a59108d59679974146ad6bd..1a3cfe713473eeb1b271cb0779809cabd484957b 100644 (file)
@@ -46,6 +46,7 @@ import org.simantics.objmap.IMappingListener;
 import org.simantics.objmap.Mappings;\r
 import org.simantics.simulation.experiment.Experiment;\r
 import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IDynamicExperiment;\r
 import org.simantics.simulation.experiment.IExperiment;\r
 import org.simantics.simulation.model.IModel;\r
 import org.simantics.simulation.ontology.SimulationResource;\r
@@ -467,10 +468,22 @@ public class SysdynModel implements IMappingListener, IModel {
                                e.printStackTrace();\r
                        } \r
                }\r
+               \r
 \r
-               SysdynExperiment exp = new SysdynExperiment(experiment, modelResource);\r
                try {\r
-                       exp.init(g);\r
+                   \r
+                     SysdynResource sr = SysdynResource.getInstance(g);\r
+                       IDynamicExperiment exp;\r
+                       if(g.isInstanceOf(experiment, sr.PlaybackExperiment)) {\r
+                           exp = new SysdynPlaybackExperiment(experiment, modelResource);\r
+                           ((SysdynPlaybackExperiment)exp).init(g);\r
+                       } else if(g.isInstanceOf(experiment, sr.BasicExperiment)) {\r
+                           exp = new SysdynExperiment(experiment, modelResource);\r
+                           ((SysdynExperiment)exp).init(g);\r
+                       } else {\r
+                           return null;\r
+                       }\r
+                       \r
                        ExperimentRuns.createRun(g.getSession(), experiment, exp, listener, null);\r
                        if(listener != null)\r
                                listener.onExperimentActivated(exp);\r
diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java
new file mode 100644 (file)
index 0000000..416ce05
--- /dev/null
@@ -0,0 +1,50 @@
+package org.simantics.sysdyn.manager;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.ReadRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IDynamicExperiment;\r
+import org.simantics.simulation.ontology.SimulationResource;\r
+\r
+public class SysdynPlaybackExperiment extends SysdynExperiment implements IDynamicExperiment {\r
+\r
+    double time;\r
+    public static final long VARIABLE_UPDATE_INTERVAL = 500000000;\r
+    \r
+\r
+    public SysdynPlaybackExperiment(Resource experiment, Resource model) {\r
+        super(experiment, model);\r
+        this.time = 0;\r
+    }\r
+    \r
+    volatile boolean updating = false;\r
+\r
+    \r
+    public void setTime(double time) {\r
+        this.time = time;\r
+        fireValuesChanged(); \r
+    }\r
+    \r
+    public double getTime() {\r
+        return this.time;\r
+    }\r
+    \r
+    @Override\r
+    public void init(ReadGraph g) {\r
+        this.session = g.getSession();\r
+        changeState(ExperimentState.STOPPED);\r
+\r
+        session.asyncRequest(new ReadRequest() {\r
+\r
+            @Override\r
+            public void run(ReadGraph graph) throws DatabaseException {\r
+                final Resource configuration = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration);\r
+                sysdynModel = SysdynModelManager.getInstance(session).getModel(graph, configuration);\r
+                toggleActivation(graph, true);\r
+                startSimulation();\r
+            }\r
+        });\r
+    }\r
+}\r
index fad8674a213c5a140223d94793b5f895604bc2f7..3b41fedae6e5223f7a7bac90da3e060c6f11f93e 100644 (file)
@@ -20,8 +20,8 @@ import java.util.TreeMap;
 \r
 import org.simantics.databoard.Accessors;\r
 import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Datatypes;\r
 import org.simantics.databoard.Files;\r
-import org.simantics.databoard.Historian;\r
 import org.simantics.databoard.accessor.Accessor;\r
 import org.simantics.databoard.accessor.MapAccessor;\r
 import org.simantics.databoard.accessor.RecordAccessor;\r
@@ -83,7 +83,7 @@ public class SysdynResult {
     public void setResult(SimulationResult result) {\r
         try {\r
             // Create Memory Historian\r
-            Datatype recordingSessionType = Historian.getRecordingSessionType();\r
+            Datatype recordingSessionType = Datatypes.getDatatype("RecordingSession");\r
             RecordBinding sessionBinding = (RecordBinding) Bindings.getBinding( recordingSessionType );\r
             RecordBinding recordingBinding = (RecordBinding) Bindings.getBinding( Recording.class );\r
             Object session = sessionBinding.createDefault();  \r