restarting = false;
}
public void execute() throws JADESecurityException, InterruptedException, InterruptedIOException {
// Select the next behaviour to execute
Behaviour currentBehaviour = myScheduler.schedule();
long oldRestartCounter = currentBehaviour.getRestartCounter();
// Just do it!
currentBehaviour.actionWrapper();
// When it is needed no more, delete it from the behaviours queue
if(currentBehaviour.done()) {
currentBehaviour.onEnd();
myScheduler.remove(currentBehaviour);
currentBehaviour = null;
}
else {
synchronized(myScheduler) {
// If the current Behaviour has blocked and it was restarted in the meanwhile
// (e.g. because a message arrived), restart the behaviour to give it another chance.
// Furthermore restart it even if it appears to be runnable since, due to the fact that block/restart
// events are managed in an un-synchronized way, we may end up in a situation where the root is runnable,
// but some of its childern are not.
if(oldRestartCounter != currentBehaviour.getRestartCounter()) {
currentBehaviour.handleRestartEvent();
}
// Need synchronized block (Crais Sayers, HP): What if
// 1) it checks to see if its runnable, sees its not,
// so it begins to enter the body of the if clause
// 2) meanwhile, in another thread, a message arrives, so
// the behaviour is restarted and moved to the ready list.
// 3) now back in the first thread, the agent executes the
// body of the if clause and, by calling block(), moves
// the behaviour back to the blocked list.
if(!currentBehaviour.isRunnable()) {
// Remove blocked behaviour from ready behaviours queue
// and put it in blocked behaviours queue
myScheduler.block(currentBehaviour);
currentBehaviour = null;
}