Dominik Tesch 9 lat temu
rodzic
commit
082e87ea69
19 zmienionych plików z 2704 dodań i 0 usunięć
  1. 7 0
      examples/trafficlight_example/.classpath
  2. 23 0
      examples/trafficlight_example/.project
  3. 12 0
      examples/trafficlight_example/.settings/org.eclipse.jdt.core.prefs
  4. 2 0
      examples/trafficlight_example/bin/.gitignore
  5. 549 0
      examples/trafficlight_example/model/TrafficLightWaiting.sct
  6. 19 0
      examples/trafficlight_example/model/default2.sgen
  7. 7 0
      examples/trafficlight_example/readme.txt
  8. 207 0
      examples/trafficlight_example/src-gen/org/yakindu/scr/RuntimeService.java
  9. 91 0
      examples/trafficlight_example/src-gen/org/yakindu/scr/TimerService.java
  10. 38 0
      examples/trafficlight_example/src-gen/org/yakindu/scr/trafficlightwaiting/ITrafficLightWaitingStatemachine.java
  11. 1111 0
      examples/trafficlight_example/src-gen/org/yakindu/scr/trafficlightwaiting/TrafficLightWaitingStatemachine.java
  12. 39 0
      examples/trafficlight_example/src/org/yakindu/scr/IStatemachine.java
  13. 38 0
      examples/trafficlight_example/src/org/yakindu/scr/ITimer.java
  14. 15 0
      examples/trafficlight_example/src/org/yakindu/scr/ITimerCallback.java
  15. 51 0
      examples/trafficlight_example/src/trafficlight_example/ButtonPanel.java
  16. 141 0
      examples/trafficlight_example/src/trafficlight_example/CrossingPanel.java
  17. 123 0
      examples/trafficlight_example/src/trafficlight_example/PedestrianLight.java
  18. 123 0
      examples/trafficlight_example/src/trafficlight_example/TrafficLight.java
  19. 108 0
      examples/trafficlight_example/src/trafficlight_example/TrafficlightDemo.java

+ 7 - 0
examples/trafficlight_example/.classpath

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" path="src-gen"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

+ 23 - 0
examples/trafficlight_example/.project

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>trafficlight_example</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+	</natures>
+</projectDescription>

+ 12 - 0
examples/trafficlight_example/.settings/org.eclipse.jdt.core.prefs

@@ -0,0 +1,12 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8

+ 2 - 0
examples/trafficlight_example/bin/.gitignore

@@ -0,0 +1,2 @@
+/org/
+/trafficlight_example/

Plik diff jest za duży
+ 549 - 0
examples/trafficlight_example/model/TrafficLightWaiting.sct


+ 19 - 0
examples/trafficlight_example/model/default2.sgen

@@ -0,0 +1,19 @@
+GeneratorModel for yakindu::java {
+
+	statechart TrafficLightWaiting {
+
+		feature Outlet {
+			targetProject = "trafficlight_example"
+			targetFolder = "src-gen"
+			libraryTargetFolder = "src"
+		}
+		
+		feature GeneralFeatures {
+			InterfaceObserverSupport = false
+			RuntimeService = true
+			TimerService = true
+			UseJavaIntForInteger = false
+		}
+		
+	}
+}

+ 7 - 0
examples/trafficlight_example/readme.txt

@@ -0,0 +1,7 @@
+The Trafficlight example contains a simple Swing based Java GUI to
+demonstrate the state machine behaviour in /model/TrafficLightWaiting.sct
+
+To start the application run src/trafficlight_example/TrafficlightDemo.java
+
+The example requires Java 8.
+

+ 207 - 0
examples/trafficlight_example/src-gen/org/yakindu/scr/RuntimeService.java

