001: /*
002: * $RCSfile: InputDeviceBlockingThread.java,v $
003: *
004: * Copyright 1998-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.6 $
028: * $Date: 2008/02/28 20:17:25 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: class InputDeviceBlockingThread extends Thread {
035:
036: // action flag for runMonitor
037: private static final int WAIT = 0;
038: private static final int NOTIFY = 1;
039: private static final int STOP = 2;
040:
041: // blocking device that this thread manages
042: private InputDevice device;
043: private volatile boolean running = true;
044: private volatile boolean stop = false;
045: private boolean waiting = false;
046: private boolean ready = false;
047: private static int numInstances = 0;
048: private int instanceNum = -1;
049:
050: InputDeviceBlockingThread(ThreadGroup threadGroup,
051: InputDevice device) {
052: super (threadGroup, "");
053: setName("J3D-InputDeviceBlockingThread-" + getInstanceNum());
054: this .device = device;
055: }
056:
057: private synchronized int newInstanceNum() {
058: return (++numInstances);
059: }
060:
061: private int getInstanceNum() {
062: if (instanceNum == -1)
063: instanceNum = newInstanceNum();
064: return instanceNum;
065: }
066:
067: public void run() {
068: // Since this thread is blocking, this thread should not be
069: // taking an inordinate amount of CPU time. Note that the
070: // yield() call should not be necessary (and may be ineffective),
071: // but we can't call MasterControl.threadYield() because it will
072: // sleep for at least a millisecond.
073: while (running) {
074: while (!stop) {
075: device.pollAndProcessInput();
076: Thread.yield();
077: }
078: runMonitor(WAIT);
079: }
080: }
081:
082: void sleep() {
083: stop = true;
084: }
085:
086: void restart() {
087: stop = false;
088: runMonitor(NOTIFY);
089: }
090:
091: void finish() {
092: stop = true;
093: runMonitor(STOP);
094: }
095:
096: synchronized void runMonitor(int action) {
097:
098: switch (action) {
099: case WAIT:
100: // Issue 279 - loop until ready
101: while (running && !ready) {
102: waiting = true;
103: try {
104: wait();
105: } catch (InterruptedException e) {
106: }
107: waiting = false;
108: }
109: ready = false;
110: break;
111: case NOTIFY:
112: ready = true;
113: if (waiting) {
114: notify();
115: }
116: break;
117: case STOP:
118: running = false;
119: if (waiting) {
120: notify();
121: }
122: break;
123: }
124: }
125: }
|