Package jade.core

Source Code of jade.core.Scheduler

/*****************************************************************
JADE - Java Agent DEvelopment Framework is a framework to develop
multi-agent systems in compliance with the FIPA specifications.
Copyright (C) 2000 CSELT S.p.A.
GNU Lesser General Public License
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation,
version 2.1 of the License.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA  02111-1307, USA.
*****************************************************************/


package jade.core;

import java.util.Vector;

import jade.util.leap.List;
import jade.util.leap.LinkedList;
import jade.util.leap.Iterator;
import jade.util.leap.EnumIterator;
import jade.util.leap.Serializable;

import jade.core.behaviours.Behaviour;

/**
@author Giovanni Rimassa - Universita' di Parma
@version $Date: 2005-12-16 16:37:25 +0100 (ven, 16 dic 2005) $ $Revision: 5844 $
*/

/**************************************************************
Name: Scheduler
Responsibility and Collaborations:
+ Selects the behaviour to execute.
(Behaviour)
+ Holds together all the behaviours of an agent.
(Agent, Behaviour)
+ Manages the resources needed to synchronize and execute agent
behaviours, such as thread pools, locks, etc.
****************************************************************/
class Scheduler implements Serializable {
 
 
  //#MIDP_EXCLUDE_BEGIN
  protected List readyBehaviours = new LinkedList();
  protected List blockedBehaviours = new LinkedList();
  //#MIDP_EXCLUDE_END
  /*#MIDP_INCLUDE_BEGIN
   protected Vector readyBehaviours = new Vector();
   protected Vector blockedBehaviours = new Vector();
   #MIDP_INCLUDE_END*/
 
 
 
  /**
   @serial
   */
  private Agent owner;
 
  /**
   @serial
   */
  private int currentIndex;
 
  public Scheduler(Agent a) {
    owner = a;
    currentIndex = 0;
  }
 
  // Add a behaviour at the end of the behaviours queue.
  // This can never change the index of the current behaviour.
  // If the behaviours queue was empty notifies the embedded thread of
  // the owner agent that a behaviour is now available.
  public synchronized void add(Behaviour b) {
    //#MIDP_EXCLUDE_BEGIN
    readyBehaviours.add(b);
    //#MIDP_EXCLUDE_END
    /*#MIDP_INCLUDE_BEGIN
     readyBehaviours.addElement(b);
     #MIDP_INCLUDE_END*/
    notify();
    //#MIDP_EXCLUDE_BEGIN
    owner.notifyAddBehaviour(b);
    //#MIDP_EXCLUDE_END
  }
 
  // Moves a behaviour from the ready queue to the sleeping queue.
  public synchronized void block(Behaviour b) {
    if (removeFromReady(b)) {
      //#MIDP_EXCLUDE_BEGIN
      blockedBehaviours.add(b);
      //#MIDP_EXCLUDE_END
      /*#MIDP_INCLUDE_BEGIN
       blockedBehaviours.addElement(b);
       #MIDP_INCLUDE_END*/
      //#MIDP_EXCLUDE_BEGIN
      owner.notifyChangeBehaviourState(b, Behaviour.STATE_READY, Behaviour.STATE_BLOCKED);
      //#MIDP_EXCLUDE_END
    }
  }
 
  // Moves a behaviour from the sleeping queue to the ready queue.
  public synchronized void restart(Behaviour b) {
    if (removeFromBlocked(b)) {
      //#MIDP_EXCLUDE_BEGIN
      readyBehaviours.add(b);
      //#MIDP_EXCLUDE_END
      /*#MIDP_INCLUDE_BEGIN
       readyBehaviours.addElement(b);
       #MIDP_INCLUDE_END*/
      notify();
      //#MIDP_EXCLUDE_BEGIN
      owner.notifyChangeBehaviourState(b, Behaviour.STATE_BLOCKED, Behaviour.STATE_READY);
      //#MIDP_EXCLUDE_END
    }
  }
 