@@ -0,0 +1,207 @@
+package org.yakindu.scr;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * Runtime service for state machines to execute a run to completion step
+ * periodically.
+ * 
+ */
+public class RuntimeService {
+
+	private static RuntimeService runtimeService;
+
+	private Timer timer = null;
+
+	private Map<Long, StatemachineTimerTask> timerTasks = new HashMap<Long, StatemachineTimerTask>();
+
+	private class StatemachineTimerTask extends TimerTask {
+
+		private List<IStatemachine> statemachineList = new LinkedList<IStatemachine>();
+
+		private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+
+		private boolean isPaused = false;
+
+		@Override
+		public void run() {
+			lock.readLock().lock();
+			if (!isPaused) {
+				for (IStatemachine statemachine : statemachineList) {
+					statemachine.runCycle();
+				}
+			}
+			lock.readLock().unlock();
+		}
+
+		/**
+		 * Adds the given state machine to the TimerTask.
+		 * 
+		 * @param statemachine
+		 * @return {@code true} if state machine is added properly.
+		 */
+		public boolean addStatemachine(IStatemachine statemachine) {
+			lock.writeLock().lock();
+			boolean ret = statemachineList.add(statemachine);
+			lock.writeLock().unlock();
+			return ret;
+		}
+
+		/**
+		 * Removes the given state machine from the TimerTask.
+		 * 
+		 * @param statemachine
+		 * @return {@code true} if state machine is removed properly.
+		 */
+		public boolean removeStatemachine(IStatemachine statemachine) {
+			lock.writeLock().lock();
+			boolean ret = statemachineList.remove(statemachine);
+			lock.writeLock().unlock();
+			return ret;
+		}
+
+		public void pause() {
+			isPaused = true;
+		}
+
+		public void resume() {
+			isPaused = false;
+		}
+	}
+
+	private RuntimeService() {
+		// Not intended to be instantiated.
+	}
+
+	/**
+	 * Returns the {@code RuntimeService} instance as singleton.
+	 * 
+	 * @return The singleton {@code RuntimeService} instance
+	 */
+	public static RuntimeService getInstance() {
+		if (runtimeService == null) {
+			runtimeService = new RuntimeService();
+		}
+		return runtimeService;
+	}
+
+	/**
+	 * Registers an {@link IStatemachine} for scheduled fixed rate execution
+	 * 
+	 * @param statemachine
+	 *            - The statemachine to execute
+	 * @param cyclePeriod
+	 *            - the fixed rate cycle period for scheduling
+	 * @return {@code true} if state machine is added properly.
+	 */
+	public boolean registerStatemachine(IStatemachine statemachine,
+			long cyclePeriod) {
+
+		if (timerTasks.containsKey(cyclePeriod)) {
+			// TimerTask for cycle time already existing -> add statemachine
+			return timerTasks.get(cyclePeriod).addStatemachine(statemachine);
+		} else {
+			// Create new TimerTask for cycle period and add statemachine
+			StatemachineTimerTask timerTask = new StatemachineTimerTask();
+			timerTasks.put(cyclePeriod, timerTask);
+			boolean ret = timerTask.addStatemachine(statemachine);
+			// Create a new Timer instance if runtime service was cancelled
+			// before
+			if (timer == null) {
+				timer = new Timer();
+			}
+			timer.scheduleAtFixedRate(timerTask, 0, cyclePeriod);
+			return ret;
+		}
+	}
+
+	/**
+	 * Removes the given state machine from runtime service.
+	 * 
+	 * @param statemachine
+	 *            - the statemachine which should be removed
+	 * @param cyclePeriod
+	 *            - the scheduling cycle period of the statemachine
+	 * @return {@code true} if state machine is removed properly.
+	 */
+	public boolean unregisterStatemachine(IStatemachine statemachine,
+			long cyclePeriod) {
+		if (timerTasks.containsKey(cyclePeriod)) {
+			boolean ret = timerTasks.get(cyclePeriod).removeStatemachine(
+					statemachine);
+
+			return ret;
+		}
+		return false;
+	}
+
+	/**
+	 * Cancels the execution of statemachines for the given cycle period. This
+	 * stops the execution of statemachines which are registered for the given
+	 * cycle period and cancels the executing {@link TimerTask}.
+	 * 
+	 * @return {@code true} if poperly cancelled
+	 */
+	public boolean cancelAll(long cyclePeriod) {
+		if (timer != null && timerTasks.containsKey(cyclePeriod)) {
+			TimerTask task = timerTasks.get(cyclePeriod);
+			task.cancel();
+			timer.purge();
+			timerTasks.remove(cyclePeriod);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Pauses the execution of all statemachines which are registered for the
+	 * given cyclePeriod.
+	 * 
+	 * @param cyclePeriod
+	 * @return {@code true} if properly paused
+	 * 
+	 */
+	public boolean pauseAll(long cyclePeriod) {
+		if (timerTasks.containsKey(cyclePeriod)) {
+			timerTasks.get(cyclePeriod).pause();
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Resumes the execution of all statemachines which are registered for the
+	 * given cyclePeriod.
+	 * 
+	 * @param cyclePeriod
+	 * @return {@code true} if properly resumed
+	 * 
+	 */
+	public boolean resumeAll(long cyclePeriod) {
+		if (timerTasks.containsKey(cyclePeriod)) {
+			timerTasks.get(cyclePeriod).resume();
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Cancels the execution of all registered statemachines. This cancels the
+	 * executing {@link Timer} freeing all allocated resources and terminates
+	 * all existing execution threads.
+	 */
+	public void cancelTimer() {
+		if (timer != null) {
+			timer.cancel();
+			timer.purge();
+			timerTasks.clear();
+			timer = null;
+		}
+	}
+}

+ 91 - 0
examples/trafficlight_example/src-gen/org/yakindu/scr/TimerService.java

@@ -0,0 +1,91 @@
+package org.yakindu.scr;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * Default timer service implementation.
+ * 
+ */
+public class TimerService implements ITimer {
+
+	private final Timer timer = new Timer();
+	
+	private final List<TimeEventTask> timerTaskList = new ArrayList<TimeEventTask>();
+	
+	/**
+	 * Timer task that reflects a time event. It's internally used by
+	 * {@link TimerService}.
+	 * 
+	 */
+	private class TimeEventTask extends TimerTask {
+	
+		private ITimerCallback callback;
+	
+		int eventID;
+	
+		/**
+		 * Constructor for a time event.
+		 * 
+		 * @param callback
+		 *            : Set to {@code true} if event should be repeated
+		 *            periodically.
+		 * 
+		 * @param eventID
+		 *            : Index position within the state machine's timeEvent
+		 *            array.
+		 */
+		public TimeEventTask(ITimerCallback callback, int eventID) {
+			this.callback = callback;
+			this.eventID = eventID;
+		}
+	
+		public void run() {
+			callback.timeElapsed(eventID);
+		}
+	
+		public boolean equals(Object obj) {
+			if (obj instanceof TimeEventTask) {
+				return ((TimeEventTask) obj).callback.equals(callback)
+						&& ((TimeEventTask) obj).eventID == eventID;
+			}
+			return super.equals(obj);
+		}
+	}
+	
+	public void setTimer(final ITimerCallback callback, final int eventID,
+			long time, boolean isPeriodic) {
+	
+		// Create a new TimerTask for given event and store it.
+		TimeEventTask timerTask = new TimeEventTask(callback, eventID);
+		timerTaskList.add(timerTask);
+	
+		// start scheduling the timer
+		if (isPeriodic) {
+			timer.scheduleAtFixedRate(timerTask, time, time);
+		} else {
+			timer.schedule(timerTask, time);
+		}
+	}
+	
+	public void unsetTimer(ITimerCallback callback, int eventID) {
+		int index = timerTaskList.indexOf(new TimeEventTask(callback, eventID));
+		if (index != -1) {
+			timerTaskList.get(index).cancel();
+			timer.purge();
+			timerTaskList.remove(index);
+		}
+	}
+	
+	/**
+	 * Cancel timer service. Use this to end possible timing threads and free
+	 * memory resources.
+	 */
+	public void cancel() {
+		timer.cancel();
+		timer.purge();
+	}
+}
+

+ 38 - 0
examples/trafficlight_example/src-gen/org/yakindu/scr/trafficlightwaiting/ITrafficLightWaitingStatemachine.java

@@ -0,0 +1,38 @@
+package org.yakindu.scr.trafficlightwaiting;
+import org.yakindu.scr.IStatemachine;
+import org.yakindu.scr.ITimerCallback;
+
+public interface ITrafficLightWaitingStatemachine extends ITimerCallback, IStatemachine {
+	public interface SCITrafficLight {
+		public boolean getRed();
+		public void setRed(boolean value);
+		public boolean getYellow();
+		public void setYellow(boolean value);
+		public boolean getGreen();
+		public void setGreen(boolean value);
+
+	}
+
+	public SCITrafficLight getSCITrafficLight();
+
+	public interface SCIPedestrian {
+		public boolean getRequest();
+		public void setRequest(boolean value);
+		public boolean getRed();
+		public void setRed(boolean value);
+		public boolean getGreen();
+		public void setGreen(boolean value);
+
+	}
+
+	public SCIPedestrian getSCIPedestrian();
+
+	public interface SCInterface {
+		public void raisePedestrianRequest();
+		public void raiseOnOff();
+
+	}
+
+	public SCInterface getSCInterface();
+
+}

Plik diff jest za duży
+ 1111 - 0
examples/trafficlight_example/src-gen/org/yakindu/scr/trafficlightwaiting/TrafficLightWaitingStatemachine.java


+ 39 - 0
examples/trafficlight_example/src/org/yakindu/scr/IStatemachine.java

@@ -0,0 +1,39 @@
+package org.yakindu.scr;
+
+/**
+ * Basic interface for statemachines.
+ */
+public interface IStatemachine {
+
+	/**
+	 * Initializes the statemachine. Use to init internal variables etc.
+	 */
+	public void init();
+
+	/**
+	 * Enters the statemachine. Sets the statemachine in a defined state.
+	 */
+	public void enter();
+
+	/**
+	 * Exits the statemachine. Leaves the statemachine with a defined state.
+	 */
+	public void exit();
+
+	/**
+	 * Checks if the statemachine is active. 
+	 * A statemachine is active if it was entered. It is inactive if it has not been entered at all or if it was exited.
+	 */
+	public boolean isActive();
+
+	/**
+	 * Checks if all active states are final. 
+	 * If there are no active states then the statemachine is considered as incative and this method returns false.
+	 */
+	public boolean isFinal();
+
+	/**
+	* Start a run-to-completion cycle.
+	*/
+	public void runCycle();
+}

+ 38 - 0
examples/trafficlight_example/src/org/yakindu/scr/ITimer.java

@@ -0,0 +1,38 @@
+package org.yakindu.scr;
+
+/**
+ * Interface a timer has to implement. Use to implement your own timer
+ * service.
+ * 
+ */
+public interface ITimer {
+
+	/**
+	 * Starts the timing for a given time event id.
+	 * 
+	 * @param callback
+	 * 			  : The target callback where the time event has to be raised.
+	 * 
+	 * @param eventID
+	 *            : The eventID the timer should use if timed out.
+	 *            
+	 * @param time
+	 *            : Time in milliseconds after the given time event should be
+	 *            triggered
+	 *            
+	 * @param isPeriodic
+	 * 			  : Set to true if the time event should be triggered periodically
+	 */
+	public void setTimer(ITimerCallback callback, int eventID, long time, boolean isPeriodic);
+
+	/**
+	 * Unset a time event.
+	 * 
+	 * @param callback
+	 * 			: The target callback for which the time event has to be unset.
+	 * 
+	 * @param eventID
+	 * 			: The time event id.
+	 */
+	public void unsetTimer(ITimerCallback callback, int eventID);
+}

+ 15 - 0
examples/trafficlight_example/src/org/yakindu/scr/ITimerCallback.java

@@ -0,0 +1,15 @@
+package org.yakindu.scr;
+
+/**
+* Interface for state machines which use timed event triggers.
+*/
+public interface ITimerCallback {
+	
+	/**
+	* Callback method if a time event occurred.
+	* 
+	* @param eventID
+	* 			:The id of the occurred event.
+	*/
+	public void timeElapsed(int eventID);
+}

+ 51 - 0
examples/trafficlight_example/src/trafficlight_example/ButtonPanel.java

@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2016 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 trafficlight_example;
+
+import java.awt.BorderLayout;
+
+import javax.swing.JButton;
+import javax.swing.JPanel;
+
+/**
+ * 
+ * @author Tesch
+ *
+ */
+
+public class ButtonPanel extends JPanel {
+
+	private static final long serialVersionUID = 1L;
+	private JButton pedestrianRequest;
+	private JButton onOff;
+
+	public ButtonPanel() {
+		createContents();
+	}
+
+	private void createContents() {
+		pedestrianRequest = new JButton();
+		pedestrianRequest.setText("pedestrain request");
+		add(BorderLayout.SOUTH, pedestrianRequest);
+		onOff = new JButton();
+		onOff.setText("on / off");
+		add(BorderLayout.SOUTH, onOff);
+	}
+
+	public JButton getPedestrianRequest() {
+		return pedestrianRequest;
+	}
+
+	public JButton getOnOff() {
+		return onOff;
+	}
+
+}

+ 141 - 0
examples/trafficlight_example/src/trafficlight_example/CrossingPanel.java

@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2016 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 trafficlight_example;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Point;
+
+import javax.swing.JPanel;
+
+import trafficlight_example.TrafficLight.Alignment;
+
+/**
+ * 
+ * @author Tesch
+ *
+ */
+
+public class CrossingPanel extends JPanel {
+
+	private static final long serialVersionUID = 2709756259645789247L;
+	private TrafficLight light1;
+	private TrafficLight light2;
+	private TrafficLight light3;
+	private TrafficLight light4;
+	private PedestrianLight light5;
+	private PedestrianLight light6;
+
+	public CrossingPanel() {
+		light1 = new TrafficLight(Alignment.HORIZONTAL);
+		light2 = new TrafficLight(Alignment.VERTICAL);
+		light3 = new TrafficLight(Alignment.HORIZONTAL);
+		light4 = new TrafficLight(Alignment.VERTICAL);
+		light5 = new PedestrianLight(trafficlight_example.PedestrianLight.Alignment.HORIZONTAL);
+		light6 = new PedestrianLight(trafficlight_example.PedestrianLight.Alignment.VERTICAL);
+	}
+
+	public void paint(Graphics g) {
+		paintCrossing(g);
+		paintTrafficLights(g);
+		paintPedestrainLights(g);
+		g.dispose();
+	}
+
+	private void paintTrafficLights(Graphics g) {
+		light1.updatePosition(new Point(25, 150));
+		light1.paint(g);
+
+		light2.updatePosition(new Point(350, 25));
+		light2.paint(g);
+
+		light3.updatePosition(new Point(425, 350));
+		light3.paint(g);
+
+		light4.updatePosition(new Point(150, 425));
+		light4.paint(g);
+	}
+
+	private void paintPedestrainLights(Graphics g) {
+		light5.updatePosition(new Point(175, 25));
+		light5.paint(g);
+
+		light6.updatePosition(new Point(475, 175));
+		light6.paint(g);
+	}
+
+	private void paintCrossing(Graphics g) {
+
+		int breite = getSize().width;
+		int hoehe = getSize().height;
+
+		g.setColor(Color.darkGray);
+		g.fillRect(225, 0, 100, hoehe);
+
+		g.setColor(Color.darkGray);
+		g.fillRect(0, 225, breite, 100);
+
+		g.setColor(Color.white);
+		g.fillRect(270, 0, 10, hoehe);
+
+		g.setColor(Color.white);
+		g.fillRect(0, 270, breite, 10);
+
+		g.setColor(Color.darkGray);
+		g.fillRect(225, 225, 100, 100);
+
+		g.setColor(Color.white);
+		g.fillRect(225, 225, 100, 100);
+
+		g.setColor(Color.darkGray);
+		g.fillRect(235, 235, 80, 80);
+
+		g.setColor(Color.white);
+
+		g.fillRect(230, 30, 10, 50);
+		g.fillRect(230 + 20, 30, 10, 50);
+		g.fillRect(230 + 40, 30, 10, 50);
+		g.fillRect(230 + 60, 30, 10, 50);
+		g.fillRect(230 + 80, 30, 10, 50);
+
+		g.setColor(Color.white);
+		g.fillRect(475, 230, 50, 10);
+		g.fillRect(475, 230 + 20, 50, 10);
+		g.fillRect(475, 230 + 40, 50, 10);
+		g.fillRect(475, 230 + 60, 50, 10);
+		g.fillRect(475, 230 + 80, 50, 10);
+
+	}
+
+	public TrafficLight getLight1() {
+		return light1;
+	}
+
+	public TrafficLight getLight2() {
+		return light2;
+	}
+
+	public TrafficLight getLight3() {
+		return light3;
+	}
+
+	public TrafficLight getLight4() {
+		return light4;
+	}
+
+	public PedestrianLight getLight5() {
+		return light5;
+	}
+
+	public PedestrianLight getLight6() {
+		return light6;
+	}
+}

+ 123 - 0
examples/trafficlight_example/src/trafficlight_example/PedestrianLight.java

@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016 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 trafficlight_example;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import javax.swing.JPanel;
+
+/**
+ * 
+ * @author Tesch
+ *
+ */
+
+public class PedestrianLight extends JPanel {
+
+	private static final long serialVersionUID = 1L;
+
+	boolean white = false;
+	boolean red = false;
+	boolean green = false;
+	private Alignment alignment;
+
+	public enum Alignment {
+		HORIZONTAL(25, 50), VERTICAL(50, 25);
+
+		private int width;
+		private int height;
+
+		Alignment(int width, int height) {
+			this.width = width;
+			this.height = height;
+		}
+
+		public int getWidth() {
+			return width;
+		}
+
+		public int getHeight() {
+			return height;
+		}
+
+	}
+
+	public PedestrianLight(Alignment alignment) {
+		this.alignment = alignment;
+	}
+
+	public boolean isWhite() {
+		return white;
+	}
+
+	public void setWhite(boolean white) {
+		this.white = white;
+	}
+
+	public boolean isRed() {
+		return red;
+	}
+
+	public void setRed(boolean red) {
+		this.red = red;
+	}
+
+	public boolean isGreen() {
+		return green;
+	}
+
+	public void setGreen(boolean green) {
+		this.green = green;
+	}
+
+	public void updatePosition(Point position) {
+		setBounds(new Rectangle(position.x, position.y, alignment.getWidth(), alignment.getHeight()));
+	}
+
+	@Override
+	public void paint(Graphics graphics) {
+		Rectangle bounds = getBounds();
+		graphics.setColor(Color.black);
+		graphics.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
+
+		if (alignment == Alignment.VERTICAL) {
+
+			graphics.setColor(white ? Color.white : Color.black);
+			graphics.fillRect(bounds.x + ((bounds.width - (3 * (bounds.height / 3))) / 4),
+					bounds.y + ((bounds.width - (3 * (bounds.height / 3))) / 4), bounds.width / 4, bounds.width / 4);
+
+			graphics.setColor(red ? Color.red : Color.black);
+			graphics.fillOval(bounds.x + (2 * ((bounds.width - (3 * (bounds.height / 3))) / 4)) + (bounds.height / 3),
+					bounds.y + ((bounds.width - (3 * (bounds.height / 3))) / 4), bounds.width / 4, bounds.width / 4);
+
+			graphics.setColor(green ? Color.green : Color.black);
+			graphics.fillOval(
+					bounds.x + (3 * ((bounds.width - (3 * (bounds.height / 3))) / 4)) + (2 * (bounds.height / 3)),
+					bounds.y + ((bounds.width - (3 * (bounds.height / 3))) / 4), bounds.width / 4, bounds.width / 4);
+
+		} else if (alignment == Alignment.HORIZONTAL) {
+
+			graphics.setColor(white ? Color.white : Color.black);
+			graphics.fillRect(bounds.x + 7, bounds.y + 2, bounds.height / 4, bounds.height / 4);
+
+			graphics.setColor(red ? Color.red : Color.black);
+			graphics.fillOval(bounds.x + 7, bounds.y + 2 * bounds.height / 5, bounds.height / 4, bounds.height / 4);
+
+			graphics.setColor(green ? Color.green : Color.black);
+			graphics.fillOval((bounds.x + (bounds.width / 2) - ((bounds.height / 5) / 2)),
+					bounds.y + bounds.height - (bounds.height / 5) - 5, bounds.height / 4, bounds.height / 4);
+		}
+	}
+
+}

+ 123 - 0
examples/trafficlight_example/src/trafficlight_example/TrafficLight.java

@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016 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 trafficlight_example;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+
+import javax.swing.JPanel;
+
+/**
+ * 
+ * @author Tesch
+ *
+ */
+
+public class TrafficLight extends JPanel {
+
+	private boolean red = false;
+	private boolean yellow = false;
+	private boolean green = false;
+	private Alignment alignment;
+
+	public enum Alignment {
+		HORIZONTAL(100, 50), VERTICAL(50, 100);
+
+		private int width;
+		private int height;
+
+		Alignment(int width, int height) {
+			this.width = width;
+			this.height = height;
+		}
+
+		public int getWidth() {
+			return width;
+		}
+
+		public int getHeight() {
+			return height;
+		}
+
+	}
+
+	public TrafficLight(Alignment alignment) {
+		this.alignment = alignment;
+	}
+
+	public boolean isRed() {
+		return red;
+	}
+
+	public void setRed(boolean red) {
+		this.red = red;
+	}
+
+	public boolean isYellow() {
+		return yellow;
+	}
+
+	public void setYellow(boolean yellow) {
+		this.yellow = yellow;
+	}
+
+	public boolean isGreen() {
+		return green;
+	}
+
+	public void setGreen(boolean green) {
+		this.green = green;
+	}
+
+	private static final long serialVersionUID = 1L;
+
+	public void updatePosition(Point position) {
+		setBounds(new Rectangle(position.x, position.y, alignment.getWidth(), alignment.getHeight()));
+	}
+
+	@Override
+	public void paint(Graphics graphics) {
+		Rectangle bounds = getBounds();
+		graphics.setColor(Color.black);
+		graphics.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
+		
+		if (alignment == Alignment.VERTICAL) {
+
+			graphics.setColor(red ? Color.red : Color.black);
+			graphics.fillOval(bounds.x + 15, bounds.y + 5, bounds.height / 5, bounds.height / 5);
+
+			graphics.setColor(yellow ? Color.yellow : Color.black);
+			graphics.fillOval(bounds.x + 15, bounds.y + 2 * bounds.height / 5, bounds.height / 5, bounds.height / 5);
+
+			graphics.setColor(green ? Color.green : Color.black);
+			graphics.fillOval(bounds.x + (bounds.width / 2) - ((bounds.height / 5) / 2),
+					bounds.y + bounds.height - (bounds.height / 5) - 5, bounds.height / 5, bounds.height / 5);
+
+		} else if (alignment == Alignment.HORIZONTAL) {
+
+			graphics.setColor(red ? Color.red : Color.black);
+			graphics.fillOval(bounds.x + ((bounds.width - (3 * (bounds.height / 3))) / 4),
+					bounds.y + ((bounds.width - (3 * (bounds.height / 3))) / 4), bounds.width / 5, bounds.width / 5);
+
+			graphics.setColor(yellow ? Color.yellow : Color.black);
+			graphics.fillOval(bounds.x + (2 * ((bounds.width - (3 * (bounds.height / 3))) / 4)) + (bounds.height / 3),
+					bounds.y + ((bounds.width - (3 * (bounds.height / 3))) / 4), bounds.width / 5, bounds.width / 5);
+
+			graphics.setColor(green ? Color.green : Color.black);
+			graphics.fillOval(bounds.x + (3 * ((bounds.width - (3 * (bounds.height / 3))) / 4)) + (2 * (bounds.height / 3)),
+					bounds.y + ((bounds.width - (3 * (bounds.height / 3))) / 4), bounds.width / 5, bounds.width / 5);
+
+		}
+	}
+
+}

+ 108 - 0
examples/trafficlight_example/src/trafficlight_example/TrafficlightDemo.java

@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2016 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 trafficlight_example;
+
+import java.awt.BorderLayout;
+import java.awt.Graphics;
+
+import javax.swing.JFrame;
+
+import org.yakindu.scr.RuntimeService;
+import org.yakindu.scr.TimerService;
+import org.yakindu.scr.trafficlightwaiting.TrafficLightWaitingStatemachine;
+
+/**
+ * 
+ * @author Tesch
+ *
+ */
+
+public class TrafficlightDemo extends JFrame {
+
+	private static final long serialVersionUID = -8909693541678814631L;
+
+	protected TrafficLightWaitingStatemachine statemachine;
+
+	protected TimerService timer;
+
+	private CrossingPanel crossing;
+
+	private ButtonPanel buttonPanel;
+
+	public static void main(String[] args) {
+		TrafficlightDemo application = new TrafficlightDemo();
+		application.createContents();
+		application.setupStatemachine();
+		application.run();
+	}
+
+	protected void run() {
+		statemachine.enter();
+		RuntimeService.getInstance().registerStatemachine(statemachine, 100);
+		while (isVisible()) {
+			checkTrafficLightStates();
+			repaint();
+		}
+	}
+
+	protected void createContents() {
+		setLayout(new BorderLayout());
+		setTitle("CycleBasedDemo");
+		crossing = new CrossingPanel();
+		add(BorderLayout.CENTER, crossing);
+		buttonPanel = new ButtonPanel();
+		add(BorderLayout.SOUTH, buttonPanel);
+		setSize(600, 600);
+		setVisible(true);
+	}
+
+	@Override
+	public void paint(Graphics g) {
+		super.paint(g);
+	}
+
+	protected void setupStatemachine() {
+		statemachine = new TrafficLightWaitingStatemachine();
+		timer = new TimerService();
+		statemachine.setTimer(timer);
+		statemachine.init();
+
+		buttonPanel.getPedestrianRequest()
+				.addActionListener(e -> statemachine.getSCInterface().raisePedestrianRequest());
+		buttonPanel.getOnOff().addActionListener(e -> statemachine.getSCInterface().raiseOnOff());
+	}
+
+	protected void checkTrafficLightStates() {
+		crossing.getLight1().setRed(statemachine.getSCITrafficLight().getRed());
+		crossing.getLight1().setYellow(statemachine.getSCITrafficLight().getYellow());
+		crossing.getLight1().setGreen(statemachine.getSCITrafficLight().getGreen());
+
+		crossing.getLight3().setRed(statemachine.getSCITrafficLight().getRed());
+		crossing.getLight3().setYellow(statemachine.getSCITrafficLight().getYellow());
+		crossing.getLight3().setGreen(statemachine.getSCITrafficLight().getGreen());
+
+		crossing.getLight2().setGreen(statemachine.getSCITrafficLight().getRed());
+		crossing.getLight2().setYellow(statemachine.getSCITrafficLight().getYellow());
+		crossing.getLight2().setRed(statemachine.getSCITrafficLight().getGreen());
+
+		crossing.getLight4().setGreen(statemachine.getSCITrafficLight().getRed());
+		crossing.getLight4().setYellow(statemachine.getSCITrafficLight().getYellow());
+		crossing.getLight4().setRed(statemachine.getSCITrafficLight().getGreen());
+
+		crossing.getLight5().setGreen(statemachine.getSCIPedestrian().getRed());
+		crossing.getLight5().setRed(statemachine.getSCIPedestrian().getGreen());
+		crossing.getLight5().setWhite(statemachine.getSCIPedestrian().getRequest());
+
+		crossing.getLight6().setRed(statemachine.getSCIPedestrian().getRed());
+		crossing.getLight6().setGreen(statemachine.getSCIPedestrian().getGreen());
+		crossing.getLight6().setWhite(statemachine.getSCIPedestrian().getRequest());
+	}
+}