From: lempinen Date: Fri, 14 Oct 2011 07:40:50 +0000 (+0000) Subject: More simulation playback. Results for styles using ExternalRead. X-Git-Tag: simantics-1.5~12 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=c88c2482d650277cb2fe2e7af860f0c407c44323;p=simantics%2Fsysdyn.git More simulation playback. Results for styles using ExternalRead. git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@22737 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.sysdyn.ontology/graph.tg b/org.simantics.sysdyn.ontology/graph.tg index ecd1bceb..a8cc35be 100644 Binary files a/org.simantics.sysdyn.ontology/graph.tg and b/org.simantics.sysdyn.ontology/graph.tg differ diff --git a/org.simantics.sysdyn.ontology/graph/Profiles.pgraph b/org.simantics.sysdyn.ontology/graph/Profiles.pgraph index 63cb5258..40a270f2 100644 --- a/org.simantics.sysdyn.ontology/graph/Profiles.pgraph +++ b/org.simantics.sysdyn.ontology/graph/Profiles.pgraph @@ -13,6 +13,7 @@ groupStyleEntry : L0.Template DIA.ProfileEntry.HasStyle %style DIA.ProfileEntry.HasGroup %group +SYSDYN.SimulationPlaybackProfile { +public class SimulationPlaybackStyle extends StyleBase> { - HashMap timeListeners = new HashMap(); - @Override - public Double calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException { + public Pair calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException { IProject project = SimanticsUI.getProject(); IExperimentManager em = project.getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); @@ -62,26 +63,21 @@ public class SimulationPlaybackStyle extends StyleBase { if(var == null) return null; - Double time = var.getPossiblePropertyValue(graph, Variables.DISPLAY_VALUE, Bindings.DOUBLE); - if(time == null) + Double[] va = var.getPossiblePropertyValue(graph, SysdynVariableProperties.VALUES , Bindings.DOUBLE_ARRAY); + if(va == null || va.length < 2) return null; - - final RecordAccessor acc = var.getInterface(graph, RecordAccessor.class); - if(acc == null) + Double[] ta = var.getPossiblePropertyValue(graph, SysdynVariableProperties.TIMES , Bindings.DOUBLE_ARRAY); + if(ta == null || ta.length < 2) return null; - - ArrayAccessor timeAccessor, valueAccessor; - timeAccessor = acc.getFieldAccessor(1); - valueAccessor = acc.getFieldAccessor(2); - Datatype dt = new org.simantics.databoard.type.ArrayType(new DoubleType()); - - double[] ta = (double[]) timeAccessor.getValue(Bindings.getBinding(dt)); - double[] va = (double[]) valueAccessor.getValue(Bindings.getBinding(dt)); if(va.length == 0 || va.length == 2) return null; + Double time = var.getPossiblePropertyValue(graph, SysdynVariableProperties.TIME , Bindings.DOUBLE); + if(time == null) + return null; + double min = va[0], max = va[0]; for(double d : va) { if(d < min) @@ -104,19 +100,18 @@ public class SimulationPlaybackStyle extends StyleBase { double multiplier = (value - min) / (max - min); -// AffineTransform at = (AffineTransform) DiagramGraphUtil.getAffineTransform(graph, element, G2DResource.getInstance(graph).HasTransform, true).clone(); -// at.translate(0, 10); - return multiplier; + AffineTransform at = (AffineTransform) DiagramGraphUtil.getAffineTransform(graph, element, G2DResource.getInstance(graph).HasTransform, true).clone(); + + return new Pair(at, multiplier); } catch(Exception ignore) { - System.err.println("POIKKEUS SimulationPlaybackStyle"); ignore.printStackTrace(); } return null; } @Override - public void styleResultChanged(Observer observer, Resource element, Double result) { + public void styleResultChanged(Observer observer, Resource element, Pair result) { if (result != null) values.put(element, result); else @@ -125,13 +120,33 @@ public class SimulationPlaybackStyle extends StyleBase { } @Override - public void applyStyleForNode(EvaluationContext observer, INode _node, Double multiplier) { - if (multiplier != null) { - TextNode n = NodeUtil.getNearestChildByClass((SingleElementNode)_node, TextNode.class); - Color c = new Color(multiplier.floatValue(), (float)(0), (float) (1 - multiplier)); + public void applyStyleForNode(EvaluationContext observer, INode _node, Pair result) { + Double multiplier; + if (result != null && (multiplier = result.second) != null && !multiplier.isNaN()) { + + + A node = ProfileVariables.claimChild(_node, "", "playbackColour", A.class, observer); + if (node == null) + return; + + AffineTransform at = result.first; + Color c = new Color(multiplier.floatValue(), (float)(0), (float) (1 - multiplier), (float)0.5); + int zIndex = -1; + INode n = NodeUtil.getNearestChildByClass((SingleElementNode)_node, TextNode.class); if(n != null) { - n.setBackgroundColor(c); + at = ((TextNode)n).getTransform(); + zIndex = ((TextNode)n).getZIndex() - 1; + } else { + n = _node; } + Rectangle2D expandedElementBounds = GeometryUtils.expandRectangle( NodeUtil.getLocalElementBounds(n), 0.0); + node.setZIndex(zIndex); + node.setFill(true); + node.setColor(c); + node.setStroke(null); + node.setValue("shape", expandedElementBounds); + node.setTransform(at); + } else { cleanupStyleForNode(_node); } @@ -139,11 +154,30 @@ public class SimulationPlaybackStyle extends StyleBase { @Override protected void cleanupStyleForNode(INode node) { - if(node instanceof SingleElementNode) { - TextNode n = NodeUtil.getNearestChildByClass((SingleElementNode)node, TextNode.class); - if(n != null) - n.setBackgroundColor(null); + ProfileVariables.denyChild(node, "", "playbackColour"); + } + + + + public static class A extends ShapeNode { + + private static final long serialVersionUID = -5273246617906214956L; + + @Override + public Rectangle2D getBoundsInLocal() { + return null; } + + @Override + public Rectangle2D getBoundsInLocal(boolean b) { + return null; + } + + @Override + public Rectangle2D getBounds() { + return null; + } + } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java index d631a2d5..98b8f65a 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentManagerListener.java @@ -66,10 +66,12 @@ public class SysdynExperimentManagerListener implements IExperimentManagerListen (IContextService)PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getService(IContextService.class); synchronized(contextActivations) { - if(experiment instanceof SysdynPlaybackExperiment) + if(experiment instanceof SysdynPlaybackExperiment) { contextActivations.add(contextService.activateContext(PLAYBACK_EXPERIMENT_CONTEXT)); - else if(experiment instanceof SysdynExperiment) + experiment.addListener(new SysdynPlaybackExperimentListener((SysdynPlaybackExperiment)experiment)); + } else if(experiment instanceof SysdynExperiment) { contextActivations.add(contextService.activateContext(BASIC_EXPERIMENT_CONTEXT)); + } } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java new file mode 100644 index 00000000..cb859ccc --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynPlaybackExperimentListener.java @@ -0,0 +1,215 @@ +package org.simantics.sysdyn.ui.listeners; + +import java.util.Collection; +import java.util.HashMap; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.simantics.db.Resource; +import org.simantics.db.WriteGraph; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.PossibleObjectWithType; +import org.simantics.db.common.request.WriteRequest; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.Simantics; +import org.simantics.db.service.VirtualGraphSupport; +import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.layer0.Layer0; +import org.simantics.project.IProject; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.experiment.IExperimentListener; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.sysdyn.ui.editor.DiagramViewer; +import org.simantics.ui.SimanticsUI; + +public class SysdynPlaybackExperimentListener implements IExperimentListener { + + private Resource model; + + public SysdynPlaybackExperimentListener(SysdynPlaybackExperiment experiment) { + this.model = experiment.getModel(); + activatePlaybackProfile(); + } + + @Override + public void stateChanged(final ExperimentState state) { + switch(state) { + case DISPOSED: + revertPlaybackProfiles(); + break; + } + } + + class DiagramInfo { + public String modelURI = null; + public Resource previousProfile = null; + } + + HashMap previousRuntimeDiagramsAndModelUris = new HashMap(); + + private void activatePlaybackProfile() { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + previousRuntimeDiagramsAndModelUris.clear(); + previousRuntimeDiagramsAndModelUris = getCurrentRuntimeDiagramInfos(); + activatePlaybackProfileRequest(previousRuntimeDiagramsAndModelUris); + } + }); + } + + private void revertPlaybackProfiles() { + + IProject project = SimanticsUI.getProject(); + if(project == null) + return; + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + + if(experiment != null && experiment instanceof SysdynPlaybackExperiment && this.model.equals(experiment.getModel())) + return; + + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + final HashMap runtimeDiagramsAndModelUris = getCurrentRuntimeDiagramInfos(); + + VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class); + Simantics.getSession().asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + + Resource model = SysdynPlaybackExperimentListener.this.model; + if(model == null) + return; + + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + Collection profiles = graph.syncRequest(new ObjectsWithType(model, l0.ConsistsOf, sr.SimulationPlaybackProfile)); + if(profiles.isEmpty()) + return; + + Resource defaultProfile = profiles.iterator().next(); + + HashMap infos = getRuntimesForModel(graph, runtimeDiagramsAndModelUris, model); + for(Resource runtimeDiagram : infos.keySet()) { + Resource previous = null; + if(previousRuntimeDiagramsAndModelUris.containsKey(runtimeDiagram)) { + previous = previousRuntimeDiagramsAndModelUris.get(runtimeDiagram).previousProfile; + } + setProfile(graph, model, runtimeDiagram, previous == null ? defaultProfile : previous); + } + } + }); + + } + }); + } + + /** + * Run in display thread. + * + * @return + */ + private HashMap getCurrentRuntimeDiagramInfos() { + HashMap runtimeDiagramsAndModelUris = new HashMap(); + IWorkbench workBench = PlatformUI.getWorkbench(); + IWorkbenchWindow window = workBench.getActiveWorkbenchWindow(); + IWorkbenchPage[] pages = window.getPages(); + for(IWorkbenchPage page : pages) { + for(IEditorReference reference : page.getEditorReferences()) { + IEditorPart iep = reference.getEditor(false); + if(iep instanceof DiagramViewer) { + DiagramViewer viewer = (DiagramViewer) iep; + Resource runtime = viewer.getRuntime(); + String modelUri = viewer.getResourceInput2().getModelURI(); + DiagramInfo info = new DiagramInfo(); + info.modelURI = modelUri; + runtimeDiagramsAndModelUris.put(runtime, info); + } + } + } + return runtimeDiagramsAndModelUris; + } + + + private HashMap getRuntimesForModel(WriteGraph graph, HashMap allInfos, Resource model) throws DatabaseException { + HashMap runtimeDiagramsAndModelUris = new HashMap(); + for(Resource runtimeDiagram : allInfos.keySet()) { + DiagramInfo di = allInfos.get(runtimeDiagram); + if(di == null) + continue; + Resource m = graph.getPossibleResource(di.modelURI); + if(m == null || !model.equals(m)) + continue; + + runtimeDiagramsAndModelUris.put(runtimeDiagram, di); + } + return runtimeDiagramsAndModelUris; + } + + private void activatePlaybackProfileRequest(final HashMap allDiagramInfos) { + VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class); + Simantics.getSession().asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + + Resource model = SysdynPlaybackExperimentListener.this.model; + if(model == null) + return; + + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource profile = graph.syncRequest(new PossibleObjectWithType(model, l0.ConsistsOf, sr.SimulationPlaybackProfile)); + if(profile == null) + return; + + DiagramResource DIA = DiagramResource.getInstance(graph); + + HashMap infos = getRuntimesForModel(graph, allDiagramInfos, model); + for(Resource runtimeDiagram : infos.keySet()) { + DiagramInfo di = infos.get(runtimeDiagram); + Resource current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile); + if(profile.equals(current)) + continue; + di.previousProfile = current; + setProfile(graph, model, runtimeDiagram, profile); + } + } + }); + } + + + private void setProfile(WriteGraph graph, Resource model, Resource runtimeDiagram, Resource profile) throws DatabaseException { + DiagramResource DIA = DiagramResource.getInstance(graph); + + Resource current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile); + if(profile.equals(current)) return; + + graph.deny(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, current); + graph.claim(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, profile); + + // Set this profile as the default profile for this model + graph.deny(model, DIA.HasActiveProfile); + graph.claim(model, DIA.HasActiveProfile, profile); + + // Set this profile as the default profile for this diagram + Resource configuration = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasConfiguration); + graph.deny(configuration, DIA.HasActiveProfile); + graph.claim(configuration, DIA.HasActiveProfile, profile); + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ProfileEntries.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ProfileEntries.java index 597f07b3..265aed91 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ProfileEntries.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/utils/ProfileEntries.java @@ -10,21 +10,13 @@ import org.simantics.sysdyn.SysdynResource; public class ProfileEntries { - public static Resource createWorkProfile(WriteGraph graph, String name) throws DatabaseException { - - SysdynResource sr = SysdynResource.getInstance(graph); - - return Profiles.createProfile(graph, name, - sr.Profiles_SimulationPlaybackColours); - - } public static void createStandardProfiles(WriteGraph graph, final Resource model) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); DiagramResource DIA = DiagramResource.getInstance(graph); - final Resource a = createWorkProfile(graph, "Simulation Playback"); + final Resource a = createSimulationPlaybackProfile(graph); Resource plain = Profiles.createProfile(graph, "Plain"); @@ -42,5 +34,18 @@ public class ProfileEntries { // }); } + + public static Resource createSimulationPlaybackProfile(WriteGraph graph) + throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + + Resource profile = Profiles.createProfile(graph, "Simulation Playback", + sr.Profiles_SimulationPlaybackColours); + + graph.deny(profile, L0.InstanceOf); + graph.claim(profile, L0.InstanceOf, null, sr.SimulationPlaybackProfile); + return profile; + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/HistoryVariable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/HistoryVariable.java index 76c98f91..7ef3946c 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/HistoryVariable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/HistoryVariable.java @@ -36,6 +36,7 @@ import org.simantics.db.layer0.variable.Variables; import org.simantics.db.procedure.Listener; import org.simantics.db.request.ExternalRead; import org.simantics.layer0.Layer0; +import org.simantics.simulation.experiment.ExperimentState; import org.simantics.simulation.ontology.SimulationResource; import org.simantics.structural.stubs.StructuralResource2; import org.simantics.sysdyn.SysdynResource; @@ -48,7 +49,11 @@ import org.simantics.sysdyn.manager.SysdynResult; public class HistoryVariable extends ChildVariable implements PropertyProvider { + static Boolean DEBUG = false; + SysdynExperiment experiment; + SysdynModel model = null; + String rvi = null; public HistoryVariable(Variable parent, Resource resource) { super(parent, resource); @@ -67,7 +72,8 @@ public class HistoryVariable extends ChildVariable implements PropertyProvider { SysdynResult sr = new SysdynResult(sm.getSimulationResult()); // TODO: copy or not to copy ... String tmp = Variables.getRVI(graph, this); - System.out.println("HistoryVariable rvi='" + tmp + "'"); + if(DEBUG) + System.out.println("HistoryVariable rvi='" + tmp + "'"); final String rvi = tmp.substring(1).replace("/", "."); SysdynDataSet ds = sr.getDataSet(rvi); if(ds == null) ds = new SysdynDataSet("", "", new ArrayList(), new ArrayList()); // We need a dataset, so if not set, create it @@ -77,6 +83,9 @@ public class HistoryVariable extends ChildVariable implements PropertyProvider { sm.addResultListener(new Runnable() { // FIXME: remove listener at some point.. @Override public void run() { + if(HistoryVariable.this.experiment.getState().equals(ExperimentState.DISPOSED)) + return; + SysdynResult sr = new SysdynResult(sm.getSimulationResult()); SysdynDataSet ds = sr.getDataSet(rvi); if(ds == null) return; @@ -157,50 +166,117 @@ public class HistoryVariable extends ChildVariable implements PropertyProvider { @Override - public Variable getPossibleExtraProperty(ReadGraph graph, final String name) throws DatabaseException { - if(Variables.DISPLAY_VALUE.equals(name)) { - return graph.syncRequest(new ParametrizedPrimitiveRead(this) { - VariableValueSubscription subscription; - @Override - public void register(Listener procedure) { - subscription = registerSubscription(this, procedure, name); - } - @Override - public void unregistered() { - unregisterSubscription(subscription); - subscription = null; - } - }); + public Variable getPossibleExtraProperty(ReadGraph graph, String name) throws DatabaseException { + if(SysdynVariableProperties.TIME.equals(name)) { + return graph.syncRequest(new PropertyRequest(this, name)); + } else if(SysdynVariableProperties.VALUES.equals(name) || SysdynVariableProperties.TIMES.equals(name)) { + if(model == null) { + SimulationResource SIMU = SimulationResource.getInstance(graph); + Resource modelResource = Variables.getModel(graph, this); + Resource configuration = graph.getPossibleObject(modelResource, SIMU.HasConfiguration); + model = SysdynModelManager.getInstance(graph.getSession()).getModel(graph, configuration); + } + if(rvi == null) { + rvi = Variables.getRVI(graph, this).substring(1).replace("/", "."); + } + return graph.syncRequest(new PropertyRequest(this, name)); } return super.getPossibleExtraProperty(graph, name); } - + protected VariableValueSubscription registerSubscription(ExternalRead request, Listener procedure, String property) { - if(experiment instanceof SysdynPlaybackExperiment) { + if(SysdynVariableProperties.TIME.equals(property) && experiment instanceof SysdynPlaybackExperiment) { VariableValueSubscription subscription = new VariableValueSubscription(request, this, property, procedure); experiment.addVariableValueSubscription(subscription); subscription.update(); return subscription; - } else { + } else if(SysdynVariableProperties.VALUES.equals(property) && model != null) { + VariableValueSubscription subscription = new VariableValueSubscription(request, this, property, procedure); + model.addVariableValueSubscription(subscription); + subscription.update(); + return subscription; + } else if(SysdynVariableProperties.TIMES.equals(property) && model != null) { + VariableValueSubscription subscription = new VariableValueSubscription(request, this, property, procedure); + model.addVariableValueSubscription(subscription); + subscription.update(); + return subscription; + } else { return null; } - } + } protected void unregisterSubscription(VariableValueSubscription subscription) { subscription.setListener(null); - experiment.removeVariableValueSubscription(subscription); + if(SysdynVariableProperties.TIME.equals(subscription.property)) + experiment.removeVariableValueSubscription(subscription); + else if(SysdynVariableProperties.TIMES.equals(subscription.property) + || SysdynVariableProperties.VALUES.equals(subscription.property)) + model.removeVariableValueSubscription(subscription); } @Override public Variable getProperty(String name) { - if(Variables.DISPLAY_VALUE.equals(name)){ + if(SysdynVariableProperties.TIME.equals(name)){ if(experiment instanceof SysdynPlaybackExperiment) { SysdynPlaybackExperiment exp = (SysdynPlaybackExperiment) experiment; - return new ConstantPropertyVariable(parent, name, exp.getTime(), Datatypes.DOUBLE); + return new ConstantPropertyVariable(this, name, exp.getTime(), Datatypes.DOUBLE); } else { - return new ConstantPropertyVariable(parent, name, 0, Datatypes.DOUBLE); + return new ConstantPropertyVariable(this, name, 0, Datatypes.DOUBLE); } - } + } else if(SysdynVariableProperties.VALUES.equals(name)) { + SysdynResult sr = new SysdynResult(model.getSimulationResult()); + SysdynDataSet ds = sr.getDataSet(rvi); + if(ds == null) + return new ConstantPropertyVariable(this, name, new Double[0], Datatypes.DOUBLE_ARRAY); + else + return new ConstantPropertyVariable(this, name, ds.values.toArray(new Double[ds.values.size()]), Datatypes.DOUBLE_ARRAY); + } else if(SysdynVariableProperties.TIMES.equals(name)) { + SysdynResult sr = new SysdynResult(model.getSimulationResult()); + SysdynDataSet ds = sr.getDataSet(rvi); + if(ds == null) + return new ConstantPropertyVariable(this, name, new Double[0], Datatypes.DOUBLE_ARRAY); + else + return new ConstantPropertyVariable(this, name, ds.times.toArray(new Double[ds.times.size()]), Datatypes.DOUBLE_ARRAY); + } return null; } + + /** + * Class for supporting requests with different property parameters. Equals-method has been modified + * from ParametrizedPrivimiteRead to check also the property value. + * + * @author tlteemu + * + */ + class PropertyRequest extends ParametrizedPrimitiveRead { + + String property; + + public PropertyRequest(Variable parameter, String property) { + super(parameter); + this.property = property; + } + + VariableValueSubscription subscription; + + @Override + public void register(Listener procedure) { + subscription = registerSubscription(this, procedure, property); + } + @Override + public void unregistered() { + unregisterSubscription(subscription); + subscription = null; + } + + @Override + public boolean equals(Object object) { + if(object instanceof PropertyRequest && super.equals(object)) { + return this.property.equals(((PropertyRequest)object).property); + } else { + return super.equals(object); + } + } + + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/SysdynVariableProperties.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/SysdynVariableProperties.java new file mode 100644 index 00000000..102348c9 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/adapter/SysdynVariableProperties.java @@ -0,0 +1,10 @@ +package org.simantics.sysdyn.adapter; + +public class SysdynVariableProperties { + + final public static String VALUE = "VALUE"; + final public static String VALUES = "VALUES"; + final public static String TIME = "TIME"; + final public static String TIMES = "TIMES"; + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java index 1a3cfe71..56bd084a 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java @@ -11,6 +11,8 @@ *******************************************************************************/ package org.simantics.sysdyn.manager; +import gnu.trove.set.hash.THashSet; + import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; @@ -55,6 +57,7 @@ import org.simantics.simulation.project.IExperimentActivationListener; import org.simantics.structural.stubs.StructuralResource2; import org.simantics.sysdyn.Activator; import org.simantics.sysdyn.SysdynResource; +import org.simantics.sysdyn.adapter.VariableValueSubscription; import org.simantics.sysdyn.modelica.ModelicaWriter; import org.simantics.sysdyn.representation.Configuration; import org.simantics.sysdyn.representation.IElement; @@ -91,6 +94,9 @@ public class SysdynModel implements IMappingListener, IModel { new CopyOnWriteArrayList(); private CopyOnWriteArrayList resultListeners = new CopyOnWriteArrayList(); + + protected THashSet variableValueSubscriptions = new THashSet(); + protected volatile VariableValueSubscription[] variableValueSubscriptionsSnapshot = null; @SuppressWarnings("rawtypes") private Map services = new HashMap(); @@ -395,10 +401,11 @@ public class SysdynModel implements IMappingListener, IModel { public void resultChanged() { synchronized(resultListeners) { for(Runnable listener : resultListeners) { - System.out.println("Run resultListener"); listener.run(); } } + + updateSubscriptions(); } public void addModificationListener(Runnable listener) { @@ -568,5 +575,62 @@ public class SysdynModel implements IMappingListener, IModel { } return simulationDir; } + + + + + + /** + * Copy from AprosExperiment + * @param subscription + */ + public void addVariableValueSubscription(VariableValueSubscription subscription) { + assert subscription != null; + synchronized (variableValueSubscriptions) { + //System.out.println("ADD listener " + subscription); + variableValueSubscriptions.add(subscription); + variableValueSubscriptionsSnapshot = null; + } + } + + /** + * Copy from AprosExperiment + * @param subscription + */ + public void removeVariableValueSubscription(VariableValueSubscription subscription) { + assert subscription != null; + synchronized (variableValueSubscriptions) { + //System.out.println("REMOVE listener " + subscription); + variableValueSubscriptions.remove(subscription); + variableValueSubscriptionsSnapshot = null; + } + } + + /** + * Copy from AprosExperiment + * @return + */ + private VariableValueSubscription[] getListenerSnapshot() { + VariableValueSubscription[] snapshot = variableValueSubscriptionsSnapshot; + if (snapshot == null) { + synchronized (variableValueSubscriptions) { + snapshot = variableValueSubscriptionsSnapshot; + if (snapshot == null) { + snapshot = variableValueSubscriptionsSnapshot = variableValueSubscriptions.toArray(new VariableValueSubscription[variableValueSubscriptions.size()]); + } + } + //System.out.println("listener count: " + snapshot.length); + } + return snapshot; + } + + /** + * Modified copy from AporsExperiment + */ + private void updateSubscriptions() { + VariableValueSubscription[] snapShot = getListenerSnapshot(); + for(VariableValueSubscription subscription : snapShot) + subscription.update(); + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java index 416ce05c..870418ea 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java @@ -34,12 +34,11 @@ public class SysdynPlaybackExperiment extends SysdynExperiment implements IDynam @Override public void init(ReadGraph g) { this.session = g.getSession(); - changeState(ExperimentState.STOPPED); - session.asyncRequest(new ReadRequest() { @Override public void run(ReadGraph graph) throws DatabaseException { + changeState(ExperimentState.RUNNING); final Resource configuration = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration); sysdynModel = SysdynModelManager.getInstance(session).getModel(graph, configuration); toggleActivation(graph, true);