DIA.ProfileEntry.HasStyle %style\r
DIA.ProfileEntry.HasGroup %group\r
\r
+SYSDYN.SimulationPlaybackProfile <T DIA.Profile\r
\r
SYSDYN.SimulationPlaybackStyle : DIA.Style\r
\r
public final Resource ShowEnumerationIndexInCharts;\r
public final Resource ShowEnumerationIndexInCharts_Inverse;\r
public final Resource SimulateOnChangeExperiment;\r
+ public final Resource SimulationPlaybackProfile;\r
public final Resource SimulationPlaybackStyle;\r
public final Resource Stock;\r
public final Resource StockExpression;\r
public static final String ShowEnumerationIndexInCharts = "http://www.simantics.org/Sysdyn-1.0/ShowEnumerationIndexInCharts";\r
public static final String ShowEnumerationIndexInCharts_Inverse = "http://www.simantics.org/Sysdyn-1.0/ShowEnumerationIndexInCharts/Inverse";\r
public static final String SimulateOnChangeExperiment = "http://www.simantics.org/Sysdyn-1.0/SimulateOnChangeExperiment";\r
+ public static final String SimulationPlaybackProfile = "http://www.simantics.org/Sysdyn-1.0/SimulationPlaybackProfile";\r
public static final String SimulationPlaybackStyle = "http://www.simantics.org/Sysdyn-1.0/SimulationPlaybackStyle";\r
public static final String Stock = "http://www.simantics.org/Sysdyn-1.0/Stock";\r
public static final String StockExpression = "http://www.simantics.org/Sysdyn-1.0/StockExpression";\r
ShowEnumerationIndexInCharts = getResourceOrNull(graph, URIs.ShowEnumerationIndexInCharts);\r
ShowEnumerationIndexInCharts_Inverse = getResourceOrNull(graph, URIs.ShowEnumerationIndexInCharts_Inverse);\r
SimulateOnChangeExperiment = getResourceOrNull(graph, URIs.SimulateOnChangeExperiment);\r
+ SimulationPlaybackProfile = getResourceOrNull(graph, URIs.SimulationPlaybackProfile);\r
SimulationPlaybackStyle = getResourceOrNull(graph, URIs.SimulationPlaybackStyle);\r
Stock = getResourceOrNull(graph, URIs.Stock);\r
StockExpression = getResourceOrNull(graph, URIs.StockExpression);\r
package org.simantics.sysdyn.ui.elements2.profiles;\r
\r
import java.awt.Color;\r
-import java.util.HashMap;\r
+import java.awt.geom.AffineTransform;\r
+import java.awt.geom.Rectangle2D;\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.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.DiagramResource;\r
+import org.simantics.diagram.stubs.G2DResource;\r
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;\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.simulation.experiment.IExperiment;\r
import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.adapter.SysdynVariableProperties;\r
import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.datastructures.Pair;\r
\r
-public class SimulationPlaybackStyle extends StyleBase<Double> {\r
+public class SimulationPlaybackStyle extends StyleBase<Pair<AffineTransform, Double>> {\r
\r
- HashMap<INode, Runnable> timeListeners = new HashMap<INode, Runnable>();\r
-\r
@Override\r
- public Double calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {\r
+ public Pair<AffineTransform, Double> calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {\r
\r
IProject project = SimanticsUI.getProject();\r
IExperimentManager em = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
if(var == null)\r
return null;\r
\r
- Double time = var.getPossiblePropertyValue(graph, Variables.DISPLAY_VALUE, Bindings.DOUBLE);\r
- if(time == null)\r
+ Double[] va = var.getPossiblePropertyValue(graph, SysdynVariableProperties.VALUES , Bindings.DOUBLE_ARRAY);\r
+ if(va == null || va.length < 2)\r
return null;\r
-\r
\r
- final RecordAccessor acc = var.getInterface(graph, RecordAccessor.class);\r
- if(acc == null) \r
+ Double[] ta = var.getPossiblePropertyValue(graph, SysdynVariableProperties.TIMES , Bindings.DOUBLE_ARRAY);\r
+ if(ta == null || ta.length < 2)\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 time = var.getPossiblePropertyValue(graph, SysdynVariableProperties.TIME , Bindings.DOUBLE);\r
+ if(time == null)\r
+ return null;\r
+ \r
double min = va[0], max = va[0];\r
for(double d : va) {\r
if(d < min) \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
+ AffineTransform at = (AffineTransform) DiagramGraphUtil.getAffineTransform(graph, element, G2DResource.getInstance(graph).HasTransform, true).clone();\r
+ \r
+ return new Pair<AffineTransform, Double>(at, multiplier);\r
\r
} catch(Exception ignore) {\r
- System.err.println("POIKKEUS SimulationPlaybackStyle");\r
ignore.printStackTrace();\r
}\r
return null;\r
}\r
\r
@Override\r
- public void styleResultChanged(Observer observer, Resource element, Double result) {\r
+ public void styleResultChanged(Observer observer, Resource element, Pair<AffineTransform, 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, 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
+ public void applyStyleForNode(EvaluationContext observer, INode _node, Pair<AffineTransform, Double> result) {\r
+ Double multiplier;\r
+ if (result != null && (multiplier = result.second) != null && !multiplier.isNaN()) {\r
+ \r
+ \r
+ A node = ProfileVariables.claimChild(_node, "", "playbackColour", A.class, observer);\r
+ if (node == null)\r
+ return;\r
+\r
+ AffineTransform at = result.first;\r
+ Color c = new Color(multiplier.floatValue(), (float)(0), (float) (1 - multiplier), (float)0.5);\r
+ int zIndex = -1;\r
+ INode n = NodeUtil.getNearestChildByClass((SingleElementNode)_node, TextNode.class);\r
if(n != null) {\r
- n.setBackgroundColor(c);\r
+ at = ((TextNode)n).getTransform();\r
+ zIndex = ((TextNode)n).getZIndex() - 1;\r
+ } else {\r
+ n = _node;\r
}\r
+ Rectangle2D expandedElementBounds = GeometryUtils.expandRectangle( NodeUtil.getLocalElementBounds(n), 0.0);\r
+ node.setZIndex(zIndex);\r
+ node.setFill(true);\r
+ node.setColor(c);\r
+ node.setStroke(null);\r
+ node.setValue("shape", expandedElementBounds);\r
+ node.setTransform(at);\r
+\r
} else {\r
cleanupStyleForNode(_node);\r
}\r
\r
@Override\r
protected void cleanupStyleForNode(INode node) {\r
- if(node instanceof SingleElementNode) {\r
- TextNode n = NodeUtil.getNearestChildByClass((SingleElementNode)node, TextNode.class);\r
- if(n != null)\r
- n.setBackgroundColor(null);\r
+ ProfileVariables.denyChild(node, "", "playbackColour");\r
+ }\r
+ \r
+ \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
}\r
(IContextService)PlatformUI.getWorkbench()\r
.getActiveWorkbenchWindow().getService(IContextService.class);\r
synchronized(contextActivations) {\r
- if(experiment instanceof SysdynPlaybackExperiment)\r
+ if(experiment instanceof SysdynPlaybackExperiment) {\r
contextActivations.add(contextService.activateContext(PLAYBACK_EXPERIMENT_CONTEXT));\r
- else if(experiment instanceof SysdynExperiment)\r
+ experiment.addListener(new SysdynPlaybackExperimentListener((SysdynPlaybackExperiment)experiment));\r
+ } else if(experiment instanceof SysdynExperiment) {\r
contextActivations.add(contextService.activateContext(BASIC_EXPERIMENT_CONTEXT));\r
+ }\r
}\r
}\r
\r
--- /dev/null
+package org.simantics.sysdyn.ui.listeners;\r
+\r
+import java.util.Collection;\r
+import java.util.HashMap;\r
+\r
+import org.eclipse.ui.IEditorPart;\r
+import org.eclipse.ui.IEditorReference;\r
+import org.eclipse.ui.IWorkbench;\r
+import org.eclipse.ui.IWorkbenchPage;\r
+import org.eclipse.ui.IWorkbenchWindow;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.PossibleObjectWithType;\r
+import org.simantics.db.common.request.WriteRequest;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.Simantics;\r
+import org.simantics.db.service.VirtualGraphSupport;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.experiment.ExperimentState;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.experiment.IExperimentListener;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
+import org.simantics.sysdyn.ui.editor.DiagramViewer;\r
+import org.simantics.ui.SimanticsUI;\r
+\r
+public class SysdynPlaybackExperimentListener implements IExperimentListener {\r
+\r
+ private Resource model;\r
+\r
+ public SysdynPlaybackExperimentListener(SysdynPlaybackExperiment experiment) {\r
+ this.model = experiment.getModel();\r
+ activatePlaybackProfile();\r
+ }\r
+\r
+ @Override\r
+ public void stateChanged(final ExperimentState state) {\r
+ switch(state) {\r
+ case DISPOSED:\r
+ revertPlaybackProfiles();\r
+ break;\r
+ }\r
+ }\r
+\r
+ class DiagramInfo {\r
+ public String modelURI = null;\r
+ public Resource previousProfile = null;\r
+ }\r
+\r
+ HashMap<Resource, DiagramInfo> previousRuntimeDiagramsAndModelUris = new HashMap<Resource, DiagramInfo>(); \r
+\r
+ private void activatePlaybackProfile() {\r
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ previousRuntimeDiagramsAndModelUris.clear();\r
+ previousRuntimeDiagramsAndModelUris = getCurrentRuntimeDiagramInfos();\r
+ activatePlaybackProfileRequest(previousRuntimeDiagramsAndModelUris);\r
+ }\r
+ });\r
+ }\r
+ \r
+ private void revertPlaybackProfiles() {\r
+ \r
+ IProject project = SimanticsUI.getProject();\r
+ if(project == null)\r
+ return;\r
+ IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
+ IExperiment experiment = manager.getActiveExperiment();\r
+ \r
+ if(experiment != null && experiment instanceof SysdynPlaybackExperiment && this.model.equals(experiment.getModel()))\r
+ return;\r
+ \r
+ PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
+\r
+ @Override\r
+ public void run() {\r
+ final HashMap<Resource, DiagramInfo> runtimeDiagramsAndModelUris = getCurrentRuntimeDiagramInfos();\r
+\r
+ VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);\r
+ Simantics.getSession().asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ \r
+ Resource model = SysdynPlaybackExperimentListener.this.model;\r
+ if(model == null)\r
+ return;\r
+ \r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ \r
+ Collection<Resource> profiles = graph.syncRequest(new ObjectsWithType(model, l0.ConsistsOf, sr.SimulationPlaybackProfile));\r
+ if(profiles.isEmpty())\r
+ return;\r
+ \r
+ Resource defaultProfile = profiles.iterator().next();\r
+ \r
+ HashMap<Resource, DiagramInfo> infos = getRuntimesForModel(graph, runtimeDiagramsAndModelUris, model);\r
+ for(Resource runtimeDiagram : infos.keySet()) {\r
+ Resource previous = null;\r
+ if(previousRuntimeDiagramsAndModelUris.containsKey(runtimeDiagram)) {\r
+ previous = previousRuntimeDiagramsAndModelUris.get(runtimeDiagram).previousProfile;\r
+ }\r
+ setProfile(graph, model, runtimeDiagram, previous == null ? defaultProfile : previous);\r
+ }\r
+ }\r
+ });\r
+ \r
+ }\r
+ });\r
+ }\r
+ \r
+ /**\r
+ * Run in display thread.\r
+ * \r
+ * @return\r
+ */\r
+ private HashMap<Resource, DiagramInfo> getCurrentRuntimeDiagramInfos() {\r
+ HashMap<Resource, DiagramInfo> runtimeDiagramsAndModelUris = new HashMap<Resource, DiagramInfo>(); \r
+ IWorkbench workBench = PlatformUI.getWorkbench();\r
+ IWorkbenchWindow window = workBench.getActiveWorkbenchWindow();\r
+ IWorkbenchPage[] pages = window.getPages();\r
+ for(IWorkbenchPage page : pages) {\r
+ for(IEditorReference reference : page.getEditorReferences()) {\r
+ IEditorPart iep = reference.getEditor(false);\r
+ if(iep instanceof DiagramViewer) {\r
+ DiagramViewer viewer = (DiagramViewer) iep;\r
+ Resource runtime = viewer.getRuntime();\r
+ String modelUri = viewer.getResourceInput2().getModelURI();\r
+ DiagramInfo info = new DiagramInfo();\r
+ info.modelURI = modelUri;\r
+ runtimeDiagramsAndModelUris.put(runtime, info);\r
+ }\r
+ }\r
+ }\r
+ return runtimeDiagramsAndModelUris;\r
+ }\r
+ \r
+ \r
+ private HashMap<Resource, DiagramInfo> getRuntimesForModel(WriteGraph graph, HashMap<Resource, DiagramInfo> allInfos, Resource model) throws DatabaseException {\r
+ HashMap<Resource, DiagramInfo> runtimeDiagramsAndModelUris = new HashMap<Resource, DiagramInfo>(); \r
+ for(Resource runtimeDiagram : allInfos.keySet()) {\r
+ DiagramInfo di = allInfos.get(runtimeDiagram);\r
+ if(di == null)\r
+ continue;\r
+ Resource m = graph.getPossibleResource(di.modelURI);\r
+ if(m == null || !model.equals(m)) \r
+ continue;\r
+ \r
+ runtimeDiagramsAndModelUris.put(runtimeDiagram, di);\r
+ }\r
+ return runtimeDiagramsAndModelUris;\r
+ }\r
+ \r
+ private void activatePlaybackProfileRequest(final HashMap<Resource, DiagramInfo> allDiagramInfos) {\r
+ VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);\r
+ Simantics.getSession().asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {\r
+ \r
+ @Override\r
+ public void perform(WriteGraph graph) throws DatabaseException {\r
+ \r
+ Resource model = SysdynPlaybackExperimentListener.this.model;\r
+ if(model == null)\r
+ return;\r
+ \r
+ Layer0 l0 = Layer0.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ \r
+ Resource profile = graph.syncRequest(new PossibleObjectWithType(model, l0.ConsistsOf, sr.SimulationPlaybackProfile));\r
+ if(profile == null)\r
+ return;\r
+ \r
+ DiagramResource DIA = DiagramResource.getInstance(graph);\r
+\r
+ HashMap<Resource, DiagramInfo> infos = getRuntimesForModel(graph, allDiagramInfos, model);\r
+ for(Resource runtimeDiagram : infos.keySet()) {\r
+ DiagramInfo di = infos.get(runtimeDiagram);\r
+ Resource current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile);\r
+ if(profile.equals(current)) \r
+ continue;\r
+ di.previousProfile = current;\r
+ setProfile(graph, model, runtimeDiagram, profile);\r
+ }\r
+ }\r
+ });\r
+ }\r
+ \r
+ \r
+ private void setProfile(WriteGraph graph, Resource model, Resource runtimeDiagram, Resource profile) throws DatabaseException {\r
+ DiagramResource DIA = DiagramResource.getInstance(graph);\r
+\r
+ Resource current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile);\r
+ if(profile.equals(current)) return;\r
+ \r
+ graph.deny(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, current);\r
+ graph.claim(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, profile);\r
+\r
+ // Set this profile as the default profile for this model\r
+ graph.deny(model, DIA.HasActiveProfile);\r
+ graph.claim(model, DIA.HasActiveProfile, profile);\r
+ \r
+ // Set this profile as the default profile for this diagram\r
+ Resource configuration = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasConfiguration);\r
+ graph.deny(configuration, DIA.HasActiveProfile);\r
+ graph.claim(configuration, DIA.HasActiveProfile, profile);\r
+ }\r
+ \r
+}\r
\r
public class ProfileEntries {\r
\r
- public static Resource createWorkProfile(WriteGraph graph, String name) throws DatabaseException {\r
-\r
- SysdynResource sr = SysdynResource.getInstance(graph);\r
- \r
- return Profiles.createProfile(graph, name,\r
- sr.Profiles_SimulationPlaybackColours);\r
-\r
- }\r
\r
public static void createStandardProfiles(WriteGraph graph, final Resource model) throws DatabaseException {\r
\r
Layer0 L0 = Layer0.getInstance(graph);\r
DiagramResource DIA = DiagramResource.getInstance(graph);\r
\r
- final Resource a = createWorkProfile(graph, "Simulation Playback");\r
+ final Resource a = createSimulationPlaybackProfile(graph);\r
\r
Resource plain = Profiles.createProfile(graph, "Plain");\r
\r
// });\r
\r
}\r
+ \r
+ public static Resource createSimulationPlaybackProfile(WriteGraph graph)\r
+ throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ SysdynResource sr = SysdynResource.getInstance(graph);\r
+ \r
+ Resource profile = Profiles.createProfile(graph, "Simulation Playback",\r
+ sr.Profiles_SimulationPlaybackColours);\r
+ \r
+ graph.deny(profile, L0.InstanceOf);\r
+ graph.claim(profile, L0.InstanceOf, null, sr.SimulationPlaybackProfile);\r
+ return profile;\r
+ }\r
\r
}\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.experiment.ExperimentState;\r
import org.simantics.simulation.ontology.SimulationResource;\r
import org.simantics.structural.stubs.StructuralResource2;\r
import org.simantics.sysdyn.SysdynResource;\r
\r
public class HistoryVariable extends ChildVariable implements PropertyProvider {\r
\r
+ static Boolean DEBUG = false;\r
+ \r
SysdynExperiment experiment;\r
+ SysdynModel model = null;\r
+ String rvi = null;\r
\r
public HistoryVariable(Variable parent, Resource resource) {\r
super(parent, resource);\r
SysdynResult sr = new SysdynResult(sm.getSimulationResult()); // TODO: copy or not to copy ...\r
\r
String tmp = Variables.getRVI(graph, this);\r
- System.out.println("HistoryVariable rvi='" + tmp + "'");\r
+ if(DEBUG)\r
+ System.out.println("HistoryVariable rvi='" + tmp + "'");\r
final String rvi = tmp.substring(1).replace("/", ".");\r
SysdynDataSet ds = sr.getDataSet(rvi);\r
if(ds == null) ds = new SysdynDataSet("", "", new ArrayList<Double>(), new ArrayList<Double>()); // We need a dataset, so if not set, create it\r
sm.addResultListener(new Runnable() { // FIXME: remove listener at some point..\r
@Override\r
public void run() {\r
+ if(HistoryVariable.this.experiment.getState().equals(ExperimentState.DISPOSED))\r
+ return;\r
+ \r
SysdynResult sr = new SysdynResult(sm.getSimulationResult());\r
SysdynDataSet ds = sr.getDataSet(rvi);\r
if(ds == null) return;\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
+ public Variable getPossibleExtraProperty(ReadGraph graph, String name) throws DatabaseException {\r
+ if(SysdynVariableProperties.TIME.equals(name)) {\r
+ return graph.syncRequest(new PropertyRequest(this, name));\r
+ } else if(SysdynVariableProperties.VALUES.equals(name) || SysdynVariableProperties.TIMES.equals(name)) {\r
+ if(model == null) {\r
+ SimulationResource SIMU = SimulationResource.getInstance(graph);\r
+ Resource modelResource = Variables.getModel(graph, this);\r
+ Resource configuration = graph.getPossibleObject(modelResource, SIMU.HasConfiguration);\r
+ model = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configuration);\r
+ }\r
+ if(rvi == null) {\r
+ rvi = Variables.getRVI(graph, this).substring(1).replace("/", ".");\r
+ }\r
+ return graph.syncRequest(new PropertyRequest(this, name));\r
}\r
return super.getPossibleExtraProperty(graph, name);\r
}\r
-\r
+ \r
protected VariableValueSubscription registerSubscription(ExternalRead<?> request, Listener<Variable> procedure, String property) {\r
- if(experiment instanceof SysdynPlaybackExperiment) {\r
+ if(SysdynVariableProperties.TIME.equals(property) && 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
+ } else if(SysdynVariableProperties.VALUES.equals(property) && model != null) {\r
+ VariableValueSubscription subscription = new VariableValueSubscription(request, this, property, procedure);\r
+ model.addVariableValueSubscription(subscription);\r
+ subscription.update();\r
+ return subscription;\r
+ } else if(SysdynVariableProperties.TIMES.equals(property) && model != null) {\r
+ VariableValueSubscription subscription = new VariableValueSubscription(request, this, property, procedure);\r
+ model.addVariableValueSubscription(subscription);\r
+ subscription.update();\r
+ return subscription;\r
+ } else {\r
return null;\r
}\r
- }\r
+ }\r
\r
protected void unregisterSubscription(VariableValueSubscription subscription) {\r
subscription.setListener(null);\r
- experiment.removeVariableValueSubscription(subscription);\r
+ if(SysdynVariableProperties.TIME.equals(subscription.property))\r
+ experiment.removeVariableValueSubscription(subscription);\r
+ else if(SysdynVariableProperties.TIMES.equals(subscription.property) \r
+ || SysdynVariableProperties.VALUES.equals(subscription.property))\r
+ model.removeVariableValueSubscription(subscription);\r
}\r
\r
@Override\r
public Variable getProperty(String name) {\r
- if(Variables.DISPLAY_VALUE.equals(name)){\r
+ if(SysdynVariableProperties.TIME.equals(name)){\r
if(experiment instanceof SysdynPlaybackExperiment) {\r
SysdynPlaybackExperiment exp = (SysdynPlaybackExperiment) experiment;\r
- return new ConstantPropertyVariable(parent, name, exp.getTime(), Datatypes.DOUBLE);\r
+ return new ConstantPropertyVariable(this, name, exp.getTime(), Datatypes.DOUBLE);\r
} else {\r
- return new ConstantPropertyVariable(parent, name, 0, Datatypes.DOUBLE);\r
+ return new ConstantPropertyVariable(this, name, 0, Datatypes.DOUBLE);\r
}\r
- } \r
+ } else if(SysdynVariableProperties.VALUES.equals(name)) {\r
+ SysdynResult sr = new SysdynResult(model.getSimulationResult());\r
+ SysdynDataSet ds = sr.getDataSet(rvi);\r
+ if(ds == null)\r
+ return new ConstantPropertyVariable(this, name, new Double[0], Datatypes.DOUBLE_ARRAY);\r
+ else\r
+ return new ConstantPropertyVariable(this, name, ds.values.toArray(new Double[ds.values.size()]), Datatypes.DOUBLE_ARRAY);\r
+ } else if(SysdynVariableProperties.TIMES.equals(name)) {\r
+ SysdynResult sr = new SysdynResult(model.getSimulationResult());\r
+ SysdynDataSet ds = sr.getDataSet(rvi);\r
+ if(ds == null)\r
+ return new ConstantPropertyVariable(this, name, new Double[0], Datatypes.DOUBLE_ARRAY);\r
+ else\r
+ return new ConstantPropertyVariable(this, name, ds.times.toArray(new Double[ds.times.size()]), Datatypes.DOUBLE_ARRAY);\r
+ }\r
return null;\r
}\r
+ \r
+ /**\r
+ * Class for supporting requests with different property parameters. Equals-method has been modified \r
+ * from ParametrizedPrivimiteRead to check also the property value.\r
+ * \r
+ * @author tlteemu\r
+ *\r
+ */\r
+ class PropertyRequest extends ParametrizedPrimitiveRead<Variable, Variable> {\r
+\r
+ String property;\r
+ \r
+ public PropertyRequest(Variable parameter, String property) {\r
+ super(parameter);\r
+ this.property = property;\r
+ }\r
+\r
+ VariableValueSubscription subscription;\r
+ \r
+ @Override\r
+ public void register(Listener<Variable> procedure) {\r
+ subscription = registerSubscription(this, procedure, property);\r
+ }\r
+ @Override\r
+ public void unregistered() {\r
+ unregisterSubscription(subscription);\r
+ subscription = null;\r
+ }\r
+ \r
+ @Override\r
+ public boolean equals(Object object) {\r
+ if(object instanceof PropertyRequest && super.equals(object)) {\r
+ return this.property.equals(((PropertyRequest)object).property);\r
+ } else {\r
+ return super.equals(object);\r
+ }\r
+ }\r
+ \r
+ }\r
}\r
--- /dev/null
+package org.simantics.sysdyn.adapter;\r
+\r
+public class SysdynVariableProperties {\r
+ \r
+ final public static String VALUE = "VALUE";\r
+ final public static String VALUES = "VALUES";\r
+ final public static String TIME = "TIME";\r
+ final public static String TIMES = "TIMES";\r
+\r
+}\r
*******************************************************************************/\r
package org.simantics.sysdyn.manager;\r
\r
+import gnu.trove.set.hash.THashSet;\r
+\r
import java.io.BufferedReader;\r
import java.io.File;\r
import java.io.FileNotFoundException;\r
import org.simantics.structural.stubs.StructuralResource2;\r
import org.simantics.sysdyn.Activator;\r
import org.simantics.sysdyn.SysdynResource;\r
+import org.simantics.sysdyn.adapter.VariableValueSubscription;\r
import org.simantics.sysdyn.modelica.ModelicaWriter;\r
import org.simantics.sysdyn.representation.Configuration;\r
import org.simantics.sysdyn.representation.IElement;\r
new CopyOnWriteArrayList<Runnable>();\r
private CopyOnWriteArrayList<Runnable> resultListeners =\r
new CopyOnWriteArrayList<Runnable>();\r
+ \r
+ protected THashSet<VariableValueSubscription> variableValueSubscriptions = new THashSet<VariableValueSubscription>();\r
+ protected volatile VariableValueSubscription[] variableValueSubscriptionsSnapshot = null;\r
\r
@SuppressWarnings("rawtypes")\r
private Map<Class, Object> services = new HashMap<Class, Object>();\r
public void resultChanged() {\r
synchronized(resultListeners) {\r
for(Runnable listener : resultListeners) {\r
- System.out.println("Run resultListener");\r
listener.run();\r
}\r
}\r
+ \r
+ updateSubscriptions();\r
}\r
\r
public void addModificationListener(Runnable listener) {\r
}\r
return simulationDir;\r
}\r
+ \r
+ \r
+ \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
+ /**\r
+ * Modified copy from AporsExperiment\r
+ */\r
+ private void updateSubscriptions() {\r
+ VariableValueSubscription[] snapShot = getListenerSnapshot();\r
+ for(VariableValueSubscription subscription : snapShot)\r
+ subscription.update();\r
+ }\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
+ changeState(ExperimentState.RUNNING);\r
final Resource configuration = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration);\r
sysdynModel = SysdynModelManager.getInstance(session).getModel(graph, configuration);\r
toggleActivation(graph, true);\r