Source Code Cross Referenced for SensorEventAgent.java in  » 6.0-JDK-Modules » java-3d » com » sun » j3d » utils » behaviors » sensor » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » java 3d » com.sun.j3d.utils.behaviors.sensor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: SensorEventAgent.java,v $
003:         *
004:         * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * Redistribution and use in source and binary forms, with or without
007:         * modification, are permitted provided that the following conditions
008:         * are met:
009:         *
010:         * - Redistribution of source code must retain the above copyright
011:         *   notice, this list of conditions and the following disclaimer.
012:         *
013:         * - Redistribution in binary form must reproduce the above copyright
014:         *   notice, this list of conditions and the following disclaimer in
015:         *   the documentation and/or other materials provided with the
016:         *   distribution.
017:         *
018:         * Neither the name of Sun Microsystems, Inc. or the names of
019:         * contributors may be used to endorse or promote products derived
020:         * from this software without specific prior written permission.
021:         *
022:         * This software is provided "AS IS," without a warranty of any
023:         * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024:         * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025:         * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026:         * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027:         * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028:         * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029:         * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030:         * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031:         * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032:         * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033:         * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034:         * POSSIBILITY OF SUCH DAMAGES.
035:         *
036:         * You acknowledge that this software is not designed, licensed or
037:         * intended for use in the design, construction, operation or
038:         * maintenance of any nuclear facility.
039:         *
040:         * $Revision: 1.4 $
041:         * $Date: 2007/02/09 17:20:15 $
042:         * $State: Exp $
043:         */
044:
045:        package com.sun.j3d.utils.behaviors.sensor;
046:
047:        import java.util.Iterator;
048:        import java.util.List;
049:        import java.util.ArrayList;
050:        import javax.media.j3d.Sensor;
051:        import javax.media.j3d.Transform3D;
052:        import com.sun.j3d.utils.timer.J3DTimer;
053:
054:        /**
055:         * This class works in conjunction with the <code>SensorButtonListener</code>
056:         * and <code>SensorReadListener</code> interfaces to support an event-driven
057:         * model of sensor interaction.  Java 3D defines sensors as delivering
058:         * continuous input data which must be polled to retrieve their values, but in
059:         * practice it is often convenient to structure application code to respond to
060:         * events such as button state transitions.
061:         * <p>
062:         * Listeners registered with this class are invoked when its
063:         * <code>dispatchEvents</code> method is called.  This is usually called from
064:         * the <code>processStimulus</code> method of a <code>Behavior</code>, but may
065:         * also be called directly from the <code>pollAndProcessInput</code> method of
066:         * an event-driven implementation of <code>InputDevice</code>.  In either case
067:         * the device is still polled by the Java 3D input device scheduling thread to
068:         * get its current values; however, in the former, <code>dispatchEvents</code>
069:         * is called from the behavior scheduler thread regardless of whether any new
070:         * events are available, while in the latter, the <code>InputDevice</code>
071:         * implementation may choose to call <code>dispatchEvents</code> only if new
072:         * events are actually generated.
073:         * <p>
074:         * Button events are generated by changes in sensor button state, from pressed
075:         * to released and vice versa.  Button state changes are examined with each
076:         * invocation of the <code>dispatchEvents</code> method.  Events are
077:         * distributed to interested parties through the button listener interface
078:         * using the <code>pressed</code> and <code>released</code> callbacks.
079:         * <p>
080:         * The <code>dragged</code> method is not necessarily called in response to a
081:         * motion event generated by a sensor.  <code>dispatchEvents</code> will call
082:         * <code>dragged</code> whenever any button assigned to the listener is down
083:         * and has not changed state since the last time it was called.  If
084:         * <code>dispatchEvents</code> is called in the <code>processStimulus</code>
085:         * of a <code>Behavior</code>, then <code>dragged</code> may be called even if
086:         * the sensor value has not changed.  This is as a consequence of the core
087:         * Java 3D API definition of sensors as continuous devices.
088:         * <p>
089:         * Like <code>dragged</code>, the <code>read</code> method of
090:         * <code>SensorReadListener</code> is not necessarily invoked in response to a
091:         * real event.  It is called by <code>dispatchEvents</code> whenever a button
092:         * listener has not been called for that sensor.  This usually means that no
093:         * buttons are down, but clients are free to leave a button listener null, or
094:         * to explicitly bind a null button listener to a button so that button's
095:         * events are ignored.  The sensor value has not necessarily changed since the
096:         * last <code>read</code> callback.
097:         * <p>
098:         * A <i>mutual exclusion</i> policy can be applied between button
099:         * listeners when they are grouped in an array mapped to the sensor's
100:         * buttons.  If multiple sensor buttons are held down at the same time,
101:         * then a listener in the array is invoked only for the button that was
102:         * depressed first.  The <code>read</code> callback is separated from the
103:         * <code>pressed</code>, <code>released</code>, and <code>dragged</code>
104:         * callbacks in a separate interface in order to support this policy.
105:         * <p>
106:         * The events passed to the listeners are <i>ephemeral</i>; they are only
107:         * valid until the listener has returned.  This is done to avoid
108:         * allocating large numbers of mostly temporary objects, especially for
109:         * behaviors that wake up every frame.  If a listener needs to retain the
110:         * event it must be copied using the <code>SensorEvent(SensorEvent)</code>
111:         * constructor.
112:         * <p>
113:         * It is safe to add and remove listeners in response to a callback.
114:         * 
115:         * @see SensorEvent
116:         * @see SensorButtonListener
117:         * @see SensorReadListener
118:         * @since Java 3D 1.3
119:         */
120:        public class SensorEventAgent {
121:            private long t0 = 0;
122:            private Object source = null;
123:            private SensorEvent e = new SensorEvent();
124:
125:            // List of SensorBinding objects and corresponding array.
126:            private List bindingsList = new ArrayList();
127:            private SensorBinding[] bindings = new SensorBinding[0];
128:
129:            // Indicates that lists must be converted to arrays.  Need to do this
130:            // to allow listeners to add and remove themselves or other listeners
131:            // safely during event dispatch.
132:            private boolean listsDirty = false;
133:
134:            /**
135:             * Create a <code>SensorEventAgent</code> to generate and dispatch
136:             * sensor events to registered listeners.
137:             * 
138:             * @param source reference to the originating object for inclusion in
139:             *  generated <code>SensorEvents</code>; intended to refer to the
140:             *  instantiating Behavior but may be any reference, or null
141:             */
142:            public SensorEventAgent(Object source) {
143:                this .source = source;
144:            }
145:
146:            /**
147:             * This class contains all the button and read listeners registered
148:             * with a sensor.
149:             */
150:            private static class SensorBinding {
151:                Sensor sensor = null;
152:                int[] buttons = null;
153:                Transform3D read = null;
154:
155:                // List of SensorButtonBinding objects and corresponding array.
156:                List buttonBindingsList = new ArrayList();
157:                SensorButtonBinding[] buttonBindings = new SensorButtonBinding[0];
158:
159:                // List of SensorReadListener objects and corresponding array.
160:                List readBindingsList = new ArrayList();
161:                SensorReadListener[] readBindings = new SensorReadListener[0];
162:
163:                SensorBinding(Sensor sensor) {
164:                    this .sensor = sensor;
165:                    buttons = new int[sensor.getSensorButtonCount()];
166:                    read = new Transform3D();
167:                }
168:
169:                void updateArrays() {
170:                    buttonBindings = (SensorButtonBinding[]) buttonBindingsList
171:                            .toArray(new SensorButtonBinding[buttonBindingsList
172:                                    .size()]);
173:                    readBindings = (SensorReadListener[]) readBindingsList
174:                            .toArray(new SensorReadListener[readBindingsList
175:                                    .size()]);
176:                }
177:
178:                public String toString() {
179:                    String s = new String();
180:                    s = "sensor " + sensor + "\nbutton listener arrays:\n";
181:                    for (int i = 0; i < buttonBindingsList.size(); i++)
182:                        s = s
183:                                + ((SensorButtonBinding) buttonBindingsList
184:                                        .get(i));
185:                    s = s + "read listeners:\n";
186:                    for (int i = 0; i < readBindingsList.size(); i++)
187:                        s = s
188:                                + "  "
189:                                + ((SensorReadListener) readBindingsList.get(i))
190:                                + "\n";
191:                    return s;
192:                }
193:            }
194:
195:            /**
196:             * This class contains an array of SensorButtonListener
197:             * implementations, one for each sensor button.  This array is used to
198:             * support a mutual exclusion callback policy.  There may be multiple
199:             * instances of this class associated with a single sensor.
200:             */
201:            private static class SensorButtonBinding {
202:                int buttonsHandled = 0;
203:                boolean[] prevButtons = null;
204:                boolean multiButton = false;
205:                SensorButtonListener[] listeners = null;
206:
207:                SensorButtonBinding(SensorButtonListener[] listeners,
208:                        boolean multiButtonEnable) {
209:
210:                    prevButtons = new boolean[listeners.length];
211:                    this .listeners = new SensorButtonListener[listeners.length];
212:
213:                    for (int i = 0; i < listeners.length; i++) {
214:                        prevButtons[i] = false;
215:                        this .listeners[i] = listeners[i];
216:                    }
217:
218:                    this .multiButton = multiButtonEnable;
219:                }
220:
221:                public String toString() {
222:                    String s = new String();
223:                    s = "  length " + listeners.length + ", mutual exclusion "
224:                            + (!multiButton) + "\n";
225:                    for (int i = 0; i < listeners.length; i++)
226:                        s = s
227:                                + "    "
228:                                + (listeners[i] == null ? "null" : listeners[i]
229:                                        .toString()) + "\n";
230:                    return s;
231:                }
232:            }
233:
234:            /**
235:             * Look up the sensor listeners bound to the given sensor.
236:             */
237:            private SensorBinding getSensorBinding(Sensor sensor) {
238:                for (int i = 0; i < bindingsList.size(); i++) {
239:                    SensorBinding sb = (SensorBinding) bindingsList.get(i);
240:                    if (sb.sensor == sensor)
241:                        return sb;
242:                }
243:                return null;
244:            }
245:
246:            /**
247:             * Creates a binding of the specified sensor button to the given
248:             * <code>SensorButtonListener</code> implementation.
249:             * 
250:             * @param sensor the sensor with the button to be bound
251:             * @param button the index of the button to be bound on the specified
252:             *  sensor; may range from 0 to
253:             *  <code>(sensor.getSensorButtonCount() - 1)</code>
254:             * @param buttonListener the <code>SensorButtonListener</code>
255:             *  implementation that will be invoked for the sensor's button
256:             */
257:            public synchronized void addSensorButtonListener(Sensor sensor,
258:                    int button, SensorButtonListener buttonListener) {
259:
260:                if (sensor == null)
261:                    throw new NullPointerException("\nsensor is null");
262:
263:                if (button >= sensor.getSensorButtonCount())
264:                    throw new ArrayIndexOutOfBoundsException("\nbutton "
265:                            + button + " >= sensor button count "
266:                            + sensor.getSensorButtonCount());
267:
268:                SensorBinding sb = getSensorBinding(sensor);
269:                if (sb == null) {
270:                    sb = new SensorBinding(sensor);
271:                    bindingsList.add(sb);
272:                }
273:
274:                SensorButtonListener[] listeners = new SensorButtonListener[sb.buttons.length];
275:
276:                // Assign only the specified button; others remain null.
277:                listeners[button] = buttonListener;
278:                SensorButtonBinding sbb = new SensorButtonBinding(listeners,
279:                        true);
280:
281:                sb.buttonBindingsList.add(sbb);
282:                listsDirty = true;
283:            }
284:
285:            /**
286:             * Creates a binding from all the buttons on the specified sensor to
287:             * the given <code>SensorButtonListener</code> implementation.  If
288:             * multiple sensor buttons are held down at the same time, the press
289:             * and release callbacks are called for each button in the order that
290:             * they occur.  This allows actions to be bound to combinations of
291:             * button presses, but is also convenient for listeners that don't
292:             * care which button was pressed.
293:             * 
294:             * @param sensor the sensor to be bound
295:             * @param buttonListener the <code>SensorButtonListener</code>
296:             *  implementation that will be called for all button events
297:             */
298:            public synchronized void addSensorButtonListener(Sensor sensor,
299:                    SensorButtonListener buttonListener) {
300:
301:                if (sensor == null)
302:                    throw new NullPointerException("\nsensor is null");
303:
304:                SensorBinding sb = getSensorBinding(sensor);
305:                if (sb == null) {
306:                    sb = new SensorBinding(sensor);
307:                    bindingsList.add(sb);
308:                }
309:
310:                SensorButtonListener[] listeners = new SensorButtonListener[sb.buttons.length];
311:
312:                // All buttons are bound to the same listener.
313:                for (int i = 0; i < sb.buttons.length; i++)
314:                    listeners[i] = buttonListener;
315:
316:                SensorButtonBinding sbb = new SensorButtonBinding(listeners,
317:                        true);
318:
319:                sb.buttonBindingsList.add(sbb);
320:                listsDirty = true;
321:            }
322:
323:            /**
324:             * Creates a binding of the specified sensor to the given array of
325:             * <code>SensorButtonListener</code> implementations.  The array index
326:             * of the listener indicates the index of the sensor button to which
327:             * it will be bound.
328:             * <p>
329:             * This method enforces a <i>mutually exclusive</i> callback policy
330:             * among the listeners specified in the array.  If multiple sensor
331:             * buttons are held down at the same time, callbacks are invoked only
332:             * for the button that was depressed first.
333:             * 
334:             * @param sensor the sensor to be bound
335:             * @param buttonListeners array of implementations of
336:             *  <code>SensorButtonListener</code>; array entries may be null or
337:             *  duplicates but the array length must equal the sensor's button
338:             *  count
339:             */
340:            public synchronized void addSensorButtonListeners(Sensor sensor,
341:                    SensorButtonListener[] buttonListeners) {
342:
343:                if (sensor == null)
344:                    throw new NullPointerException("\nsensor is null");
345:
346:                SensorBinding sb = getSensorBinding(sensor);
347:                if (sb == null) {
348:                    sb = new SensorBinding(sensor);
349:                    bindingsList.add(sb);
350:                }
351:
352:                if (sb.buttons.length != buttonListeners.length)
353:                    throw new IllegalArgumentException(
354:                            "\nbuttonListeners length "
355:                                    + buttonListeners.length
356:                                    + " must equal sensor button count "
357:                                    + sb.buttons.length);
358:
359:                SensorButtonBinding sbb = new SensorButtonBinding(
360:                        buttonListeners, false);
361:
362:                sb.buttonBindingsList.add(sbb);
363:                listsDirty = true;
364:            }
365:
366:            /**
367:             * Gets the <code>SensorButtonListener</code> implementations bound to
368:             * the given sensor and button.
369:             * 
370:             * @param sensor the sensor of interest
371:             * @param button the button of interest
372:             * @return array of <code>SensorButtonListener</code> implementations
373:             *  bound to the given sensor and button, or null
374:             */
375:            public SensorButtonListener[] getSensorButtonListeners(
376:                    Sensor sensor, int button) {
377:                if (sensor == null)
378:                    throw new NullPointerException("\nsensor is null");
379:
380:                if (button >= sensor.getSensorButtonCount())
381:                    throw new ArrayIndexOutOfBoundsException("\nbutton "
382:                            + button + " >= sensor button count "
383:                            + sensor.getSensorButtonCount());
384:
385:                SensorBinding sb = getSensorBinding(sensor);
386:                if (sb == null)
387:                    return null;
388:
389:                ArrayList listeners = new ArrayList();
390:                for (int i = 0; i < sb.buttonBindingsList.size(); i++) {
391:                    SensorButtonBinding sbb = (SensorButtonBinding) sb.buttonBindingsList
392:                            .get(i);
393:
394:                    if (sbb.listeners[button] != null)
395:                        listeners.add(sbb.listeners[button]);
396:                }
397:
398:                if (listeners.size() == 0)
399:                    return null;
400:                else
401:                    return (SensorButtonListener[]) listeners
402:                            .toArray(new SensorButtonListener[listeners.size()]);
403:            }
404:
405:            /**
406:             * Remove the SensorButtonListener from the given SensorBinding.
407:             */
408:            private void removeSensorButtonListener(SensorBinding sb,
409:                    SensorButtonListener listener) {
410:
411:                Iterator i = sb.buttonBindingsList.iterator();
412:                while (i.hasNext()) {
413:                    int instanceCount = 0;
414:                    SensorButtonBinding sbb = (SensorButtonBinding) i.next();
415:
416:                    for (int j = 0; j < sbb.listeners.length; j++) {
417:                        if (sbb.listeners[j] == listener)
418:                            sbb.listeners[j] = null;
419:                        else if (sbb.listeners[j] != null)
420:                            instanceCount++;
421:                    }
422:                    if (instanceCount == 0) {
423:                        i.remove();
424:                    }
425:                }
426:                listsDirty = true;
427:            }
428:
429:            /**
430:             * Remove the given <code>SensorButtonListener</code> binding from the
431:             * specified sensor.
432:             * 
433:             * @param sensor the sensor from which to remove the listener
434:             * @param listener the listener to be removed
435:             */
436:            public synchronized void removeSensorButtonListener(Sensor sensor,
437:                    SensorButtonListener listener) {
438:
439:                if (sensor == null)
440:                    throw new NullPointerException("\nsensor is null");
441:
442:                SensorBinding sb = getSensorBinding(sensor);
443:                if (sb == null)
444:                    return;
445:
446:                removeSensorButtonListener(sb, listener);
447:                if (sb.buttonBindingsList.size() == 0
448:                        && sb.readBindingsList.size() == 0)
449:                    removeSensorBinding(sensor);
450:
451:                listsDirty = true;
452:            }
453:
454:            /**
455:             * Remove the given <code>SensorButtonListener</code> from all sensors.
456:             * 
457:             * @param listener the listener to remove
458:             */
459:            public synchronized void removeSensorButtonListener(
460:                    SensorButtonListener listener) {
461:
462:                Iterator i = bindingsList.iterator();
463:                while (i.hasNext()) {
464:                    SensorBinding sb = (SensorBinding) i.next();
465:                    removeSensorButtonListener(sb, listener);
466:
467:                    if (sb.buttonBindingsList.size() == 0
468:                            && sb.readBindingsList.size() == 0) {
469:                        i.remove();
470:                    }
471:                }
472:                listsDirty = true;
473:            }
474:
475:            /**
476:             * Creates a binding of the specified sensor to the given
477:             * <code>SensorReadListener</code>.  The read listener is invoked
478:             * every time <code>dispatchEvents</code> is called and a button
479:             * listener is <i>not</i> invoked.
480:             * 
481:             * @param sensor the sensor to be bound
482:             * @param readListener the <code>SensorReadListener</code>
483:             *  implementation
484:             */
485:            public synchronized void addSensorReadListener(Sensor sensor,
486:                    SensorReadListener readListener) {
487:
488:                if (sensor == null)
489:                    throw new NullPointerException("\nsensor is null");
490:
491:                SensorBinding sb = getSensorBinding(sensor);
492:                if (sb == null) {
493:                    sb = new SensorBinding(sensor);
494:                    bindingsList.add(sb);
495:                }
496:                sb.readBindingsList.add(readListener);
497:                listsDirty = true;
498:            }
499:
500:            /**
501:             * Gets the <code>SensorReadListeners</code> bound to the specified
502:             * sensor.
503:             * 
504:             * @param sensor the sensor of interest
505:             * @return array of <code>SensorReadListeners</code> bound to the
506:             *  given sensor, or null
507:             */
508:            public SensorReadListener[] getSensorReadListeners(Sensor sensor) {
509:                if (sensor == null)
510:                    throw new NullPointerException("\nsensor is null");
511:
512:                SensorBinding sb = getSensorBinding(sensor);
513:                if (sb == null)
514:                    return null;
515:                else if (sb.readBindingsList.size() == 0)
516:                    return null;
517:                else
518:                    return (SensorReadListener[]) sb.readBindingsList
519:                            .toArray(new SensorReadListener[sb.readBindingsList
520:                                    .size()]);
521:            }
522:
523:            /**
524:             * Remove the SensorReadListener from the given SensorBinding.
525:             */
526:            private void removeSensorReadListener(SensorBinding sb,
527:                    SensorReadListener listener) {
528:
529:                Iterator i = sb.readBindingsList.iterator();
530:                while (i.hasNext()) {
531:                    if (((SensorReadListener) i.next()) == listener)
532:                        i.remove();
533:                }
534:                listsDirty = true;
535:            }
536:
537:            /**
538:             * Remove the given <code>SensorReadListener</code> binding from the
539:             * specified sensor.
540:             * 
541:             * @param sensor the sensor from which to remove the listener
542:             * @param listener the listener to be removed
543:             */
544:            public synchronized void removeSensorReadListener(Sensor sensor,
545:                    SensorReadListener listener) {
546:
547:                if (sensor == null)
548:                    throw new NullPointerException("\nsensor is null");
549:
550:                SensorBinding sb = getSensorBinding(sensor);
551:                if (sb == null)
552:                    return;
553:
554:                removeSensorReadListener(sb, listener);
555:                if (sb.buttonBindingsList.size() == 0
556:                        && sb.readBindingsList.size() == 0)
557:                    removeSensorBinding(sensor);
558:
559:                listsDirty = true;
560:            }
561:
562:            /**
563:             * Remove the given <code>SensorReadListener</code> from all sensors.
564:             * 
565:             * @param listener the listener to remove
566:             */
567:            public synchronized void removeSensorReadListener(
568:                    SensorReadListener listener) {
569:
570:                Iterator i = bindingsList.iterator();
571:                while (i.hasNext()) {
572:                    SensorBinding sb = (SensorBinding) i.next();
573:                    removeSensorReadListener(sb, listener);
574:
575:                    if (sb.buttonBindingsList.size() == 0
576:                            && sb.readBindingsList.size() == 0) {
577:                        i.remove();
578:                    }
579:                }
580:                listsDirty = true;
581:            }
582:
583:            /**
584:             * Remove all sensor listeners bound to the given sensor.
585:             */
586:            public synchronized void removeSensorBinding(Sensor sensor) {
587:                Iterator i = bindingsList.iterator();
588:                while (i.hasNext()) {
589:                    SensorBinding sb = (SensorBinding) i.next();
590:                    if (sb.sensor == sensor) {
591:                        i.remove();
592:                        break;
593:                    }
594:                }
595:                listsDirty = true;
596:            }
597:
598:            /**
599:             * Returns an array of references to all sensors that have been bound
600:             * to listeners.
601:             * @return an array of sensors, or null if no sensors have been bound
602:             */
603:            public Sensor[] getSensors() {
604:                if (bindingsList.size() == 0)
605:                    return null;
606:
607:                Sensor[] s = new Sensor[bindingsList.size()];
608:                for (int i = 0; i < bindingsList.size(); i++)
609:                    s[i] = ((SensorBinding) bindingsList.get(i)).sensor;
610:
611:                return s;
612:            }
613:
614:            /**
615:             * Copies binding lists to arrays for event dispatch.  This allows
616:             * listeners to add or remove themselves or other listeners safely.
617:             */
618:            private synchronized void updateArrays() {
619:                bindings = (SensorBinding[]) bindingsList
620:                        .toArray(new SensorBinding[bindingsList.size()]);
621:
622:                for (int i = 0; i < bindings.length; i++) {
623:                    bindings[i].updateArrays();
624:                }
625:            }
626:
627:            /**
628:             * Reads all sensor button state and dispatches events to registered
629:             * button and read listeners.  This method is intended to be called from
630:             * the <code>processStimulus</code> implementation of a
631:             * <code>Behavior</code> or the <code>pollAndProcessInput</code> method of
632:             * an event-driven implementation of <code>InputDevice</code>.
633:             */
634:            public void dispatchEvents() {
635:                long t1 = t0;
636:                t0 = J3DTimer.getValue();
637:
638:                if (listsDirty) {
639:                    updateArrays();
640:                    listsDirty = false;
641:                }
642:
643:                // Loop through all sensor bindings.
644:                for (int k = 0; k < bindings.length; k++) {
645:                    SensorBinding sb = bindings[k];
646:                    Sensor s = sb.sensor;
647:                    Transform3D read = sb.read;
648:                    int[] buttons = sb.buttons;
649:                    int dragButton = 0;
650:                    boolean callReadListeners = true;
651:                    boolean callDraggedListener = false;
652:
653:                    // Get this sensor's readings.
654:                    s.getRead(read);
655:                    s.lastButtons(buttons);
656:
657:                    // Dispatch button listeners.
658:                    for (int j = 0; j < sb.buttonBindings.length; j++) {
659:                        SensorButtonBinding sbb = sb.buttonBindings[j];
660:                        for (int i = 0; i < buttons.length; i++) {
661:                            if (sbb.listeners[i] == null)
662:                                continue;
663:
664:                            // Check for button release.
665:                            if (sbb.prevButtons[i]) {
666:                                if (buttons[i] == 0) {
667:                                    e.set(source, SensorEvent.RELEASED, s,
668:                                            read, buttons, i, t0, t1);
669:                                    sbb.listeners[i].released(e);
670:                                    sbb.prevButtons[i] = false;
671:                                    sbb.buttonsHandled--;
672:                                } else {
673:                                    callDraggedListener = true;
674:                                    dragButton = i;
675:                                }
676:                                callReadListeners = false;
677:                            }
678:                            // Check for button press.
679:                            // Ignore multiple button presses if not enabled;
680:                            // otherwise, one listener is bound to all buttons.
681:                            else if (buttons[i] == 1) {
682:                                if (sbb.buttonsHandled == 0 || sbb.multiButton) {
683:                                    e.set(source, SensorEvent.PRESSED, s, read,
684:                                            buttons, i, t0, t1);
685:                                    sbb.listeners[i].pressed(e);
686:                                    sbb.prevButtons[i] = true;
687:                                    sbb.buttonsHandled++;
688:                                    callReadListeners = false;
689:                                }
690:                            }
691:                        }
692:                        if (callDraggedListener) {
693:                            // One drag event even if multiple buttons down.
694:                            // Called after all pressed() and released() calls.
695:                            e.set(source, SensorEvent.DRAGGED, s, read,
696:                                    buttons, SensorEvent.NOBUTTON, t0, t1);
697:                            sbb.listeners[dragButton].dragged(e);
698:                        }
699:                    }
700:                    // Dispatch read listeners.
701:                    if (callReadListeners) {
702:                        e.set(source, SensorEvent.READ, s, read, buttons,
703:                                SensorEvent.NOBUTTON, t0, t1);
704:                        for (int r = 0; r < sb.readBindings.length; r++) {
705:                            sb.readBindings[r].read(e);
706:                        }
707:                    }
708:                }
709:            }
710:
711:            public String toString() {
712:                String s = "SensorEventAgent@"
713:                        + Integer.toHexString(hashCode());
714:                s += "\nsensor bindings:\n\n";
715:                for (int i = 0; i < bindingsList.size(); i++) {
716:                    s += ((SensorBinding) bindingsList.get(i)).toString()
717:                            + "\n";
718:                }
719:                return s;
720:            }
721:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.