From: lempinen Date: Thu, 20 Oct 2011 09:10:22 +0000 (+0000) Subject: Controls for simulation playback X-Git-Tag: simantics-1.5~6 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=dd7ee2fd1dcd61369ba6f721e2b5826e304f323a;p=simantics%2Fsysdyn.git Controls for simulation playback git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@22888 ac1ea38d-2e2b-0410-8846-a27921b304fc --- diff --git a/org.simantics.sysdyn.ui/icons/control_fastforward.png b/org.simantics.sysdyn.ui/icons/control_fastforward.png new file mode 100644 index 00000000..31f7fd3a Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_fastforward.png differ diff --git a/org.simantics.sysdyn.ui/icons/control_fastforward_blue.png b/org.simantics.sysdyn.ui/icons/control_fastforward_blue.png new file mode 100644 index 00000000..4a2f9d4e Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_fastforward_blue.png differ diff --git a/org.simantics.sysdyn.ui/icons/control_pause.png b/org.simantics.sysdyn.ui/icons/control_pause.png new file mode 100644 index 00000000..2d9ce9c4 Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_pause.png differ diff --git a/org.simantics.sysdyn.ui/icons/control_pause_blue.png b/org.simantics.sysdyn.ui/icons/control_pause_blue.png new file mode 100644 index 00000000..ec61099b Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_pause_blue.png differ diff --git a/org.simantics.sysdyn.ui/icons/control_play.png b/org.simantics.sysdyn.ui/icons/control_play.png new file mode 100644 index 00000000..0846555d Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_play.png differ diff --git a/org.simantics.sysdyn.ui/icons/control_play_blue.png b/org.simantics.sysdyn.ui/icons/control_play_blue.png new file mode 100644 index 00000000..f8c8ec68 Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_play_blue.png differ diff --git a/org.simantics.sysdyn.ui/icons/control_step.png b/org.simantics.sysdyn.ui/icons/control_step.png new file mode 100644 index 00000000..820b020d Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_step.png differ diff --git a/org.simantics.sysdyn.ui/icons/control_step_blue.png b/org.simantics.sysdyn.ui/icons/control_step_blue.png new file mode 100644 index 00000000..98071cc0 Binary files /dev/null and b/org.simantics.sysdyn.ui/icons/control_step_blue.png differ diff --git a/org.simantics.sysdyn.ui/plugin.xml b/org.simantics.sysdyn.ui/plugin.xml index a9237d57..0f62b299 100644 --- a/org.simantics.sysdyn.ui/plugin.xml +++ b/org.simantics.sysdyn.ui/plugin.xml @@ -278,6 +278,46 @@ + + + + + + + + + + + + + + + + + + + + @@ -294,6 +334,25 @@ + + + + + + + + + + + + + + + + + + @@ -756,6 +837,31 @@ id="org.simantics.sysdyn.ui.newPlaybackExperiment" name="New Playback Experiment"> + + + + + + + + + + diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/profiles/SimulationPlaybackStyle.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/profiles/SimulationPlaybackStyle.java index 1dd87165..8a68153a 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/profiles/SimulationPlaybackStyle.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/profiles/SimulationPlaybackStyle.java @@ -100,10 +100,10 @@ public class SimulationPlaybackStyle extends StyleBase ta[ta.length / 2] ) { index = ta.length - 1; - while(ta[index] > time) + while(ta[index] > time && index > 0) index--; } else { - while(ta[index] < time) + while(ta[index] < time && index < ta.length - 1) index++; } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/FastSpeedHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/FastSpeedHandler.java new file mode 100644 index 00000000..d98a44ec --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/FastSpeedHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; + +public class FastSpeedHandler extends SpeedHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setPlaybackSpeed(SysdynPlaybackExperiment.DURATION_FAST); + return null; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/NormalSpeedHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/NormalSpeedHandler.java new file mode 100644 index 00000000..b2ece4d6 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/NormalSpeedHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; + +public class NormalSpeedHandler extends SpeedHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setPlaybackSpeed(SysdynPlaybackExperiment.DURATION_NORMAL); + return null; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackExperimentHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackExperimentHandler.java new file mode 100644 index 00000000..72ae6ec7 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackExperimentHandler.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.sysdyn.ui.Activator; +import org.simantics.ui.SimanticsUI; + +public class PlaybackExperimentHandler extends AbstractHandler implements IElementUpdater { + + public static final String COMMAND = "org.simantics.sysdyn.ui.playback"; + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return null; + SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + if(!spe.isPlaybackRunning()) + spe.startPlayback(); + else + spe.stopPlayback(); + return null; + } + + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return; + SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + + ExperimentState state = experiment.getState(); + if(state == ExperimentState.RUNNING && !spe.isPlaybackRunning()) { + // RUNNING == simulation, not playback + this.setBaseEnabled(false); + } else { + this.setBaseEnabled(true); + } + + if(spe.isPlaybackRunning()) { + element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_pause.png"))); + element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_pause_blue.png"))); + } else { + long duration = spe.getPlaybackDuration(); + if(duration == SysdynPlaybackExperiment.DURATION_SLOW) { + element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_step.png"))); + element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_step_blue.png"))); + } else if(duration == SysdynPlaybackExperiment.DURATION_FAST) { + element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_fastforward.png"))); + element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_fastforward_blue.png"))); + } else { + element.setIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_play.png"))); + element.setHoverIcon(ImageDescriptor.createFromURL(Activator.getDefault().getBundle().getResource("icons/control_play_blue.png"))); + } + } + } +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackResetHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackResetHandler.java new file mode 100644 index 00000000..e4155b67 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/PlaybackResetHandler.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import java.util.Map; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.commands.IElementUpdater; +import org.eclipse.ui.menus.UIElement; +import org.simantics.simulation.experiment.ExperimentState; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.ui.SimanticsUI; + +public class PlaybackResetHandler extends AbstractHandler implements IElementUpdater { + + public static final String COMMAND = "org.simantics.sysdyn.ui.playbackReset"; + + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return null; + SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + spe.resetPlayback(); + return null; + } + + @SuppressWarnings("rawtypes") + @Override + public void updateElement(UIElement element, Map parameters) { + IExperimentManager manager = + SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return; + SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + + ExperimentState state = experiment.getState(); + if(state == ExperimentState.RUNNING && !spe.isPlaybackRunning()) { + // RUNNING == simulation, not playback + this.setBaseEnabled(false); + } else { + this.setBaseEnabled(true); + } + + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SlowSpeedHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SlowSpeedHandler.java new file mode 100644 index 00000000..6ebeba33 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SlowSpeedHandler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; + +public class SlowSpeedHandler extends SpeedHandler { + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + setPlaybackSpeed(SysdynPlaybackExperiment.DURATION_SLOW); + return null; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SpeedHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SpeedHandler.java new file mode 100644 index 00000000..4fe96910 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/simulationPlayback/SpeedHandler.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.handlers.simulationPlayback; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.simantics.simulation.experiment.IExperiment; +import org.simantics.simulation.project.IExperimentManager; +import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; +import org.simantics.ui.SimanticsUI; + +abstract class SpeedHandler extends AbstractHandler { + + protected void setPlaybackSpeed(long duration) { + + + IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER); + IExperiment experiment = manager.getActiveExperiment(); + if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) + return; + final SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; + + if(spe.getPlaybackDuration() == duration) + return; + + + spe.setPlaybackDuration(duration); + + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + ICommandService commandService = + (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); + commandService.refreshElements(PlaybackExperimentHandler.COMMAND, null); + } + }); + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentListener.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentListener.java index 44406261..04507781 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentListener.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/listeners/SysdynExperimentListener.java @@ -20,6 +20,8 @@ import org.simantics.simulation.experiment.ExperimentState; import org.simantics.simulation.experiment.IExperimentListener; import org.simantics.sysdyn.ui.handlers.RunBasicExperiment; import org.simantics.sysdyn.ui.handlers.ToggleSimulation; +import org.simantics.sysdyn.ui.handlers.simulationPlayback.PlaybackExperimentHandler; +import org.simantics.sysdyn.ui.handlers.simulationPlayback.PlaybackResetHandler; public class SysdynExperimentListener implements IExperimentListener { @@ -43,6 +45,8 @@ public class SysdynExperimentListener implements IExperimentListener { } commandService.refreshElements(command.getId(), null); commandService.refreshElements(RunBasicExperiment.COMMAND, null); + commandService.refreshElements(PlaybackExperimentHandler.COMMAND, null); + commandService.refreshElements(PlaybackResetHandler.COMMAND, null); } }); 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 index cb859ccc..50bd0480 100644 --- 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 @@ -1,6 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ package org.simantics.sysdyn.ui.listeners; -import java.util.Collection; import java.util.HashMap; import org.eclipse.ui.IEditorPart; @@ -11,18 +21,19 @@ 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.profile.Profiles; 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.ontology.SimulationResource; import org.simantics.simulation.project.IExperimentManager; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.manager.SysdynPlaybackExperiment; @@ -32,6 +43,7 @@ import org.simantics.ui.SimanticsUI; public class SysdynPlaybackExperimentListener implements IExperimentListener { private Resource model; + private Resource previousProfile; public SysdynPlaybackExperimentListener(SysdynPlaybackExperiment experiment) { this.model = experiment.getModel(); @@ -96,11 +108,11 @@ public class SysdynPlaybackExperimentListener implements IExperimentListener { Layer0 l0 = Layer0.getInstance(graph); SysdynResource sr = SysdynResource.getInstance(graph); - Collection profiles = graph.syncRequest(new ObjectsWithType(model, l0.ConsistsOf, sr.SimulationPlaybackProfile)); - if(profiles.isEmpty()) + Resource defaultProfile = graph.syncRequest(new PossibleObjectWithType(model, l0.ConsistsOf, sr.DefaultProfile)); + if(defaultProfile == null) return; - Resource defaultProfile = profiles.iterator().next(); + setProfileForModel(graph, model, previousProfile == null ? defaultProfile : previousProfile); HashMap infos = getRuntimesForModel(graph, runtimeDiagramsAndModelUris, model); for(Resource runtimeDiagram : infos.keySet()) { @@ -108,7 +120,7 @@ public class SysdynPlaybackExperimentListener implements IExperimentListener { if(previousRuntimeDiagramsAndModelUris.containsKey(runtimeDiagram)) { previous = previousRuntimeDiagramsAndModelUris.get(runtimeDiagram).previousProfile; } - setProfile(graph, model, runtimeDiagram, previous == null ? defaultProfile : previous); + setProfileForDiagram(graph, runtimeDiagram, previous == null ? defaultProfile : previous); } } }); @@ -170,30 +182,34 @@ public class SysdynPlaybackExperimentListener implements IExperimentListener { 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)); + Resource profile = getSimulationPlaybackProfile(graph, model); if(profile == null) return; DiagramResource DIA = DiagramResource.getInstance(graph); + Resource current = graph.getPossibleObject(model, DIA.HasActiveProfile); + previousProfile = current; + + if(!profile.equals(current)) { + setProfileForModel(graph, model, profile); + } + HashMap infos = getRuntimesForModel(graph, allDiagramInfos, model); for(Resource runtimeDiagram : infos.keySet()) { DiagramInfo di = infos.get(runtimeDiagram); - Resource current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile); + current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile); + di.previousProfile = current; if(profile.equals(current)) continue; - di.previousProfile = current; - setProfile(graph, model, runtimeDiagram, profile); + setProfileForDiagram(graph, runtimeDiagram, profile); } } }); } - private void setProfile(WriteGraph graph, Resource model, Resource runtimeDiagram, Resource profile) throws DatabaseException { + private void setProfileForDiagram(WriteGraph graph, Resource runtimeDiagram, Resource profile) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(graph); Resource current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile); @@ -202,14 +218,38 @@ public class SysdynPlaybackExperimentListener implements IExperimentListener { 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); } + private void setProfileForModel(WriteGraph graph, Resource model, Resource profile) throws DatabaseException { + DiagramResource DIA = DiagramResource.getInstance(graph); + + // Set this profile as the default profile for this model + graph.deny(model, DIA.HasActiveProfile); + graph.claim(model, DIA.HasActiveProfile, profile); + } + + private Resource getSimulationPlaybackProfile(WriteGraph graph, Resource model) throws DatabaseException { + Layer0 l0 = Layer0.getInstance(graph); + SysdynResource sr = SysdynResource.getInstance(graph); + SimulationResource SIMU = SimulationResource.getInstance(graph); + + Resource profile = graph.syncRequest(new PossibleObjectWithType(model, l0.ConsistsOf, sr.SimulationPlaybackProfile)); + if(profile == null) { + profile = Profiles.createProfile(graph, "Simulation Playback", sr.Profiles_SimulationPlaybackColours); + graph.deny(profile, l0.InstanceOf); + graph.claim(profile, l0.InstanceOf, null, sr.SimulationPlaybackProfile); + graph.claim(model, l0.ConsistsOf, profile); + } + + if(!graph.hasStatement(profile, SIMU.IsActive)) { + graph.claim(profile, SIMU.IsActive, sr.Profiles_SimulationPlaybackColours); + } + + return profile; + } + } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java index 04596c12..e589c31d 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/menu/PlaybackSliderContribution.java @@ -23,6 +23,11 @@ import org.simantics.ui.SimanticsUI; public class PlaybackSliderContribution extends ToolBarContributionItem { + Runnable timeListener; + SysdynPlaybackExperiment spe; + Slider s; + Double startTime, endTime; + boolean ignoreChange = false; @Override public void fill(ToolBar parent, int index) @@ -33,8 +38,8 @@ public class PlaybackSliderContribution extends ToolBarContributionItem { IExperiment experiment = manager.getActiveExperiment(); if(experiment == null || !(experiment instanceof SysdynPlaybackExperiment)) return; - final SysdynPlaybackExperiment spe = (SysdynPlaybackExperiment)experiment; - + spe = (SysdynPlaybackExperiment)experiment; + Double[] numbers = new Double[3]; try { numbers = SimanticsUI.getSession().syncRequest(new Read() { @@ -52,38 +57,37 @@ public class PlaybackSliderContribution extends ToolBarContributionItem { } catch (DatabaseException e1) { e1.printStackTrace(); } - + ToolItem ti = new ToolItem(parent, SWT.SEPARATOR); - + Composite composite = new Composite(parent, SWT.NONE); - GridLayoutFactory.fillDefaults().numColumns(2).applyTo(composite); + GridLayoutFactory.fillDefaults().margins(3, SWT.DEFAULT).numColumns(2).applyTo(composite); GridDataFactory.fillDefaults().applyTo(composite); - Slider s = new Slider(composite, SWT.NONE); + s = new Slider(composite, SWT.NONE); s.setMinimum(0); s.setMaximum(100); s.setIncrement(1); s.setPageIncrement(1); s.setThumb(1); - + final Label label = new Label(composite, SWT.NONE); GridDataFactory.fillDefaults().hint(50, SWT.DEFAULT).applyTo(label); label.setText("0.0"); ti.setWidth(250); ti.setControl(composite); - - final Double startTime = numbers[0]; - final Double endTime = numbers[1]; - + startTime = numbers[0]; + endTime = numbers[1]; + s.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { Slider s = (Slider)e.widget; Double time = s.getSelection() / 99.0 * (endTime - startTime) + startTime; - spe.setTime(time); + spe.setTimeAndContinue(time); if(!label.isDisposed()) { label.setText(time.toString()); } @@ -93,6 +97,39 @@ public class PlaybackSliderContribution extends ToolBarContributionItem { public void widgetDefaultSelected(SelectionEvent e) { } }); + + if(timeListener != null) { + spe.removeTimeListener(timeListener); + } + + timeListener = new Runnable() { + + @Override + public void run() { + s.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + int value = (int) ((spe.getTime() - startTime) / (endTime - startTime) * 99); + s.setSelection(value); + label.setText("" + spe.getTime()); + } + }); + + } + + }; + spe.addTimeListener(timeListener); + } + } + + @Override + public void dispose() { + if(this.timeListener != null && spe != null) { + spe.removeTimeListener(timeListener); + this.timeListener = null; } + super.dispose(); + } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ValidationUtils.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ValidationUtils.java index 7659e3d5..d81d186e 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ValidationUtils.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/validation/ValidationUtils.java @@ -27,6 +27,7 @@ import org.simantics.db.WriteGraph; import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.utils.OrderedSetUtils; import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.RemoverUtil; import org.simantics.issues.ontology.IssueResource; import org.simantics.layer0.Layer0; import org.simantics.sysdyn.SysdynResource; @@ -39,6 +40,7 @@ public class ValidationUtils { public static void removeIssue(WriteGraph graph, Resource model, Resource source, Resource variable, Resource issue, Collection existing) throws DatabaseException { graph.deny(issue, Layer0.getInstance(graph).PartOf); graph.deny(source, IssueResource.getInstance(graph).Manages, issue); + RemoverUtil.remove(graph, issue); existing.remove(issue); } diff --git a/org.simantics.sysdyn.ui/sysdyn.product b/org.simantics.sysdyn.ui/sysdyn.product index 540ebbc5..8ab825b0 100644 --- a/org.simantics.sysdyn.ui/sysdyn.product +++ b/org.simantics.sysdyn.ui/sysdyn.product @@ -7,7 +7,9 @@ - -fixerrors + -fixerrors +--launcher.XXMaxPermSize +256m -ea -Xmx768M -Xshare:off -XstartOnFirstThread -Dorg.eclipse.swt.internal.carbon.smallFonts 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 870418ea..615c7020 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynPlaybackExperiment.java @@ -1,28 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ package org.simantics.sysdyn.manager; +import java.util.ArrayList; +import java.util.Collection; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.util.Simantics; +import org.simantics.db.request.Read; import org.simantics.simulation.experiment.ExperimentState; import org.simantics.simulation.experiment.IDynamicExperiment; import org.simantics.simulation.ontology.SimulationResource; +import org.simantics.sysdyn.SysdynResource; public class SysdynPlaybackExperiment extends SysdynExperiment implements IDynamicExperiment { - + + public static long DURATION_SLOW = 20000; + public static long DURATION_NORMAL = 10000; + public static long DURATION_FAST = 5000; + double time; public static final long VARIABLE_UPDATE_INTERVAL = 500000000; + private static final double UPDATES_PER_TIME_UNIT = 0.015; + private long playbackDuration = DURATION_NORMAL; + private Collection timeListeners = new ArrayList(); + ScheduledExecutorService playbackExecutionService; + PlaybackConfiguration playbackConfiguration; public SysdynPlaybackExperiment(Resource experiment, Resource model) { super(experiment, model); this.time = 0; } - volatile boolean updating = false; - - public void setTime(double time) { + /** + * Interrupts a possible ongoing playback + * + * @param time + */ + public void setTimeInterrupting(double time) { + stopPlayback(); + setTime(time); + } + + /** + * Sets a new time and continues playback from that point if + * playback was running + * @param time + */ + public void setTimeAndContinue(double time) { + if(isPlaybackRunning()) { + stopPlayback(); + setTime(time); + startPlayback(500); + } else { + setTime(time); + } + } + + private void setTime(double time) { this.time = time; fireValuesChanged(); } @@ -31,6 +84,18 @@ public class SysdynPlaybackExperiment extends SysdynExperiment implements IDynam return this.time; } + public void setPlaybackDuration(long duration) { + this.playbackDuration = duration; + if(isPlaybackRunning()) { + //Restart playback with different time settings + startPlayback(); + } + } + + public long getPlaybackDuration() { + return this.playbackDuration; + } + @Override public void init(ReadGraph g) { this.session = g.getSession(); @@ -46,4 +111,160 @@ public class SysdynPlaybackExperiment extends SysdynExperiment implements IDynam } }); } + + + // PLAYBACK CONTROLS + public void startPlayback() { + startPlayback(0); + } + public void startPlayback(long initialDelay) { + if(isPlaybackRunning()) { + stopPlayback(); + } + playbackConfiguration = getPlaybackConfiguration(); + playbackExecutionService = Executors.newScheduledThreadPool(1); + + if(time >= playbackConfiguration.endTime) { + setTime(playbackConfiguration.startTime); + playbackConfiguration = getPlaybackConfiguration(); + } + + Runnable playbackSimulationTask = new PlaybackSimulationTask(time, playbackConfiguration.simulationStepLength); + + long delay = (long) (playbackConfiguration.playbackDuration / playbackConfiguration.intervals); + ScheduledFuture stepper = playbackExecutionService.scheduleWithFixedDelay( + playbackSimulationTask, initialDelay, delay, TimeUnit.MILLISECONDS + ); + + Runnable stopSimulationTask = new StopSimulationTask(stepper, playbackConfiguration.endTime); + playbackExecutionService.schedule(stopSimulationTask, playbackConfiguration.playbackDuration + initialDelay, TimeUnit.MILLISECONDS); + + changeState(ExperimentState.RUNNING); + } + + public boolean isPlaybackRunning() { + return playbackExecutionService != null && !playbackExecutionService.isShutdown(); + } + + public void resetPlayback() { + double startTime = 0.0; + if(isPlaybackRunning() && playbackConfiguration != null) { + startTime = playbackConfiguration.startTime; + } else { + startTime = getPlaybackConfiguration().startTime; + } + setTimeInterrupting(startTime); + } + + public void stopPlayback() { + if(isPlaybackRunning()) { + playbackExecutionService.shutdownNow(); + playbackExecutionService.shutdown(); + if(playbackConfiguration != null) + playbackConfiguration = null; + changeState(ExperimentState.STOPPED); + } + } + + + private class PlaybackSimulationTask implements Runnable { + private int stepCount; + private double startTime, stepLength; + + public PlaybackSimulationTask(double startTime, double stepLength) { + this.startTime = startTime; + this.stepLength = stepLength; + } + + public void run() { + ++stepCount; + setTime(startTime + stepCount * stepLength); +// System.out.println("Playback step at time: " + (startTime + stepCount * stepLength) + " (step: " + stepCount + ")"); + } + } + + private class StopSimulationTask implements Runnable { + + private ScheduledFuture scheduledFuture; + private double endTime; + + public StopSimulationTask(ScheduledFuture aSchedFuture, double endTime){ + scheduledFuture = aSchedFuture; + this.endTime = endTime; + } + public void run() { +// System.out.println("Stopping playback"); + scheduledFuture.cancel(false); + stopPlayback(); + setTime(endTime); + } + + } + + private PlaybackConfiguration getPlaybackConfiguration() { + Double[] numbers = new Double[3]; + try { + numbers = Simantics.getSession().syncRequest(new Read() { + @Override + public Double[] perform(ReadGraph graph) throws DatabaseException { + Double[] numbers = new Double[3]; + Resource model = getModel(); + SysdynResource sr = SysdynResource.getInstance(graph); + numbers[0] = graph.getRelatedValue(model, sr.HasStartTime); + numbers[1] = graph.getRelatedValue(model, sr.HasStopTime); + numbers[2] = graph.getPossibleRelatedValue(model, sr.HasOutputInterval); + return numbers; + } + }); + } catch (DatabaseException e1) { + e1.printStackTrace(); + } + + PlaybackConfiguration config = new PlaybackConfiguration(); + config.simulationDuration = numbers[1] - numbers[0] - time; + config.playbackDuration = (long) (config.simulationDuration / (config.simulationDuration + time) * playbackDuration); + config.intervals = config.playbackDuration * UPDATES_PER_TIME_UNIT; + config.simulationStepLength = config.simulationDuration / config.intervals; + config.endTime = numbers[1]; + config.startTime = numbers[0]; + return config; + } + + private class PlaybackConfiguration { + public double simulationDuration, simulationStepLength, intervals, endTime, startTime; + public long playbackDuration; + } + + protected void localStateChange() { + super.localStateChange(); + + ExperimentState state = getState(); + if(ExperimentState.DISPOSED.equals(state)) { + stopPlayback(); + } + } + + // TIME LISTENERS + public void addTimeListener(Runnable timeListener) { + if(!this.timeListeners.contains(timeListener)) + this.timeListeners.add(timeListener); + } + + public Collection getTimeListeners() { + return this.timeListeners; + } + + public void removeTimeListener(Runnable timeListener) { + this.timeListeners.remove(timeListener); + } + + @Override + public void fireValuesChanged() { + for(Runnable listener : timeListeners) { + listener.run(); + } + super.fireValuesChanged(); + + } + }