40 /**
41 * EventDispatcher. Used by various classes in the Java Sound implementation
42 * to send events.
43 *
44 * @author David Rivas
45 * @author Kara Kytle
46 * @author Florian Bomers
47 */
48 final class EventDispatcher implements Runnable {
49
50 /**
51 * time of inactivity until the auto closing clips
52 * are closed
53 */
54 private static final int AUTO_CLOSE_TIME = 5000;
55
56
57 /**
58 * List of events
59 */
60 private final ArrayList eventQueue = new ArrayList();
61
62
63 /**
64 * Thread object for this EventDispatcher instance
65 */
66 private Thread thread = null;
67
68
69 /*
70 * support for auto-closing Clips
71 */
72 private final ArrayList<ClipInfo> autoClosingClips = new ArrayList<ClipInfo>();
73
74 /*
75 * support for monitoring data lines
76 */
77 private final ArrayList<LineMonitor> lineMonitors = new ArrayList<LineMonitor>();
78
79 /**
80 * Approximate interval between calls to LineMonitor.checkLine
169 synchronized (this) {
170
171 // Wait till there is an event in the event queue.
172 try {
173
174 if (eventQueue.size() == 0) {
175 if (autoClosingClips.size() > 0 || lineMonitors.size() > 0) {
176 int waitTime = AUTO_CLOSE_TIME;
177 if (lineMonitors.size() > 0) {
178 waitTime = LINE_MONITOR_TIME;
179 }
180 wait(waitTime);
181 } else {
182 wait();
183 }
184 }
185 } catch (InterruptedException e) {
186 }
187 if (eventQueue.size() > 0) {
188 // Remove the event from the queue and dispatch it to the listeners.
189 eventInfo = (EventInfo) eventQueue.remove(0);
190 }
191
192 } // end of synchronized
193 if (eventInfo != null) {
194 processEvent(eventInfo);
195 } else {
196 if (autoClosingClips.size() > 0) {
197 closeAutoClosingClips();
198 }
199 if (lineMonitors.size() > 0) {
200 monitorLines();
201 }
202 }
203 }
204
205
206 /**
207 * Queue the given event in the event queue.
208 */
209 private synchronized void postEvent(EventInfo eventInfo) {
213
214
215 /**
216 * A loop to dispatch events.
217 */
218 public void run() {
219
220 while (true) {
221 try {
222 dispatchEvents();
223 } catch (Throwable t) {
224 if (Printer.err) t.printStackTrace();
225 }
226 }
227 }
228
229
230 /**
231 * Send audio and MIDI events.
232 */
233 void sendAudioEvents(Object event, List listeners) {
234 if ((listeners == null)
235 || (listeners.size() == 0)) {
236 // nothing to do
237 return;
238 }
239
240 start();
241
242 EventInfo eventInfo = new EventInfo(event, listeners);
243 postEvent(eventInfo);
244 }
245
246
247 /*
248 * go through the list of registered auto-closing
249 * Clip instances and close them, if appropriate
250 *
251 * This method is called in regular intervals
252 */
253 private void closeAutoClosingClips() {
375 lineMonitors.remove(lm);
376 }
377 if (Printer.debug)Printer.debug("< EventDispatcher.removeLineMonitor finished -- now ("+lineMonitors.size()+" monitors)");
378 }
379
380 // /////////////////////////////////// INNER CLASSES ////////////////////////////////////////// //
381
382 /**
383 * Container for an event and a set of listeners to deliver it to.
384 */
385 private class EventInfo {
386
387 private final Object event;
388 private final Object[] listeners;
389
390 /**
391 * Create a new instance of this event Info class
392 * @param event the event to be dispatched
393 * @param listeners listener list; will be copied
394 */
395 EventInfo(Object event, List listeners) {
396 this.event = event;
397 this.listeners = listeners.toArray();
398 }
399
400 Object getEvent() {
401 return event;
402 }
403
404 int getListenerCount() {
405 return listeners.length;
406 }
407
408 Object getListener(int index) {
409 return listeners[index];
410 }
411
412 } // class EventInfo
413
414
415 /**
|
40 /**
41 * EventDispatcher. Used by various classes in the Java Sound implementation
42 * to send events.
43 *
44 * @author David Rivas
45 * @author Kara Kytle
46 * @author Florian Bomers
47 */
48 final class EventDispatcher implements Runnable {
49
50 /**
51 * time of inactivity until the auto closing clips
52 * are closed
53 */
54 private static final int AUTO_CLOSE_TIME = 5000;
55
56
57 /**
58 * List of events
59 */
60 private final ArrayList<EventInfo> eventQueue = new ArrayList<>();
61
62
63 /**
64 * Thread object for this EventDispatcher instance
65 */
66 private Thread thread = null;
67
68
69 /*
70 * support for auto-closing Clips
71 */
72 private final ArrayList<ClipInfo> autoClosingClips = new ArrayList<ClipInfo>();
73
74 /*
75 * support for monitoring data lines
76 */
77 private final ArrayList<LineMonitor> lineMonitors = new ArrayList<LineMonitor>();
78
79 /**
80 * Approximate interval between calls to LineMonitor.checkLine
169 synchronized (this) {
170
171 // Wait till there is an event in the event queue.
172 try {
173
174 if (eventQueue.size() == 0) {
175 if (autoClosingClips.size() > 0 || lineMonitors.size() > 0) {
176 int waitTime = AUTO_CLOSE_TIME;
177 if (lineMonitors.size() > 0) {
178 waitTime = LINE_MONITOR_TIME;
179 }
180 wait(waitTime);
181 } else {
182 wait();
183 }
184 }
185 } catch (InterruptedException e) {
186 }
187 if (eventQueue.size() > 0) {
188 // Remove the event from the queue and dispatch it to the listeners.
189 eventInfo = eventQueue.remove(0);
190 }
191
192 } // end of synchronized
193 if (eventInfo != null) {
194 processEvent(eventInfo);
195 } else {
196 if (autoClosingClips.size() > 0) {
197 closeAutoClosingClips();
198 }
199 if (lineMonitors.size() > 0) {
200 monitorLines();
201 }
202 }
203 }
204
205
206 /**
207 * Queue the given event in the event queue.
208 */
209 private synchronized void postEvent(EventInfo eventInfo) {
213
214
215 /**
216 * A loop to dispatch events.
217 */
218 public void run() {
219
220 while (true) {
221 try {
222 dispatchEvents();
223 } catch (Throwable t) {
224 if (Printer.err) t.printStackTrace();
225 }
226 }
227 }
228
229
230 /**
231 * Send audio and MIDI events.
232 */
233 void sendAudioEvents(Object event, List<Object> listeners) {
234 if ((listeners == null)
235 || (listeners.size() == 0)) {
236 // nothing to do
237 return;
238 }
239
240 start();
241
242 EventInfo eventInfo = new EventInfo(event, listeners);
243 postEvent(eventInfo);
244 }
245
246
247 /*
248 * go through the list of registered auto-closing
249 * Clip instances and close them, if appropriate
250 *
251 * This method is called in regular intervals
252 */
253 private void closeAutoClosingClips() {
375 lineMonitors.remove(lm);
376 }
377 if (Printer.debug)Printer.debug("< EventDispatcher.removeLineMonitor finished -- now ("+lineMonitors.size()+" monitors)");
378 }
379
380 // /////////////////////////////////// INNER CLASSES ////////////////////////////////////////// //
381
382 /**
383 * Container for an event and a set of listeners to deliver it to.
384 */
385 private class EventInfo {
386
387 private final Object event;
388 private final Object[] listeners;
389
390 /**
391 * Create a new instance of this event Info class
392 * @param event the event to be dispatched
393 * @param listeners listener list; will be copied
394 */
395 EventInfo(Object event, List<Object> listeners) {
396 this.event = event;
397 this.listeners = listeners.toArray();
398 }
399
400 Object getEvent() {
401 return event;
402 }
403
404 int getListenerCount() {
405 return listeners.length;
406 }
407
408 Object getListener(int index) {
409 return listeners[index];
410 }
411
412 } // class EventInfo
413
414
415 /**
|