Browse Source

Added TimeSchedulerLabel/-Refresher to SimulationView... (#1670)

* Moved org.yakindu.sct.simulation.core.sexec.scheduling to org.yakindu.sct.simulation.core.engine.scheduling. Added TimeSchedulerLabel/-Refresher to SimulationView. Extracted ViewerRefresher from ExecutionContextContentProvider to SimulationView.

* fixed mars travis build. replaced requestLayout() with update() method for timelabel

* Updated Oxygen Target

* Update AbstractExecutionFlowSimulationEngine.java

* Update SimulationView.java

* removed refresher for timelabel. removed sashform
Robert Rudi 7 years ago
parent
commit
3e4f7ef659
13 changed files with 343 additions and 275 deletions
  1. 1 2
      plugins/org.yakindu.sct.simulation.core.sexec/META-INF/MANIFEST.MF
  2. 6 1
      plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/container/AbstractExecutionFlowSimulationEngine.java
  3. 2 2
      plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/container/CycleBasedSimulationEngine.java
  4. 2 2
      plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/interpreter/DefaultExecutionFlowInterpreter.xtend
  5. 1 0
      plugins/org.yakindu.sct.simulation.core/META-INF/MANIFEST.MF
  6. 3 0
      plugins/org.yakindu.sct.simulation.core/src/org/yakindu/sct/simulation/core/engine/ISimulationEngine.java
  7. 6 1
      plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/scheduling/DefaultTimeTaskScheduler.java
  8. 109 107
      plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/scheduling/ITimeTaskScheduler.java
  9. 1 1
      plugins/org.yakindu.sct.simulation.ui/plugin.xml
  10. 93 138
      plugins/org.yakindu.sct.simulation.ui/src/org/yakindu/sct/simulation/ui/view/ExecutionContextContentProvider.java
  11. 7 7
      plugins/org.yakindu.sct.simulation.ui/src/org/yakindu/sct/simulation/ui/view/ExecutionContextLabelProvider.java
  12. 11 12
      plugins/org.yakindu.sct.simulation.ui/src/org/yakindu/sct/simulation/ui/view/ExecutionContextViewerFactory.java
  13. 101 2
      plugins/org.yakindu.sct.simulation.ui/src/org/yakindu/sct/simulation/ui/view/SimulationView.java

+ 1 - 2
plugins/org.yakindu.sct.simulation.core.sexec/META-INF/MANIFEST.MF

@@ -23,7 +23,6 @@ Bundle-ActivationPolicy: lazy
 Export-Package: org.yakindu.sct.simulation.core.sexec,
  org.yakindu.sct.simulation.core.sexec.container,
  org.yakindu.sct.simulation.core.sexec.interpreter,
- org.yakindu.sct.simulation.core.sexec.launch,
- org.yakindu.sct.simulation.core.sexec.scheduling
+ org.yakindu.sct.simulation.core.sexec.launch
 Bundle-Vendor: statecharts.org
 

+ 6 - 1
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/container/AbstractExecutionFlowSimulationEngine.java

@@ -24,9 +24,9 @@ import org.yakindu.sct.model.sruntime.ExecutionContext;
 import org.yakindu.sct.simulation.core.SimulationCoreActivator;
 import org.yakindu.sct.simulation.core.engine.IExecutionControl;
 import org.yakindu.sct.simulation.core.engine.ISimulationEngine;
+import org.yakindu.sct.simulation.core.engine.scheduling.ITimeTaskScheduler;
 import org.yakindu.sct.simulation.core.launch.AbstractSCTLaunchConfigurationDelegate.InitializationException;
 import org.yakindu.sct.simulation.core.sexec.interpreter.IExecutionFlowInterpreter;
-import org.yakindu.sct.simulation.core.sexec.scheduling.ITimeTaskScheduler;
 
 import com.google.inject.Inject;
 
@@ -161,5 +161,10 @@ public class AbstractExecutionFlowSimulationEngine extends AbstractSimulationEng
 	public Statechart getStatechart() {
 		return statechart;
 	}
+	
+	@Override
+	public ITimeTaskScheduler getTimeTaskScheduler() {
+		return this.timeTaskScheduler;
+	}
 
 }

