package algorithm; /** * controls the execution of an {@link Algorithm}. * Do not use the same controller for multiple Algorithms! * @author kolja * */ public class AnimationController { public static final int DEFAULT_DELAY = 100; private Action next; private boolean continuous; private long lastTime; private long delay; private int stepOption; /** * creates a new {@link AnimationController} that can be used to control an {@link Algorithm} */ public AnimationController() { stepOption = 0; next = null; continuous = false; lastTime = 0; delay = DEFAULT_DELAY; } /** * Ask the controller, which kind of action should be done next. * The controller waits until it knows this for sure. * @return The action. * @throws InterruptedException if any thread interrupted the * current thread before or while the current thread * was waiting for a notification. The interrupted * status of the current thread is cleared when * this exception is thrown. */ public Action getNextAction() throws InterruptedException { long old = lastTime; Action ret = null; synchronized( this ) { while( next == null ) wait(); lastTime = System.currentTimeMillis(); ret = next; } if( !continuous ) next = null; else { if( lastTime - old < delay ) { Thread.sleep( delay - ( lastTime - old ) ); lastTime = System.currentTimeMillis(); } } return ret; } /** * activates or deactivates automatic execution * @param c automatic execution will be activated if c is true * and deactivated otherwise */ public void setContinuous( boolean c ) { if( !c && continuous ) { synchronized( this ) { next = null; } } this.continuous = c; } /** * sets the delay of the automatic execution. * You might also want to enable it by calling setContinuous() * @param delay the delay in milliseconds */ public void setDelay( long delay ) { this.delay = delay; } /** * sets the next action and wakes up one thread waiting for an answer of the controller. * @param a * the action */ public void setNextAction( Action a ) { synchronized( this ) { next = a; notify(); } } public void setStepOption( int opt ) { stepOption = opt; } public int getStepOption() { return stepOption; } /** * checks if automatic execution is active * @return true if it is */ public boolean isContinuous() { return continuous; } }