Method from com.sun.media.sound.EventDispatcher Detail: |
void addLineMonitor(LineMonitor lm) {
if (Printer.trace)Printer.trace(" > EventDispatcher.addLineMonitor("+lm+")");
synchronized(lineMonitors) {
if (lineMonitors.indexOf(lm) >= 0) {
if (Printer.trace)Printer.trace("< EventDispatcher.addLineMonitor finished -- this monitor already exists!");
return;
}
if (Printer.debug)Printer.debug("EventDispatcher: adding line monitor "+lm);
lineMonitors.add(lm);
}
synchronized (this) {
// need to interrupt the infinite wait()
notifyAll();
}
if (Printer.debug)Printer.debug("< EventDispatcher.addLineMonitor finished -- now ("+lineMonitors.size()+" monitors)");
}
Add this LineMonitor instance to the list of monitors |
void autoClosingClipClosed(AutoClosingClip clip) {
// nothing to do -- is removed from arraylist above
}
called from auto-closing clips when their closed() method is called |
void autoClosingClipOpened(AutoClosingClip clip) {
if (Printer.debug)Printer.debug(" > EventDispatcher.autoClosingClipOpened ");
int index = 0;
synchronized(autoClosingClips) {
index = getAutoClosingClipIndex(clip);
if (index == -1) {
if (Printer.debug)Printer.debug("EventDispatcher: adding auto-closing clip "+clip);
autoClosingClips.add(new ClipInfo(clip));
}
}
if (index == -1) {
synchronized (this) {
// this is only for the case that the first clip is set to autoclosing,
// and it is already open, and nothing is done with it.
// EventDispatcher.process() method would block in wait() and
// never close this first clip, keeping the device open.
notifyAll();
}
}
if (Printer.debug)Printer.debug("< EventDispatcher.autoClosingClipOpened finished("+autoClosingClips.size()+" clips)");
}
called from auto-closing clips when one of their open() method is called |
protected void dispatchEvents() {
EventInfo eventInfo = null;
synchronized (this) {
// Wait till there is an event in the event queue.
try {
if (eventQueue.size() == 0) {
if (autoClosingClips.size() > 0 || lineMonitors.size() > 0) {
int waitTime = AUTO_CLOSE_TIME;
if (lineMonitors.size() > 0) {
waitTime = LINE_MONITOR_TIME;
}
wait(waitTime);
} else {
wait();
}
}
} catch (InterruptedException e) {
}
if (eventQueue.size() > 0) {
// Remove the event from the queue and dispatch it to the listeners.
eventInfo = (EventInfo) eventQueue.remove(0);
}
} // end of synchronized
if (eventInfo != null) {
processEvent(eventInfo);
} else {
if (autoClosingClips.size() > 0) {
closeAutoClosingClips();
}
if (lineMonitors.size() > 0) {
monitorLines();
}
}
}
Wait until there is something in the event queue to process. Then
dispatch the event to the listeners.The entire method does not
need to be synchronized since this includes taking the event out
from the queue and processing the event. We only need to provide
exclusive access over the code where an event is removed from the
queue. |
protected void processEvent(EventInfo eventInfo) {
int count = eventInfo.getListenerCount();
// process an LineEvent
if (eventInfo.getEvent() instanceof LineEvent) {
LineEvent event = (LineEvent) eventInfo.getEvent();
if (Printer.debug) Printer.debug("Sending "+event+" to "+count+" listeners");
for (int i = 0; i < count; i++) {
try {
((LineListener) eventInfo.getListener(i)).update(event);
} catch (Throwable t) {
if (Printer.err) t.printStackTrace();
}
}
return;
}
// process a MetaMessage
if (eventInfo.getEvent() instanceof MetaMessage) {
MetaMessage event = (MetaMessage)eventInfo.getEvent();
for (int i = 0; i < count; i++) {
try {
((MetaEventListener) eventInfo.getListener(i)).meta(event);
} catch (Throwable t) {
if (Printer.err) t.printStackTrace();
}
}
return;
}
// process a Controller or Mode Event
if (eventInfo.getEvent() instanceof ShortMessage) {
ShortMessage event = (ShortMessage)eventInfo.getEvent();
int status = event.getStatus();
// Controller and Mode events have status byte 0xBc, where
// c is the channel they are sent on.
if ((status & 0xF0) == 0xB0) {
for (int i = 0; i < count; i++) {
try {
((ControllerEventListener) eventInfo.getListener(i)).controlChange(event);
} catch (Throwable t) {
if (Printer.err) t.printStackTrace();
}
}
}
return;
}
Printer.err("Unknown event type: " + eventInfo.getEvent());
}
Invoked when there is at least one event in the queue.
Implement this as a callback to process one event. |
void removeLineMonitor(LineMonitor lm) {
if (Printer.trace)Printer.trace(" > EventDispatcher.removeLineMonitor("+lm+")");
synchronized(lineMonitors) {
if (lineMonitors.indexOf(lm) < 0) {
if (Printer.trace)Printer.trace("< EventDispatcher.removeLineMonitor finished -- this monitor does not exist!");
return;
}
if (Printer.debug)Printer.debug("EventDispatcher: removing line monitor "+lm);
lineMonitors.remove(lm);
}
if (Printer.debug)Printer.debug("< EventDispatcher.removeLineMonitor finished -- now ("+lineMonitors.size()+" monitors)");
}
Remove this LineMonitor instance from the list of monitors |
public void run() {
while (true) {
try {
dispatchEvents();
} catch (Throwable t) {
if (Printer.err) t.printStackTrace();
}
}
}
A loop to dispatch events. |
void sendAudioEvents(Object event,
List listeners) {
if ((listeners == null)
|| (listeners.size() == 0)) {
// nothing to do
return;
}
start();
EventInfo eventInfo = new EventInfo(event, listeners);
postEvent(eventInfo);
}
Send audio and MIDI events. |
synchronized void start() {
if(thread == null) {
thread = JSSecurityManager.createThread(this,
"Java Sound Event Dispatcher", // name
true, // daemon
-1, // priority
true); // doStart
}
}
This start() method starts an event thread if one is not already active. |