+ 2 - 2
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/container/CycleBasedSimulationEngine.java

@@ -17,8 +17,8 @@ import org.yakindu.sct.model.sgraph.Statechart;
 import org.yakindu.sct.model.sruntime.SRuntimeFactory;
 import org.yakindu.sct.model.stext.stext.ArgumentedAnnotation;
 import org.yakindu.sct.simulation.core.engine.ISimulationEngine;
-import org.yakindu.sct.simulation.core.sexec.scheduling.ITimeTaskScheduler.TimeTask;
-import org.yakindu.sct.simulation.core.sexec.scheduling.ITimeTaskScheduler.TimeTask.Priority;
+import org.yakindu.sct.simulation.core.engine.scheduling.ITimeTaskScheduler.TimeTask;
+import org.yakindu.sct.simulation.core.engine.scheduling.ITimeTaskScheduler.TimeTask.Priority;
 
 import com.google.inject.Inject;
 

+ 2 - 2
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/interpreter/DefaultExecutionFlowInterpreter.xtend

@@ -44,8 +44,8 @@ import org.yakindu.sct.model.sruntime.EventDirection
 import org.yakindu.sct.model.sruntime.ExecutionContext
 import org.yakindu.sct.model.sruntime.ExecutionEvent
 import org.yakindu.sct.model.stext.lib.StatechartAnnotations
-import org.yakindu.sct.simulation.core.sexec.scheduling.ITimeTaskScheduler
-import org.yakindu.sct.simulation.core.sexec.scheduling.ITimeTaskScheduler.TimeTask
+import org.yakindu.sct.simulation.core.engine.scheduling.ITimeTaskScheduler
+import org.yakindu.sct.simulation.core.engine.scheduling.ITimeTaskScheduler.TimeTask
 import org.yakindu.sct.simulation.core.util.ExecutionContextExtensions
 
 /**

+ 1 - 0
plugins/org.yakindu.sct.simulation.core/META-INF/MANIFEST.MF

@@ -26,6 +26,7 @@ Bundle-ActivationPolicy: lazy
 Export-Package: org.yakindu.sct.simulation.core,
  org.yakindu.sct.simulation.core.debugmodel,
  org.yakindu.sct.simulation.core.engine,
+ org.yakindu.sct.simulation.core.engine.scheduling,
  org.yakindu.sct.simulation.core.hmr,
  org.yakindu.sct.simulation.core.launch,
  org.yakindu.sct.simulation.core.util

+ 3 - 0
plugins/org.yakindu.sct.simulation.core/src/org/yakindu/sct/simulation/core/engine/ISimulationEngine.java

@@ -11,6 +11,7 @@
 package org.yakindu.sct.simulation.core.engine;
 
 import org.yakindu.sct.model.sruntime.ExecutionContext;
+import org.yakindu.sct.simulation.core.engine.scheduling.ITimeTaskScheduler;
 
 /**
  * 
@@ -25,4 +26,6 @@ public interface ISimulationEngine {
 	
 	public void setExecutionContext(ExecutionContext context);
 
+	public ITimeTaskScheduler getTimeTaskScheduler();
+
 }

+ 6 - 1
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/scheduling/DefaultTimeTaskScheduler.java

@@ -6,7 +6,7 @@
  * 	Andreas Muelder - itemis AG
  * 
  */
-package org.yakindu.sct.simulation.core.sexec.scheduling;
+package org.yakindu.sct.simulation.core.engine.scheduling;
 
 import java.util.Optional;
 import java.util.PriorityQueue;
