SynchronizedTrafficLightCtrlStatemachine.java 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. package traffic.light.trafficlightctrl;
  2. import java.util.List;
  3. import traffic.light.ITimer;
  4. import traffic.light.ITimerCallback;
  5. import traffic.light.trafficlightctrl.TrafficLightCtrlStatemachine.State;
  6. /**
  7. * Runnable wrapper of TrafficLightCtrlStatemachine. This wrapper provides a thread-safe
  8. * instance of the state machine.
  9. *
  10. * Please report bugs and issues...
  11. */
  12. public class SynchronizedTrafficLightCtrlStatemachine implements ITrafficLightCtrlStatemachine {
  13. /**
  14. * The core state machine is simply wrapped and the event processing will be
  15. * delegated to that state machine instance. This instance will be created
  16. * implicitly.
  17. */
  18. protected TrafficLightCtrlStatemachine statemachine = new TrafficLightCtrlStatemachine();
  19. /**
  20. * Interface object for SCInterface
  21. */
  22. protected class SynchronizedSCInterface implements SCInterface {
  23. public void raisePolice_interrupt() {
  24. synchronized (statemachine) {
  25. statemachine.getSCInterface().raisePolice_interrupt();
  26. statemachine.runCycle();
  27. }
  28. }
  29. public void raiseToggle() {
  30. synchronized (statemachine) {
  31. statemachine.getSCInterface().raiseToggle();
  32. statemachine.runCycle();
  33. }
  34. }
  35. };
  36. protected SCInterface sCInterface;
  37. /**
  38. * Interface object for SCITrafficLight
  39. */
  40. protected class SynchronizedSCITrafficLight implements SCITrafficLight {
  41. public List<SCITrafficLightListener> getListeners() {
  42. synchronized(statemachine) {
  43. return statemachine.getSCITrafficLight().getListeners();
  44. }
  45. }
  46. public boolean isRaisedDisplayRed() {
  47. synchronized(statemachine) {
  48. return statemachine.getSCITrafficLight().isRaisedDisplayRed();
  49. }
  50. }
  51. public boolean isRaisedDisplayGreen() {
  52. synchronized(statemachine) {
  53. return statemachine.getSCITrafficLight().isRaisedDisplayGreen();
  54. }
  55. }
  56. public boolean isRaisedDisplayYellow() {
  57. synchronized(statemachine) {
  58. return statemachine.getSCITrafficLight().isRaisedDisplayYellow();
  59. }
  60. }
  61. public boolean isRaisedDisplayNone() {
  62. synchronized(statemachine) {
  63. return statemachine.getSCITrafficLight().isRaisedDisplayNone();
  64. }
  65. }
  66. };
  67. protected SCITrafficLight sCITrafficLight;
  68. /**
  69. * Interface object for SCITimer
  70. */
  71. protected class SynchronizedSCITimer implements SCITimer {
  72. public List<SCITimerListener> getListeners() {
  73. synchronized(statemachine) {
  74. return statemachine.getSCITimer().getListeners();
  75. }
  76. }
  77. public boolean isRaisedUpdateTimerColour() {
  78. synchronized(statemachine) {
  79. return statemachine.getSCITimer().isRaisedUpdateTimerColour();
  80. }
  81. }
  82. public String getUpdateTimerColourValue() {
  83. synchronized(statemachine) {
  84. return statemachine.getSCITimer().getUpdateTimerColourValue();
  85. }
  86. }
  87. public boolean isRaisedUpdateTimerValue() {
  88. synchronized(statemachine) {
  89. return statemachine.getSCITimer().isRaisedUpdateTimerValue();
  90. }
  91. }
  92. public long getUpdateTimerValueValue() {
  93. synchronized(statemachine) {
  94. return statemachine.getSCITimer().getUpdateTimerValueValue();
  95. }
  96. }
  97. };
  98. protected SCITimer sCITimer;
  99. public SynchronizedTrafficLightCtrlStatemachine() {
  100. sCInterface = new SynchronizedSCInterface();
  101. sCITrafficLight = new SynchronizedSCITrafficLight();
  102. sCITimer = new SynchronizedSCITimer();
  103. }
  104. public synchronized SCInterface getSCInterface() {
  105. return sCInterface;
  106. }
  107. public synchronized SCITrafficLight getSCITrafficLight() {
  108. return sCITrafficLight;
  109. }
  110. public synchronized SCITimer getSCITimer() {
  111. return sCITimer;
  112. }
  113. /*================ TIME EVENT HANDLING ================
  114. /** An external timer instance is required. */
  115. protected ITimer externalTimer;
  116. /** Internally we use a timer proxy that queues time events together with other input events. */
  117. protected ITimer timerProxy = new ITimer() {
  118. /** Simply delegate to external timer with a modified callback. */
  119. @Override
  120. public void setTimer(ITimerCallback callback, int eventID, long time,
  121. boolean isPeriodic) {
  122. externalTimer.setTimer(SynchronizedTrafficLightCtrlStatemachine.this, eventID, time, isPeriodic);
  123. }
  124. @Override
  125. public void unsetTimer(ITimerCallback callback, int eventID) {
  126. externalTimer.unsetTimer(SynchronizedTrafficLightCtrlStatemachine.this, eventID);
  127. }
  128. };
  129. /**
  130. * Set the {@link ITimer} for the state machine. It must be set externally
  131. * on a timed state machine before a run cycle can be correct executed.
  132. *
  133. * @param timer
  134. */
  135. public void setTimer(ITimer timer) {
  136. synchronized(statemachine) {
  137. this.externalTimer = timer;
  138. /* the wrapped state machine uses timer proxy as timer */
  139. statemachine.setTimer(timerProxy);
  140. }
  141. }
  142. /**
  143. * Returns the currently used timer.
  144. *
  145. * @return {@link ITimer}
  146. */
  147. public ITimer getTimer() {
  148. return externalTimer;
  149. }
  150. public void timeElapsed(int eventID) {
  151. synchronized (statemachine) {
  152. statemachine.timeElapsed(eventID);
  153. }
  154. }
  155. /**
  156. * init() will be delegated thread-safely to the wrapped state machine.
  157. */
  158. public void init() {
  159. synchronized(statemachine) {
  160. statemachine.init();
  161. }
  162. }
  163. /**
  164. * enter() will be delegated thread-safely to the wrapped state machine.
  165. */
  166. public void enter() {
  167. synchronized(statemachine) {
  168. statemachine.enter();
  169. }
  170. }
  171. /**
  172. * exit() will be delegated thread-safely to the wrapped state machine.
  173. */
  174. public void exit() {
  175. synchronized(statemachine) {
  176. statemachine.exit();
  177. }
  178. }
  179. /**
  180. * isActive() will be delegated thread-safely to the wrapped state machine.
  181. */
  182. public boolean isActive() {
  183. synchronized(statemachine) {
  184. return statemachine.isActive();
  185. }
  186. }
  187. /**
  188. * isFinal() will be delegated thread-safely to the wrapped state machine.
  189. */
  190. public boolean isFinal() {
  191. synchronized(statemachine) {
  192. return statemachine.isFinal();
  193. }
  194. }
  195. /**
  196. * isStateActive() will be delegated thread-safely to the wrapped state machine.
  197. */
  198. public boolean isStateActive(State state) {
  199. synchronized(statemachine) {
  200. return statemachine.isStateActive(state);
  201. }
  202. }
  203. /**
  204. * runCycle() will be delegated thread-safely to the wrapped state machine.
  205. */
  206. @Override
  207. public void runCycle() {
  208. synchronized (statemachine) {
  209. statemachine.runCycle();
  210. }
  211. }
  212. }