  /**
   Restarts all behaviours. This method simply calls
   Behaviour.restart() on every behaviour. The
   Behaviour.restart() method then notifies the agent (with the
   Agent.notifyRestarted() method), causing Scheduler.restart() to
   be called (this also moves behaviours from the blocked queue to
   the ready queue --> we must copy all behaviours into a temporary
   buffer to avoid concurrent modification exceptions).
   Why not restarting only blocked behaviours?
   Some ready behaviour can be a ParallelBehaviour with some of its
   children blocked. These children must be restarted too.
   */
  public synchronized void restartAll() {
   
    Behaviour[] behaviours = new Behaviour[readyBehaviours.size()];
    int counter = 0;
    //#MIDP_EXCLUDE_BEGIN
    for(Iterator it = readyBehaviours.iterator(); it.hasNext();)
      //#MIDP_EXCLUDE_END
      /*#MIDP_INCLUDE_BEGIN
       for(Iterator it = new EnumIterator(readyBehaviours.elements()); it.hasNext();)
       #MIDP_INCLUDE_END*/
      behaviours[counter++] = (Behaviour)it.next();
   
    for(int i = 0; i < behaviours.length; i++) {
      Behaviour b = behaviours[i];
      b.restart();
    }
   
    behaviours = new Behaviour[blockedBehaviours.size()];
    counter = 0;
    //#MIDP_EXCLUDE_BEGIN
    for(Iterator it = blockedBehaviours.iterator(); it.hasNext();) {
      //#MIDP_EXCLUDE_END
      /*#MIDP_INCLUDE_BEGIN
       for(Iterator it = new EnumIterator(blockedBehaviours.elements()); it.hasNext();) {
       #MIDP_INCLUDE_END*/
     
      //#DOTNET_EXCLUDE_BEGIN
      behaviours[counter++] = (Behaviour)it.next();
      //#DOTNET_EXCLUDE_END
      /*#DOTNET_INCLUDE_BEGIN
       Object tmpB = null;
       try // Hack: sometimes .NET inserts into this array a non-Behaviour object
       {
       tmpB = it.next();
       behaviours[counter++] = (Behaviour)tmpB;
       }
       catch(ClassCastException cce)
       {
       System.out.println("Found an object of type "+tmpB.getClass().getName()+" instead of Behaviour");
       cce.printStackTrace();
       }
       #DOTNET_INCLUDE_END*/
    }
   
    for(int i = 0; i < behaviours.length; i++) {
      Behaviour b = behaviours[i];
      /*#DOTNET_INCLUDE_BEGIN
       if (b != null)
       #DOTNET_INCLUDE_END*/
      b.restart();
     
    }
  }
 
  /**
   Removes a specified behaviour from the scheduler
   */
  public synchronized void remove(Behaviour b) {
    boolean found = removeFromBlocked(b);
    if(!found) {
      found = removeFromReady(b);
    }
    if (found) {
      //#MIDP_EXCLUDE_BEGIN
      owner.notifyRemoveBehaviour(b);   
      //#MIDP_EXCLUDE_END
    }
  }
 
  /**
   Selects the appropriate behaviour for execution, with a trivial
   round-robin algorithm.
   */
  public synchronized Behaviour schedule() throws InterruptedException {
    while(readyBehaviours.isEmpty()) {
      owner.idle();
    }
   
    //#MIDP_EXCLUDE_BEGIN
    Behaviour b = (Behaviour)readyBehaviours.get(currentIndex);
    //#MIDP_EXCLUDE_END
    /*#MIDP_INCLUDE_BEGIN
     Behaviour b = (Behaviour)readyBehaviours.elementAt(currentIndex);
     #MIDP_INCLUDE_END*/
    currentIndex = (currentIndex + 1) % readyBehaviours.size();
    return b;
  }
 
 
  //#MIDP_EXCLUDE_BEGIN
 
  // Helper method for persistence service
  public synchronized Behaviour[] getBehaviours() {
   
    Behaviour[] result = new Behaviour[blockedBehaviours.size() + readyBehaviours.size()];
    Iterator itReady = readyBehaviours.iterator();
    Iterator itBlocked = blockedBehaviours.iterator();
    for(int i = 0; i < result.length; i++) {
      Behaviour b = null;
      if(itReady.hasNext()) {
        b = (Behaviour)itReady.next();
      }
      else {
        b = (Behaviour)itBlocked.next();
      }
     
      result[i] = b;
     
    }
   
    return result;
  }
 
  // Helper method for persistence service
  public void setBehaviours(Behaviour[] behaviours) {
   
    readyBehaviours.clear();
    blockedBehaviours.clear();
   
    for(int i = 0; i < behaviours.length; i++) {
      Behaviour b = behaviours[i];
      if(b.isRunnable()) {
        readyBehaviours.add(b);
      }
      else {
        blockedBehaviours.add(b);
      }
    }
   
    // The current index is not saved when persisting an agent
    currentIndex = 0;
  }
 
  //#MIDP_EXCLUDE_END
 
 
  // Removes a specified behaviour from the blocked queue.
  private boolean removeFromBlocked(Behaviour b) {
    //#MIDP_EXCLUDE_BEGIN
    return blockedBehaviours.remove(b);
    //#MIDP_EXCLUDE_END
    /*#MIDP_INCLUDE_BEGIN
     return blockedBehaviours.removeElement(b);
     #MIDP_INCLUDE_END*/
  }
 
  // Removes a specified behaviour from the ready queue.
  // This can change the index of the current behaviour, so a check is
  // made: if the just removed behaviour has an index lesser than the
  // current one, then the current index must be decremented.
  private boolean removeFromReady(Behaviour b) {
    int index = readyBehaviours.indexOf(b);
    if(index != -1) {
      //#MIDP_EXCLUDE_BEGIN
      readyBehaviours.remove(b);
      //#MIDP_EXCLUDE_END
      /*#MIDP_INCLUDE_BEGIN
       readyBehaviours.removeElement(b);
       #MIDP_INCLUDE_END*/
      if(index < currentIndex)
        --currentIndex;
      //if(currentIndex < 0)
      //  currentIndex = 0;
      else if (index == currentIndex && currentIndex == readyBehaviours.size())
        currentIndex = 0;
    }
    return index != -1;
  }
 
}

TOP

Related Classes of jade.core.Scheduler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.