SYSDYN.SimulateOnChangeExperiment <T SYSDYN.Experiment
+SYSDYN.PlaybackExperiment <T SYSDYN.Experiment
+
SYSDYN.HasResult <R L0.IsComposedOf
L0.HasRange SYSDYN.Result
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
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
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
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
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
}\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
\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
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
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
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
});\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
--- /dev/null
+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
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
(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
--- /dev/null
+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
\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
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
return Boolean.FALSE;\r
}\r
}\r
- System.out.println("NOTHING");\r
return Boolean.TRUE;\r
}\r
\r
\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
}\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
}\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
\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
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
} 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
--- /dev/null
+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
--- /dev/null
+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
*******************************************************************************/\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
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
}\r
\r
\r
- private void startSimulation() {\r
+ protected void startSimulation() {\r
session.asyncRequest(new ReadRequest() {\r
\r
@Override\r
}\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
// 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
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
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
--- /dev/null
+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
\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
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