001: /*
002: * IdleHandler.java --
003: *
004: * The API for defining idle event handler.
005: *
006: * Copyright (c) 1997 Sun Microsystems, Inc.
007: *
008: * See the file "license.terms" for information on usage and
009: * redistribution of this file, and for a DISCLAIMER OF ALL
010: * WARRANTIES.
011: *
012: * RCS: @(#) $Id: IdleHandler.java,v 1.3 2006/06/12 04:00:18 mdejong Exp $
013: *
014: */
015:
016: package tcl.lang;
017:
018: /*
019: * This abstract class is used to define idle handlers.
020: */
021:
022: public abstract class IdleHandler {
023:
024: /*
025: * Back pointer to the notifier that will fire this idle.
026: */
027:
028: Notifier notifier;
029:
030: /*
031: * True if the cancel() method has been called.
032: */
033:
034: boolean isCancelled;
035:
036: /*
037: * Used to distinguish older idle handlers from recently-created ones.
038: */
039:
040: int generation;
041:
042: /*
043: *----------------------------------------------------------------------
044: *
045: * IdleHandler --
046: *
047: * Create a idle handler to be fired when the notifier is idle.
048: *
049: * Results:
050: * None.
051: *
052: * Side effects:
053: * The idle is registered in the list of idle handlers in the
054: * given notifier. When the notifier is idle, the
055: * processIdleEvent() method will be invoked exactly once inside
056: * the primary thread of the notifier.
057: *
058: *----------------------------------------------------------------------
059: */
060:
061: public IdleHandler(Notifier n) // The notifier to fire the event.
062: {
063: notifier = (Notifier) n;
064: isCancelled = false;
065:
066: synchronized (notifier) {
067: notifier.idleList.add(this );
068: generation = notifier.idleGeneration;
069: if (Thread.currentThread() != notifier.primaryThread) {
070: notifier.notifyAll();
071: }
072: }
073: }
074:
075: /*
076: *----------------------------------------------------------------------
077: *
078: * cancel --
079: *
080: * Mark this idle handler as cancelled so that it won't be invoked.
081: *
082: * Results:
083: * None.
084: *
085: * Side effects:
086: * The idle handler is marked as cancelled so that its
087: * processIdleEvent() method will not be called. If the idle
088: * event has already fired, then nothing this call has no effect.
089: *
090: *----------------------------------------------------------------------
091: */
092:
093: public synchronized void cancel() {
094: if (isCancelled) {
095: return;
096: }
097:
098: isCancelled = true;
099:
100: synchronized (notifier) {
101: for (int i = 0; i < notifier.idleList.size(); i++) {
102: if (notifier.idleList.get(i) == this ) {
103: notifier.idleList.remove(i);
104:
105: /*
106: * We can return now because the same idle handler can
107: * be registered only once in the list of idles.
108: */
109:
110: return;
111: }
112: }
113: }
114: }
115:
116: /*
117: *----------------------------------------------------------------------
118: *
119: * invoke --
120: *
121: * Execute the idle handler if it has not been cancelled. This
122: * method should be called by the notifier only.
123: *
124: * Because the idle handler may be being cancelled by another
125: * thread, both this method and cancel() must be synchronized to
126: * ensure correctness.
127: *
128: * Results:
129: * 0 if the handler was not executed because it was already
130: * cancelled, 1 otherwise.
131: *
132: * Side effects:
133: * The idle handler may have arbitrary side effects.
134: *
135: *----------------------------------------------------------------------
136: */
137:
138: synchronized final int invoke() {
139: /*
140: * The idle handler may be cancelled after it was registered in
141: * the notifier. Check the isCancelled field to make sure it's not
142: * cancelled.
143: */
144:
145: if (!isCancelled) {
146: processIdleEvent();
147: return 1;
148: } else {
149: return 0;
150: }
151: }
152:
153: /*
154: *----------------------------------------------------------------------
155: *
156: * processIdleEvent --
157: *
158: * This method is called when the idle is expired. Override
159: * This method to implement your own idle handlers.
160: *
161: * Results:
162: * None.
163: *
164: * Side effects:
165: * It can do anything.
166: *
167: *----------------------------------------------------------------------
168: */
169:
170: abstract public void processIdleEvent();
171:
172: /*
173: *----------------------------------------------------------------------
174: *
175: * toString --
176: *
177: * This method prints a text description of the event for debugging.
178: *
179: *----------------------------------------------------------------------
180: */
181:
182: public String toString() {
183: StringBuffer sb = new StringBuffer(64);
184: sb.append("IdleHandler.generation is " + generation + "\n");
185: return sb.toString();
186: }
187:
188: } // end IdleHandler
|