@@ -0,0 +1,2553 @@
+%0Apackage jade.core;%0A%0Aimport java.util.SortedSet;%0Aimport java.util.TreeSet;%0A%0Aclass TimerDispatcher implements Runnable %7B%0A%0A  private Thread myThread;%0A  private SortedSet timers = new TreeSet();%0A  private boolean active;%0A%0A  TimerDispatcher() %7B%0A    active = true;%0A  %7D%0A%0A  void setThread(Thread t) %7B%0A    if(myThread == null) %7B%0A      myThread = t;%0A      myThread.setName(%22JADE Timer dispatcher%22);%0A    %7D%0A  %7D%0A%0A  synchronized void add(Timer t) %7B%0A    timers.add(t);%0A    // If this is the first timer, wake up the dispatcher thread%0A    if(timers.first() == t)%0A      notify();%0A  %7D%0A%0A  synchronized void remove(Timer t) %7B%0A    timers.remove(t);%0A  %7D%0A%0A  private synchronized boolean emptySet() %7B%0A    return timers.isEmpty();%0A  %7D%0A%0A  private synchronized Timer firstTimer() %7B%0A    return (Timer)timers.first();%0A  %7D%0A%0A  public void run() %7B%0A    // Server loop, demultiplexing between timer dispatching and timer%0A    // addition/removal.%0A%0A    //    System.out.println(%22Timer Dispatcher started ...%22);%0A    //    System.out.println(%22Running in group %22 + Thread.currentThread().getThreadGroup().getName() + %22 at priority %22 + Thread.currentThread().getPriority());%0A%0A    try %7B%0A      // Used as a flag. The dispatcher must recheck the timer list%0A      // whenever the last timer was expired.%0A      boolean checkAgain = false;%0A%0A      long timeToWait = 0;%0A      Timer t = null;%0A      synchronized(this) %7B%0A%09while(active) %7B%0A%09  checkAgain = false;%0A%09  // If no timers are armed, wait until one is added.%0A%09  if(emptySet()) %7B%0A%09    timeToWait = 0;%0A%09  %7D%0A%09  // Otherwise...%0A%09  else %7B%0A%09    t = firstTimer();%0A%09    // If t was expired, calling this function executes the%0A%09    // time-out action; then the timer is removed and the need%0A%09    // for further inspections of the timer list is flagged.%0A%09    if(t.isExpired()) %7B%0A%09      remove(t);%0A%09      checkAgain = true;%0A%09    %7D%0A%09    else %7B%0A%09      // The first timer is still armed. Then the dispatcher%0A%09      // calculates the remaining time to wait.%0A%09      timeToWait = t.expirationTime() - System.currentTimeMillis();%0A%09      if(timeToWait %3C= 0) // Avoid wait(0), that means 'for ever'...%0A%09%09timeToWait = 1;%0A%09    %7D%0A%09  %7D%0A%09  if(!checkAgain) %7B%0A%09    // System.out.println(%22Waiting for %22 + timeToWait + %22 ms.%22);%0A%09    wait(timeToWait);%0A%09  %7D%0A%09%7D%0A      %7D%0A    %7D%0A    catch(InterruptedException ie) %7B%0A      // Do nothing, but just return, since this is a shutdown.%0A    %7D%0A    System.out.println(%22Timer Dispatcher shutting down ...%22);%0A  %7D%0A%0A  public void start() %7B%0A    myThread.start();%0A  %7D%0A%0A  public void stop() %7B%0A    active = false;%0A    myThread.interrupt();%0A  %7D%0A%0A%7D%0A

Active object used to dispatch expired timers to JADE agents.