@@ -204,4 +204,9 @@ public class DefaultTimeTaskScheduler implements ITimeTaskScheduler {
 	public void step() {
 		work();
 	}
+
+	@Override
+	public long getCurrentTime() {
+		return this.currentTime;
+	}
 }

+ 109 - 107
plugins/org.yakindu.sct.simulation.core.sexec/src/org/yakindu/sct/simulation/core/sexec/scheduling/ITimeTaskScheduler.java

@@ -1,107 +1,109 @@
-/**
- * Copyright (c) 2017 committers of YAKINDU and others.
- * 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:
- *     committers of YAKINDU - initial API and implementation
- */
-package org.yakindu.sct.simulation.core.sexec.scheduling;
-
-import com.google.inject.ImplementedBy;
-
-/**
- * 
- * @author andreas muelder - Initial contribution and API
- * 
- */
-@ImplementedBy(DefaultTimeTaskScheduler.class)
-public interface ITimeTaskScheduler {
-
-	public void scheduleTimeTask(TimeTask task, boolean isPeriodical, long duration);
-
-	public void unscheduleTimeTask(String eventName);
-
-	public void timeLeap(long ms);
-
-	public void start();
-
-	public void suspend();
-
-	public void resume();
-
-	public void step();
-
-	public void terminate();
-
-	public static class TimeTask implements Runnable, Comparable<TimeTask> {
-
-		public static enum Priority {
-
-			LOW(0), NORMAL(50), HIGH(100);
-
-			private int intValue;
-
-			Priority(int prio) {
-				this.intValue = prio;
-			}
-
-			public int getIntValue() {
-				return intValue;
-			}
-		}
-
-		private long nextExecutionTime = 0;
-		long period = -1;
-		long scheduleOrder = 0;
-		boolean isCanceled = false;
-		Priority priority = Priority.NORMAL;
-		String name;
-
-		private final Runnable callBack;
-
-		public TimeTask(String name, Runnable callBack) {
-			this(name, callBack, Priority.NORMAL);
-		}
-
-		public TimeTask(String name, Runnable callBack, Priority priority) {
-			this.callBack = callBack;
-			this.name = name;
-			this.priority = priority;
-		}
-
-		public void run() {
-			callBack.run();
-		}
-
-		public int compareTo(TimeTask other) {
-			if (nextExecutionTime != other.nextExecutionTime) {
-				return (int) (nextExecutionTime - other.nextExecutionTime);
-			} else if (other.priority != this.priority) {
-				return other.priority.getIntValue() - this.priority.getIntValue();
-			} else if (period != other.period) {
-				return (int) (period - other.period);
-			}
-			return (int) (scheduleOrder - other.scheduleOrder);
-		}
-
-		public boolean isCanceled() {
-			return isCanceled;
-		}
-
-		public void cancel() {
-			isCanceled = true;
-		}
-
-		public long getNextExecutionTime() {
-			return nextExecutionTime;
-		}
-
-		public void setNextExecutionTime(long nextExecutionTime) {
-			this.nextExecutionTime = nextExecutionTime;
-		}
-	}
-
-}
+/**
+ * Copyright (c) 2017 committers of YAKINDU and others.
+ * 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:
+ *     committers of YAKINDU - initial API and implementation
+ */
+package org.yakindu.sct.simulation.core.engine.scheduling;
+
+import com.google.inject.ImplementedBy;
+
+/**
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+@ImplementedBy(DefaultTimeTaskScheduler.class)
+public interface ITimeTaskScheduler {
+
+	public void scheduleTimeTask(TimeTask task, boolean isPeriodical, long duration);
+
+	public void unscheduleTimeTask(String eventName);
+
+	public void timeLeap(long ms);
+
+	public void start();
+
+	public void suspend();
+
+	public void resume();
+
+	public void step();
+
+	public void terminate();
+	
+	public long getCurrentTime();
+
+	public static class TimeTask implements Runnable, Comparable<TimeTask> {
+
+		public static enum Priority {
+
+			LOW(0), NORMAL(50), HIGH(100);
+
+			private int intValue;
+
+			Priority(int prio) {
+				this.intValue = prio;
+			}
+
+			public int getIntValue() {
+				return intValue;
+			}
+		}
+
+		private long nextExecutionTime = 0;
+		long period = -1;
+		long scheduleOrder = 0;
+		boolean isCanceled = false;
+		Priority priority = Priority.NORMAL;
+		String name;
+
+		private final Runnable callBack;
+
+		public TimeTask(String name, Runnable callBack) {
+			this(name, callBack, Priority.NORMAL);
+		}
+
+		public TimeTask(String name, Runnable callBack, Priority priority) {
+			this.callBack = callBack;
+			this.name = name;
+			this.priority = priority;
+		}
+
+		public void run() {
+			callBack.run();
+		}
+
+		public int compareTo(TimeTask other) {
+			if (nextExecutionTime != other.nextExecutionTime) {
+				return (int) (nextExecutionTime - other.nextExecutionTime);
+			} else if (other.priority != this.priority) {
+				return other.priority.getIntValue() - this.priority.getIntValue();
+			} else if (period != other.period) {
+				return (int) (period - other.period);
+			}
+			return (int) (scheduleOrder - other.scheduleOrder);
+		}
+
+		public boolean isCanceled() {
+			return isCanceled;
+		}
+
+		public void cancel() {
+			isCanceled = true;
+		}
+
+		public long getNextExecutionTime() {
+			return nextExecutionTime;
+		}
+
+		public void setNextExecutionTime(long nextExecutionTime) {
+			this.nextExecutionTime = nextExecutionTime;
+		}
+	}
+
+}

+ 1 - 1
plugins/org.yakindu.sct.simulation.ui/plugin.xml

@@ -23,7 +23,7 @@
     	  category="org.yakindu.sct.category"
           allowMultiple="false"
           class="org.yakindu.sct.simulation.ui.view.SimulationView"
-          icon="icons/Declarations-View-16.gif"
+          icon="icons/Statechart-Launcher-16.png"
           id="org.yakindu.sct.simulation.ui.declarationview"
           name="Simulation"
           restorable="true">

+ 93 - 138
plugins/org.yakindu.sct.simulation.ui/src/org/yakindu/sct/simulation/ui/view/ExecutionContextContentProvider.java

@@ -1,139 +1,94 @@
-/**
- * Copyright (c) 2011 committers of YAKINDU and others.
- * 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:
- * 	committers of YAKINDU - initial API and implementation
- * 
- */
-package org.yakindu.sct.simulation.ui.view;
-
-import org.eclipse.jface.preference.IPreferenceStore;
-import org.eclipse.jface.util.IPropertyChangeListener;
-import org.eclipse.jface.util.PropertyChangeEvent;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.widgets.Display;
-import org.yakindu.sct.model.sruntime.CompositeSlot;
-import org.yakindu.sct.model.sruntime.ExecutionContext;
-import org.yakindu.sct.simulation.ui.SimulationActivator;
-import org.yakindu.sct.simulation.ui.view.actions.HideTimeEventsAction;
-
-/**
- * 
- * @author andreas muelder - Initial contribution and API
- * 
- */
-public class ExecutionContextContentProvider implements ITreeContentProvider, IPropertyChangeListener {
-
-	protected class ViewerRefresher implements Runnable {
-
-		private static final int UPDATE_INTERVAL = 500;
-
-		private boolean cancel = false;
-
-		@Override
-		public void run() {
-			while (!cancel && viewer.getInput() != null) {
-				try {
-					Thread.sleep(UPDATE_INTERVAL);
-					Display.getDefault().asyncExec(new Runnable() {
-						public void run() {
-							if (viewer != null && !viewer.getControl().isDisposed() && shouldUpdate)
-								viewer.refresh();
-						}
-					});
-				} catch (InterruptedException e) {
-					e.printStackTrace();
-				}
-			}
-		}
-
-		public boolean isCancel() {
-			return cancel;
-		}
-
-		public void setCancel(boolean cancel) {
-			this.cancel = cancel;
-		}
-
-	}
-
-	private boolean shouldUpdate = true;
-	private ViewerRefresher refresher;
-	private Viewer viewer;
-
-	public void dispose() {
-		getStore().removePropertyChangeListener(this);
-		if (refresher != null)
-			refresher.cancel = true;
-	}
-
-	public ExecutionContextContentProvider() {
-		getStore().addPropertyChangeListener(this);
-	}
-
-	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-		this.viewer = viewer;
-		if (refresher != null) {
-			refresher.cancel = true;
-		}
-		refresher = new ViewerRefresher();
-		if (newInput != null) {
-			new Thread(refresher).start();
-		} else {
-			refresher.cancel = true;
-		}
-	}
-
-	public Object[] getElements(Object inputElement) {
-		if (inputElement == null) {
+/**
+ * Copyright (c) 2011 committers of YAKINDU and others.
+ * 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:
+ * 	committers of YAKINDU - initial API and implementation
+ * 
+ */
+package org.yakindu.sct.simulation.ui.view;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Label;
+import org.yakindu.sct.model.sruntime.CompositeSlot;
+import org.yakindu.sct.model.sruntime.ExecutionContext;
+import org.yakindu.sct.simulation.ui.SimulationActivator;
+import org.yakindu.sct.simulation.ui.view.actions.HideTimeEventsAction;
+
+/**
+ * 
+ * @author andreas muelder - Initial contribution and API
+ * 
+ */
+public class ExecutionContextContentProvider implements ITreeContentProvider, IPropertyChangeListener {
+
+	private boolean shouldUpdate = true;
+	private Viewer viewer;
+
+	public void dispose() {
+		getStore().removePropertyChangeListener(this);
+	}
+
+	public ExecutionContextContentProvider() {
+		getStore().addPropertyChangeListener(this);
+	}
+
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		this.viewer = viewer;
+	}
+
+	public Object[] getElements(Object inputElement) {
+		if (inputElement == null) {
 			return new Object[] {};
-		}
-		if (inputElement instanceof ExecutionContext) {
-			return ((ExecutionContext) inputElement).getSlots().toArray();
-		}
-		return new Object[] {};
-
-	}
-
-	public Object[] getChildren(Object parentElement) {
-		if (parentElement instanceof CompositeSlot) {
-			return ((CompositeSlot) parentElement).getSlots().toArray();
-		}
-		return new Object[] {};
-	}
-
-	public Object getParent(Object element) {
-		return null;
-	}
-
-	public boolean hasChildren(Object element) {
-		if (element instanceof CompositeSlot) {
-			return ((CompositeSlot) element).getSlots().size() > 0;
-		}
-		return false;
-	}
-
-	private IPreferenceStore getStore() {
-		return SimulationActivator.getDefault().getPreferenceStore();
-	}
-
-	public void propertyChange(PropertyChangeEvent event) {
-		if (event.getProperty() == HideTimeEventsAction.HIDE_KEY) {
-			if (viewer != null && !viewer.getControl().isDisposed())
-				viewer.refresh();
-		}
-	}
-
-	public boolean isShouldUpdate() {
-		return shouldUpdate;
-	}
-
-	public void setShouldUpdate(boolean shouldUpdate) {
-		this.shouldUpdate = shouldUpdate;
-	}
-
-}
+		}
+		if (inputElement instanceof ExecutionContext) {
+			return ((ExecutionContext) inputElement).getSlots().toArray();
+		}
+		return new Object[]{};
+
+	}
+
+	public Object[] getChildren(Object parentElement) {
+		if (parentElement instanceof CompositeSlot) {
+			return ((CompositeSlot) parentElement).getSlots().toArray();
+		}
+		return new Object[]{};
+	}
+
+	public Object getParent(Object element) {
+		return null;
+	}
+
+	public boolean hasChildren(Object element) {
+		if (element instanceof CompositeSlot) {
+			return ((CompositeSlot) element).getSlots().size() > 0;
+		}
+		return false;
+	}
+
+	private IPreferenceStore getStore() {
+		return SimulationActivator.getDefault().getPreferenceStore();
+	}
+
+	public void propertyChange(PropertyChangeEvent event) {
+		if (event.getProperty() == HideTimeEventsAction.HIDE_KEY) {
+			if (viewer != null && !viewer.getControl().isDisposed())
+				viewer.refresh();
+		}
+	}
+
+	public boolean isShouldUpdate() {
+		return shouldUpdate;
+	}
+
+	public void setShouldUpdate(boolean shouldUpdate) {
+		this.shouldUpdate = shouldUpdate;
+	}
+
+}

