/* * IdleHandler.java -- * * The API for defining idle event handler. * * Copyright (c) 1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and * redistribution of this file, and for a DISCLAIMER OF ALL * WARRANTIES. * * RCS: @(#) $Id: IdleHandler.java,v 1.1.1.1 1998/10/14 21:09:21 cvsadmin Exp $ * */ package tcl.lang; import java.util.Hashtable; import java.util.Vector; /* * This abstract class is used to define idle handlers. */ public abstract class IdleHandler { /* * Back pointer to the notifier that will fire this idle. */ Notifier notifier; /* * True if the cancel() method has been called. */ boolean isCancelled; /* * Used to distinguish older idle handlers from recently-created ones. */ int generation; /* *---------------------------------------------------------------------- * * IdleHandler -- * * Create a idle handler to be fired when the notifier is idle. * * Results: * None. * * Side effects: * The idle is registered in the list of idle handlers in the * given notifier. When the notifier is idle, the * processIdleEvent() method will be invoked exactly once inside * the primary thread of the notifier. * *---------------------------------------------------------------------- */ public IdleHandler( Notifier n) // The notifier to fire the event. { notifier = (Notifier)n; isCancelled = false; synchronized(notifier) { notifier.idleList.addElement(this); generation = notifier.idleGeneration; if (Thread.currentThread() != notifier.primaryThread) { notifier.notifyAll(); } } } /* *---------------------------------------------------------------------- * * cancel -- * * Mark this idle handler as cancelled so that it won't be invoked. * * Results: * None. * * Side effects: * The idle handler is marked as cancelled so that its * processIdleEvent() method will not be called. If the idle * event has already fired, then nothing this call has no effect. * *---------------------------------------------------------------------- */ public synchronized void cancel() { if (isCancelled) { return; } isCancelled = true; synchronized(notifier) { for (int i = 0; i < notifier.idleList.size(); i++) { if (notifier.idleList.elementAt(i) == this) { notifier.idleList.removeElementAt(i); /* * We can return now because the same idle handler can * be registered only once in the list of idles. */ return; } } } } /* *---------------------------------------------------------------------- * * invoke -- * * Execute the idle handler if it has not been cancelled. This * method should be called by the notifier only. * * Because the idle handler may be being cancelled by another * thread, both this method and cancel() must be synchronized to * ensure correctness. * * Results: * 0 if the handler was not executed because it was already * cancelled, 1 otherwise. * * Side effects: * The idle handler may have arbitrary side effects. * *---------------------------------------------------------------------- */ synchronized final int invoke() { /* * The idle handler may be cancelled after it was registered in * the notifier. Check the isCancelled field to make sure it's not * cancelled. */ if (!isCancelled) { processIdleEvent(); return 1; } else { return 0; } } /* *---------------------------------------------------------------------- * * processIdleEvent -- * * This method is called when the idle is expired. Override * This method to implement your own idle handlers. * * Results: * None. * * Side effects: * It can do anything. * *---------------------------------------------------------------------- */ abstract public void processIdleEvent(); } // end IdleHandler