blob: 9e25b8924bdc6052c3b527d3e637b43094bafea7 (
plain) (
tree)
|
|
/*******************************************************************************
* Copyright (c) 2007, 2010 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ericsson - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.swt.widgets.Display;
/*
* This class provides a way to wait for an asynchronous ServerEvent
* to occur. The user of this class specifies which event is of
* interest using the proper constructor or the registerForEvent() method.
* waitForEvent() can then be called to block until the event occurs or
* the timeout elapses.
*
* Note that if the event occurs after regsiterForEvent() is called but
* before waitForEvent() is called, waitForEvent() will return immediatly
* since it will know the event has already occured.
*/
public class ServiceEventWaitor<V> {
/*
* Indicates we will wait forever. Otherwise the time specified
* is in milliseconds.
*/
public final static int WAIT_FOREVER = 0 ;
/* The type of event to wait for */
private Class<V> fEventTypeClass;
private final DsfSession fSession;
private V fEvent;
private final Display fDisplay;
/* Empty contructor. registerForEvent() should be called when
* this constructor is used.
*/
public ServiceEventWaitor(DsfSession session) {
fDisplay = Display.getDefault();
fSession = session;
}
/* Contructor that takes the eventClass as parameter. This is a shortcut
* that avoids calling registerForEvent()
*/
public ServiceEventWaitor(DsfSession session, Class<V> eventClass) {
this(session);
registerForEvent(eventClass);
}
/* Specify which event to wait for, and add ourselves as
* a listener with the session
*/
public void registerForEvent(Class<V> eventClass) {
fEventTypeClass = eventClass;
fEvent = null;
fSession.addServiceEventListener(this, null);
}
public DsfSession getSession() {
return fSession;
}
public void dispose() {
if (fEventTypeClass != null) fSession.removeServiceEventListener(this);
}
/* Block until 'timeout' or the previously specified event has been
* received. The reason we don's specify the event as a parameter
* is that we must be ready for the event to occur event before
* this method is called.
*/
public synchronized V waitForEvent(int timeout) throws Exception {
if (fEventTypeClass == null) {
throw new Exception("Event to wait for has not been specified!");
}
// The event might have already been received
if (fEvent != null) return fEvent;
long timeoutTime = System.currentTimeMillis() + timeout;
while (timeoutTime > System.currentTimeMillis()) {
if (fEvent != null) {
break;
}
if (!fDisplay.readAndDispatch()) {
Thread.sleep(0);
}
}
if (fEvent == null) {
throw new Exception("Timed out waiting for ServiceEvent: " + fEventTypeClass.getName());
}
return fEvent;
}
/*
* Listen to all possible events by having the base class be the parameter.
* and then igure out if that event is the one we were waiting for.
*/
@DsfServiceEventHandler
public void eventDispatched(V event) {
if (fEventTypeClass.isAssignableFrom(event.getClass())) {
synchronized(this) {
fEvent = event;
notifyAll();
}
}
}
}
|