+ 7 - 7
plugins/org.yakindu.sct.simulation.ui/src/org/yakindu/sct/simulation/ui/view/ExecutionContextLabelProvider.java

@@ -38,12 +38,12 @@ public class ExecutionContextLabelProvider extends StyledCellLabelProvider {
 
 	public void update(ViewerCell cell) {
 		switch (index) {
-		case 0:
-			updateNameCell(cell);
-			break;
-		case 1:
-			updateValueCell(cell);
-			break;
+			case 0 :
+				updateNameCell(cell);
+				break;
+			case 1 :
+				updateValueCell(cell);
+				break;
 		}
 		super.update(cell);
 	}
@@ -86,7 +86,7 @@ public class ExecutionContextLabelProvider extends StyledCellLabelProvider {
 			style1.underline = true;
 			style1.foreground = ColorConstants.lightBlue;
 			cell.setText(event.getName());
-			cell.setStyleRanges(new StyleRange[] { style1 });
+			cell.setStyleRanges(new StyleRange[]{style1});
 			if (event.getName().contains("time_event")) {
 				cell.setImage(SimulationImages.TIMEEVENT.image());
 			} else {

+ 11 - 12
plugins/org.yakindu.sct.simulation.ui/src/org/yakindu/sct/simulation/ui/view/ExecutionContextViewerFactory.java

@@ -37,9 +37,9 @@ public class ExecutionContextViewerFactory {
 		final TreeViewer viewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
 		viewer.getTree().setHeaderVisible(true);
 		viewer.getTree().setLinesVisible(true);
-		final ExecutionContextContentProvider contentProvider = new ExecutionContextContentProvider();
+		ExecutionContextContentProvider contentProvider = new ExecutionContextContentProvider();
 		viewer.setContentProvider(contentProvider);
-		viewer.setFilters(new ViewerFilter[] { new TimeEventViewerFilter() });
+		viewer.setFilters(new ViewerFilter[]{new TimeEventViewerFilter()});
 		TreeViewerColumn nameColumn = new TreeViewerColumn(viewer, SWT.DEFAULT);
 		nameColumn.getColumn().setText("Name");
 		nameColumn.getColumn().setMoveable(true);
@@ -51,16 +51,15 @@ public class ExecutionContextViewerFactory {
 		valueColumn.getColumn().setMoveable(true);
 		valueColumn.getColumn().setWidth(100);
 		if (!readOnly)
-			valueColumn
-					.setEditingSupport(new MultiEditingSupport(viewer,
-							/*
-							 * Specialized editing supports first...
-							 */
-							new EnumerationEditingSupport(viewer, provider), //
-							new IntegerEditingSupport(viewer, provider), //
-							new RealEditingSupport(viewer, provider), //
-							new BooleanEditingSupport(viewer, provider), //
-							new StringEditingSupport(viewer, provider)));//
+			valueColumn.setEditingSupport(new MultiEditingSupport(viewer,
+					/*
+					 * Specialized editing supports first...
+					 */
+					new EnumerationEditingSupport(viewer, provider), //
+					new IntegerEditingSupport(viewer, provider), //
+					new RealEditingSupport(viewer, provider), //
+					new BooleanEditingSupport(viewer, provider), //
+					new StringEditingSupport(viewer, provider)));//
 
 		valueColumn.setLabelProvider(new ExecutionContextLabelProvider(1));
 

+ 101 - 2
plugins/org.yakindu.sct.simulation.ui/src/org/yakindu/sct/simulation/ui/view/SimulationView.java

@@ -10,6 +10,7 @@
  */
 package org.yakindu.sct.simulation.ui.view;
 
+import org.apache.commons.lang.time.DurationFormatUtils;
 import org.eclipse.debug.core.DebugEvent;
 import org.eclipse.debug.core.DebugException;
 import org.eclipse.debug.core.model.IDebugTarget;
@@ -18,6 +19,7 @@ import org.eclipse.debug.internal.ui.commands.actions.ResumeCommandAction;
 import org.eclipse.debug.internal.ui.commands.actions.StepOverCommandAction;
 import org.eclipse.debug.internal.ui.commands.actions.SuspendCommandAction;
 import org.eclipse.debug.internal.ui.commands.actions.TerminateCommandAction;
+import org.eclipse.draw2d.ColorConstants;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jface.action.ActionContributionItem;
 import org.eclipse.jface.action.IAction;
@@ -28,6 +30,7 @@ import org.eclipse.jface.viewers.TreeViewer;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerCell;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.events.MouseAdapter;
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.MouseMoveListener;
@@ -35,14 +38,19 @@ import org.eclipse.swt.graphics.Font;
 import org.eclipse.swt.graphics.FontData;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
 import org.eclipse.ui.forms.widgets.FormToolkit;
 import org.yakindu.base.types.typesystem.ITypeSystem;
 import org.yakindu.sct.domain.extension.DomainRegistry;
 import org.yakindu.sct.domain.extension.IDomain;
 import org.yakindu.sct.model.sruntime.ExecutionEvent;
 import org.yakindu.sct.simulation.core.engine.ISimulationEngine;
+import org.yakindu.sct.simulation.core.engine.scheduling.DefaultTimeTaskScheduler;
+import org.yakindu.sct.simulation.core.engine.scheduling.ITimeTaskScheduler;
 import org.yakindu.sct.simulation.ui.view.actions.CollapseAllAction;
 import org.yakindu.sct.simulation.ui.view.actions.ExpandAllAction;
 import org.yakindu.sct.simulation.ui.view.actions.HideTimeEventsAction;
@@ -58,10 +66,13 @@ import com.google.common.collect.Lists;
 public class SimulationView extends AbstractDebugTargetView implements ITypeSystemProvider {
 
 	private TreeViewer viewer;
+	private ViewerRefresher viewerRefresher;
 	private FormToolkit kit;
 	private Font font;
 	private RaiseEventSelectionListener selectionListener;
 	private ITypeSystem typeSystem;
+	private ITimeTaskScheduler timeScheduler;
+	private Label timeSchedulerLabel;
 
 	public SimulationView() {
 		kit = new FormToolkit(Display.getDefault());
@@ -73,15 +84,31 @@ public class SimulationView extends AbstractDebugTargetView implements ITypeSyst
 	public void dispose() {
 		selectionListener.dispose();
 		font.dispose();
+		disposeTimeSchedulerComponent();
+		disposeViewerRefresher();
 		super.dispose();
 	}
 
+	protected void disposeViewerRefresher() {
+		if (viewerRefresher != null) {
+			viewerRefresher.cancel = true;
+			viewerRefresher = null;
+		}
+	}
+
+	protected void disposeTimeSchedulerComponent() {
+		if (timeSchedulerLabel != null && !timeSchedulerLabel.isDisposed()) {
+			timeSchedulerLabel.dispose();
+		}
+	}
+
 	@Override
 	public void createPartControl(Composite parent) {
 		parent.setLayout(new FillLayout(SWT.VERTICAL));
 		Composite top = kit.createComposite(parent);
 		top.setLayout(new FillLayout(SWT.VERTICAL));
 		createViewer(top);
+		createTimeScheduler(top);
 		hookActions();
 		super.createPartControl(parent);
 	}
@@ -97,13 +124,40 @@ public class SimulationView extends AbstractDebugTargetView implements ITypeSyst
 		return viewer;
 	}
 
+	public Label createTimeScheduler(Composite parent) {
+		Composite comp = new Composite(parent, SWT.BORDER);
+		GridLayout layout = new GridLayout();
+		comp.setLayout(layout);
+		timeSchedulerLabel = new Label(comp, SWT.NONE);
+		timeSchedulerLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true));
+		timeSchedulerLabel.setToolTipText("Displays the duration since the simulation is running");
+		return timeSchedulerLabel;
+	}
+
+	protected void setViewerInput(Object input) {
+		if (viewerRefresher != null || input == null) {
+			viewerRefresher.cancel = true;
+		} else {
+			if (viewerRefresher == null)
+				this.viewerRefresher = new ViewerRefresher();
+		}
+		if (input != null) {
+			this.viewer.setInput(input);
+			if (this.viewerRefresher.isCancel())
+				this.viewerRefresher.cancel = false;
+
+			new Thread(viewerRefresher).start();
+		}
+
+	}
+
 	protected void handleDebugEvent(DebugEvent debugEvent) {
 		updateActions();
 		switch (debugEvent.getKind()) {
 			case DebugEvent.TERMINATE :
 				Display.getDefault().asyncExec(new Runnable() {
 					public void run() {
-						viewer.setInput(null);
+						setViewerInput(null);
 					}
 				});
 				break;
@@ -117,7 +171,8 @@ public class SimulationView extends AbstractDebugTargetView implements ITypeSyst
 	protected void activeTargetChanged(final IDebugTarget debugTarget) {
 		updateTypeSystem(debugTarget);
 		ISimulationEngine engine = (ISimulationEngine) debugTarget.getAdapter(ISimulationEngine.class);
-		viewer.setInput(engine.getExecutionContext());
+		timeScheduler = (DefaultTimeTaskScheduler) engine.getTimeTaskScheduler();
+		setViewerInput(engine.getExecutionContext());
 		(new ExpandAllAction(viewer)).run();
 		updateActions();
 	}
@@ -303,4 +358,48 @@ public class SimulationView extends AbstractDebugTargetView implements ITypeSyst
 			return debugTarget != null && debugTarget.canResume();
 		}
 	}
+
+	protected class ViewerRefresher implements Runnable {
+
+		private static final int UPDATE_INTERVAL = 500;
+		private boolean cancel = false;
+
+		@Override
+		public void run() {
+			while (!cancel && viewer.getInput() != null) {
+				try {
+					Thread.sleep(UPDATE_INTERVAL);
+					Display.getDefault().asyncExec(new Runnable() {
+						public void run() {
+							if (viewer != null && !viewer.getControl().isDisposed()
+									&& ((ExecutionContextContentProvider) viewer.getContentProvider())
+											.isShouldUpdate()) {
+								viewer.refresh();
+							}
+							if (timeSchedulerLabel != null && !timeSchedulerLabel.isDisposed()) {
+								updateTimestamp(timeScheduler.getCurrentTime());
+							}
+						}
+					});
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		
+		protected void updateTimestamp(long timestamp) {
+			String formatDurationHMS = DurationFormatUtils.formatDuration(timestamp, "HH:mm:ss.SSS");
+			timeSchedulerLabel.setText("Simulation time: " + formatDurationHMS);
+			timeSchedulerLabel.update();
+		}
+
+		public boolean isCancel() {
+			return cancel;
+		}
+
+		public void setCancel(boolean cancel) {
+			this.cancel = cancel;
+		}
+	}
+
 }