/** * All tasks (wander, leftbumber, rightbumber) * extend this class. This class * defines the lifecycle of a task. Namely: * Reset: Re-initialise task * Execute: Attempt to run (may not succeed * if a higher priority task is running). * Run: Execute an FSM. * Release: Stop running. */ abstract class Task extends Thread implements SensorConstants { public static final Motor LEFT_MOTOR = Motor.C; public static final Motor RIGHT_MOTOR = Motor.A; public static final Sensor LEFT_BUMBER = Sensor.S3; public static final Sensor RIGHT_BUMBER = Sensor.S1; public static final boolean FORWARD = true; public static final boolean BACKWARD = false; public static final int END = -1; public static final int START = 0; public Action actions[]; public int fsm[]; public int state = END; /** * Reset the FSM to its initial state. */ public void reset() { state = START; } /** * The thread entry point. * Either runs the action's FSM * to completion - * sleeping or yielding between * each state - or until 'running' is false. * When finished call 'release'. * <P> * FSM is really a bit of a * misnomer as there are no input events so * there is only one transition from * each state to the next. */ public void run() { // Keep running until the // program should exit. do { // Quiesce while (state != START && Main.main.running) { yield(); } // Execute the FSM // until it stops... do { int toSleepFor; synchronized (Main.main) { toSleepFor = actions[state].act(); state = fsm[state]; } if (toSleepFor > 0) { try { sleep(toSleepFor); } catch (InterruptedException ie) { } } else yield(); } while (state != END && Main.main.running); // Its over, release the actuators. release(); } while (Main.main.running); } /** * Inform the coordinator * that we have released the actuators. */ public void release() { Main.main.release(this); } /** * Request control of the actuators */ public void execute() { if (Main.main != null) Main.main.execute(this); } /** * Return true if the FSM * is executing, false otherwise. */ public boolean running() { return state != END; } /** * Convenience function to * make it appear to subclasses that * they have direct control of * the actuators when they are in * fact gated by the controller. */ public void setMotor(Motor motor, int power, boolean forward) { Main.main.setMotor(this, motor, power, forward); } }