package josx.robotics;
/**
* Arbitrator controls which behavior should currently be active in
* a behavior control system. Make sure to call start() after the
* Arbitrator is instantiated.
* @see Behavior
* @author Brian Bagnall
* @version 0.1 27-July-2001
*/
public class Arbitrator {
private Behavior [] behavior;
private final int NONE = 99;
private int currentBehavior;
private BehaviorAction actionThread;
/**
* Allocates an Arbitrator object and initializes it with an array of
* Behavior objects. The highest index in the Behavior array will have the
* highest order behavior level, and hence will suppress all lower level
* behaviors if it becomes active. The Behaviors in an Arbitrator can not
* be changed once the arbitrator is initialized.
* NOTE: Once the Arbitrator is initialized, the method start() must be
* called to begin the arbitration.
* @param behavior An array of Behavior objects.
*/
public Arbitrator(Behavior [] behaviors) {
this.behavior = behaviors;
currentBehavior = NONE;
actionThread = new BehaviorAction();
actionThread.start();
}
/**
* This method starts the arbitration of Behaviors.
* Modifying the start() method is not recomended.
* Note: Arbitrator does not run in a seperate thread, and hence the start()
* method will never return.
*/
public void start() {
int totalBehaviors = behavior.length - 1;
while(true) {
// Check through all behavior.takeControl() starting at highest level behavior
for(int i = totalBehaviors;i>=0;--i) {
if(behavior[i].takeControl()) {
// As soon as takeControl() is true, execute the currentBehavior.suppress()
//if(behavior[i] != currentBehavior) {
if(i != currentBehavior) { // Prevents program from running same action over and over again
if (currentBehavior != NONE) {
if(currentBehavior >= i) // If higher level thread, wait to complete..
while(!actionThread.done) {Thread.yield();}
behavior[currentBehavior].suppress();
}
// Make currentBehavior this one
currentBehavior = i;
// Run the currentBehavior.behaviorAction()
actionThread.execute(i);
Thread.yield();
}
break; // Breaks out of for() loop
}
}
}
}
/**
* This class handles the action() methods of the Behaviors.
*/
private class BehaviorAction extends Thread {
public boolean done = true;
int current = NONE;
public void run() {
while(true) {
synchronized(this)
{
if(current != NONE) {
done = false;
behavior[current].action();
current = NONE;
done = true;
}
}
Thread.yield();
}
}
public synchronized void execute(int index) {
current = index;
}
}
}