package org.yakindu.scr.runnabletest; import java.util.List; import org.yakindu.scr.ITimer; import org.yakindu.scr.ITimerCallback; import org.yakindu.scr.runnabletest.RunnableTestStatemachine.State; /** * Runnable wrapper of RunnableTestStatemachine. This wrapper provides a thread-safe * instance of the state machine. * * Please report bugs and issues... */ public class SynchronizedRunnableTestStatemachine implements IRunnableTestStatemachine { /** * The core state machine is simply wrapped and the event processing will be * delegated to that state machine instance. This instance will be created * implicitly. */ protected RunnableTestStatemachine statemachine = new RunnableTestStatemachine(); /** * Interface object for SCInterface */ protected class SynchronizedSCInterface implements SCInterface { public List<SCInterfaceListener> getListeners() { synchronized(statemachine) { return statemachine.getSCInterface().getListeners(); } } public void setSCInterfaceOperationCallback(SCInterfaceOperationCallback operationCallback) { synchronized(statemachine) { statemachine.getSCInterface().setSCInterfaceOperationCallback(operationCallback); } } public boolean isRaisedEv_out() { synchronized(statemachine) { return statemachine.getSCInterface().isRaisedEv_out(); } } public long getEv_outValue() { synchronized(statemachine) { return statemachine.getSCInterface().getEv_outValue(); } } public void raiseEv_in(final long value) { synchronized (statemachine) { statemachine.getSCInterface().raiseEv_in(value); statemachine.runCycle(); } } public long getMyVar() { synchronized(statemachine) { return statemachine.getSCInterface().getMyVar(); } } public void setMyVar(final long value) { synchronized(statemachine) { statemachine.getSCInterface().setMyVar(value); } } public long getAfterCalls() { synchronized(statemachine) { return statemachine.getSCInterface().getAfterCalls(); } } public void setAfterCalls(final long value) { synchronized(statemachine) { statemachine.getSCInterface().setAfterCalls(value); } } public long getCycles() { synchronized(statemachine) { return statemachine.getSCInterface().getCycles(); } } public void setCycles(final long value) { synchronized(statemachine) { statemachine.getSCInterface().setCycles(value); } } public long getS2_entered() { synchronized(statemachine) { return statemachine.getSCInterface().getS2_entered(); } } public void setS2_entered(final long value) { synchronized(statemachine) { statemachine.getSCInterface().setS2_entered(value); } } }; protected SCInterface sCInterface; public SynchronizedRunnableTestStatemachine() { sCInterface = new SynchronizedSCInterface(); } public synchronized SCInterface getSCInterface() { return sCInterface; } /*================ TIME EVENT HANDLING ================ /** An external timer instance is required. */ protected ITimer externalTimer; /** Internally we use a timer proxy that queues time events together with other input events. */ protected ITimer timerProxy = new ITimer() { /** Simply delegate to external timer with a modified callback. */ @Override public void setTimer(ITimerCallback callback, int eventID, long time, boolean isPeriodic) { externalTimer.setTimer(SynchronizedRunnableTestStatemachine.this, eventID, time, isPeriodic); } @Override public void unsetTimer(ITimerCallback callback, int eventID) { externalTimer.unsetTimer(SynchronizedRunnableTestStatemachine.this, eventID); } }; /** * Set the {@link ITimer} for the state machine. It must be set externally * on a timed state machine before a run cycle can be correct executed. * * @param timer */ public void setTimer(ITimer timer) { synchronized(statemachine) { this.externalTimer = timer; /* the wrapped state machine uses timer proxy as timer */ statemachine.setTimer(timerProxy); } } /** * Returns the currently used timer. * * @return {@link ITimer} */ public ITimer getTimer() { return externalTimer; } public void timeElapsed(int eventID) { synchronized (statemachine) { statemachine.timeElapsed(eventID); } } /** * init() will be delegated thread-safely to the wrapped state machine. */ public void init() { synchronized(statemachine) { statemachine.init(); } } /** * enter() will be delegated thread-safely to the wrapped state machine. */ public void enter() { synchronized(statemachine) { statemachine.enter(); } } /** * exit() will be delegated thread-safely to the wrapped state machine. */ public void exit() { synchronized(statemachine) { statemachine.exit(); } } /** * isActive() will be delegated thread-safely to the wrapped state machine. */ public boolean isActive() { synchronized(statemachine) { return statemachine.isActive(); } } /** * isFinal() will be delegated thread-safely to the wrapped state machine. */ public boolean isFinal() { synchronized(statemachine) { return statemachine.isFinal(); } } /** * isStateActive() will be delegated thread-safely to the wrapped state machine. */ public boolean isStateActive(State state) { synchronized(statemachine) { return statemachine.isStateActive(state); } } /** * runCycle() will be delegated thread-safely to the wrapped state machine. */ @Override public void runCycle() { synchronized (statemachine) { statemachine.runCycle(); } } }