001: /*
002: * $RCSfile: SensorEvent.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:14 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.utils.behaviors.sensor;
046:
047: import javax.media.j3d.Sensor;
048: import javax.media.j3d.Transform3D;
049:
050: /**
051: * This class defines the event object that is created by a
052: * <code>SensorEventAgent</code> and passed to registered
053: * <code>SensorReadListener</code> and <code>SensorButtonListener</code>
054: * implementations.
055: * <p>
056: * The events passed to the listeners are <i>ephemeral</i>; they are only
057: * valid until the listener has returned. This is done to avoid
058: * allocating large numbers of mostly temporary objects, especially for
059: * behaviors that wake up every frame. If a listener needs to retain the
060: * event it must be copied using the <code>SensorEvent(SensorEvent)</code>
061: * constructor.
062: *
063: * @see SensorEventAgent
064: * @see SensorButtonListener
065: * @see SensorReadListener
066: * @since Java 3D 1.3
067: */
068: public class SensorEvent {
069: /**
070: * A button pressed event.
071: */
072: public static final int PRESSED = 1;
073:
074: /**
075: * A button released event.
076: */
077: public static final int RELEASED = 2;
078:
079: /**
080: * A button dragged event.
081: */
082: public static final int DRAGGED = 3;
083:
084: /**
085: * A sensor read event.
086: */
087: public static final int READ = 4;
088:
089: /**
090: * The value that is returned by <code>getButton</code> when no
091: * buttons have changed state.
092: */
093: public static final int NOBUTTON = -1;
094:
095: private int id = 0;
096: private Object source = null;
097: private Sensor sensor = null;
098: private int button = NOBUTTON;
099: private int[] buttonState = null;
100: private Transform3D sensorRead = null;
101: private long time = 0;
102: private long lastTime = 0;
103: private boolean ephemeral = false;
104:
105: /**
106: * Creates a new <code>SensorEvent</code>.
107: *
108: * @param source a reference to the originating object which
109: * instantiated the <code>SensorEventAgent</code>, usually a
110: * <code>Behavior</code>; may be null
111: * @param id event type
112: * @param sensor a reference to the provoking sensor
113: * @param sensorRead the sensor's read value at the time of the event
114: * @param buttonState the state of the sensor's buttons at the time of
115: * the event, where a 1 in the array indicates that the button at that
116: * index is down, and a 0 indicates that button is up; may be null
117: * @param button index of the button that changed state, from 0 to
118: * <code>(buttonCount - 1)</code>, or the value <code>NOBUTTON</code>
119: * @param time the time in nanoseconds at which the
120: * <code>dispatchEvents</code> method of
121: * <code>SensorEventAgent</code> was called to generate this event,
122: * usually from the <code>processStimulus</code> method of a Behavior
123: * @param lastTime the time in nanoseconds at which the
124: * <code>dispatchEvents</code> method of
125: * <code>SensorEventAgent</code> was <i>last</i> called to generate
126: * events, usually from the <code>processStimulus</code> method of a
127: * <code>Behavior</code>; may be used to measure frame time in
128: * behaviors that wake up every frame
129: */
130: public SensorEvent(Object source, int id, Sensor sensor,
131: Transform3D sensorRead, int[] buttonState, int button,
132: long time, long lastTime) {
133:
134: this .source = source;
135: this .id = id;
136: this .sensor = sensor;
137: this .button = button;
138: this .time = time;
139: this .lastTime = lastTime;
140: if (sensorRead == null)
141: throw new NullPointerException("sensorRead can't be null");
142: this .sensorRead = new Transform3D(sensorRead);
143: if (buttonState != null) {
144: this .buttonState = new int[buttonState.length];
145: for (int i = 0; i < buttonState.length; i++)
146: this .buttonState[i] = buttonState[i];
147: }
148: this .ephemeral = false;
149: }
150:
151: /**
152: * Creates a new <i>ephemeral</i> <code>SensorEvent</code>. In order
153: * to avoid creating large numbers of sensor event objects, the events
154: * passed to the button and read listeners by the
155: * <code>dispatchEvents</code> method of <code>SensorEventAgent</code>
156: * are valid only until the listener returns. If the event needs to
157: * be retained then they must be copied with the
158: * <code>SensorEvent(SensorEvent)</code> constructor.
159: */
160: public SensorEvent() {
161: this .ephemeral = true;
162: }
163:
164: /**
165: * Creates a copy of the given <code>SensorEvent</code>. Listeners
166: * must use this constructor to copy events that need to be retained.
167: * NOTE: The <code>Sensor</code> and <code>Object</code> references
168: * returned by <code>getSensor</code> and <code>getSource</code>
169: * remain references to the original objects.
170: *
171: * @param e the event to be copied
172: */
173: public SensorEvent(SensorEvent e) {
174: this .source = e.source;
175: this .id = e.id;
176: this .sensor = e.sensor;
177: this .button = e.button;
178: this .time = e.time;
179: this .lastTime = e.lastTime;
180: if (e.sensorRead == null)
181: throw new NullPointerException("sensorRead can't be null");
182: this .sensorRead = new Transform3D(e.sensorRead);
183: if (e.buttonState != null) {
184: this .buttonState = new int[e.buttonState.length];
185: for (int i = 0; i < e.buttonState.length; i++)
186: this .buttonState[i] = e.buttonState[i];
187: }
188: this .ephemeral = false;
189: }
190:
191: /**
192: * Sets the fields of an ephemeral event. No objects are copied. An
193: * <code>IllegalStateException</code> will be thrown if this event
194: * is not ephemeral.
195: *
196: * @param source a reference to the originating object which
197: * instantiated the <code>SensorEventAgent</code>, usually a
198: * <code>Behavior</code>; may be null
199: * @param id event type
200: * @param sensor a reference to the provoking sensor
201: * @param sensorRead the sensor's read value at the time of the event
202: * @param buttonState the state of the sensor's buttons at the time of
203: * the event; a 1 in the array indicates that the button at that
204: * index is down, while a 0 indicates that button is up
205: * @param button index of the button that changed state, from 0 to
206: * <code>(buttonCount - 1)</code>, or the value <code>NOBUTTON</code>
207: * @param time the time in nanoseconds at which the
208: * <code>dispatchEvents</code> method of
209: * <code>SensorEventAgent</code> was called to generate this event,
210: * usually from the <code>processStimulus</code> method of a Behavior
211: * @param lastTime the time in nanoseconds at which the
212: * <code>dispatchEvents</code> method of
213: * <code>SensorEventAgent</code> was <i>last</i> called to generate
214: * events, usually from the <code>processStimulus</code> method of a
215: * <code>Behavior</code>; may be used to measure frame time in
216: * behaviors that wake up every frame
217: */
218: public void set(Object source, int id, Sensor sensor,
219: Transform3D sensorRead, int[] buttonState, int button,
220: long time, long lastTime) {
221:
222: if (!ephemeral)
223: throw new IllegalStateException(
224: "Can't set the fields of non-ephemeral events");
225:
226: this .source = source;
227: this .id = id;
228: this .sensor = sensor;
229: if (sensorRead == null)
230: throw new NullPointerException("sensorRead can't be null");
231: this .sensorRead = sensorRead;
232: this .buttonState = buttonState;
233: this .button = button;
234: this .time = time;
235: this .lastTime = lastTime;
236: }
237:
238: /**
239: * Gets a reference to the originating object which instantiated the
240: * <code>SensorEventAgent</code>, usually a <code>Behavior</code>; may
241: * be null.
242: * @return the originating object
243: */
244: public Object getSource() {
245: return source;
246: }
247:
248: /**
249: * Gets the event type.
250: * @return the event id
251: */
252: public int getID() {
253: return id;
254: }
255:
256: /**
257: * Gets a reference to the provoking sensor.
258: * @return the provoking sensor
259: */
260: public Sensor getSensor() {
261: return sensor;
262: }
263:
264: /**
265: * Gets the time in nanoseconds at which the
266: * <code>dispatchEvents</code> method of <code>SensorEventAgent</code>
267: * was called to generate this event, usually from the
268: * <code>processStimulus</code> method of a <code>Behavior</code>.
269: * @return time in nanoseconds
270: */
271: public long getTime() {
272: return time;
273: }
274:
275: /**
276: * Gets the time in nanoseconds at which the
277: * <code>dispatchEvents</code> method of <code>SensorEventAgent</code>
278: * was <i>last</i> called to generate events, usually from the
279: * <code>processStimulus</code> method of a <code>Behavior</code>; may
280: * be used to measure frame time in behaviors that wake up every
281: * frame.
282: * @return last time in nanoseconds
283: */
284: public long getLastTime() {
285: return lastTime;
286: }
287:
288: /**
289: * Copies the sensor's read value at the time of the event into the
290: * given <code>Transform3D</code>.
291: *
292: * @param t the transform to receive the sensor read
293: */
294: public void getSensorRead(Transform3D t) {
295: t.set(sensorRead);
296: }
297:
298: /**
299: * Gets the index of the button that changed state when passed to a
300: * <code>pressed</code> or <code>released</code> callback. The index
301: * may range from 0 to <code>(sensor.getSensorButtonCount() -
302: * 1)</code>. The value returned is <code>NOBUTTON</code> for events
303: * passed to a <code>read</code> or <code>dragged</code> callback.
304: * @return the button index
305: */
306: public int getButton() {
307: return button;
308: }
309:
310: /**
311: * Copies the state of the sensor's buttons at the time of the event
312: * into the given array. A 1 in the array indicates that the button
313: * at that index is down, while a 0 indicates that button is up.
314: * @param buttonState the state of the sensor buttons
315: */
316: public void getButtonState(int[] buttonState) {
317: if (buttonState.length != this .buttonState.length)
318: throw new ArrayIndexOutOfBoundsException(
319: "buttonState array is the wrong length");
320:
321: for (int i = 0; i < buttonState.length; i++)
322: buttonState[i] = this .buttonState[i];
323: }
324:
325: /**
326: * Returns true if this event is <i>ephemeral</i> and is valid only
327: * until the listener returns. A copy of the event can be created by
328: * passing it to the <code>SensorEvent(SensorEvent)</code>
329: * constructor.
330: */
331: public boolean isEphemeral() {
332: return ephemeral;
333: }
334: }
|