package org.marketcetera.photon.commons.ui;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import javax.annotation.concurrent.ThreadSafe;
import org.eclipse.swt.widgets.Display;
import org.marketcetera.photon.commons.GuiExecutor;
import org.marketcetera.photon.commons.SimpleExecutorService;
import org.marketcetera.photon.commons.Validate;
import org.marketcetera.util.misc.ClassVersion;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
/* $License$ */
/**
* An executor service that executes tasks asynchronously on a SWT display
* thread. It does not support {@link #shutdownNow()}, which will simply call
* {@link #shutdown()} and return null.
* <p>
* As long as the display is not disposed, tasks successfully submitted to this
* executor service will execute even if a shutdown is requested in the
* meantime. When all have been completed, {@link #isTerminated()} will return
* true.
* <p>
* If the display is disposed, a clean shutdown will no longer be possible.
* Tasks that were submitted, but not completed may be lost, and
* {@link #isTerminated()} and
* {@link #awaitTermination(long, java.util.concurrent.TimeUnit)} will always
* return false. Tasks submitted after the display is disposed will be
* immediately rejected.
*
* @author <a href="mailto:will@marketcetera.com">Will Horn</a>
* @version $Id: DisplayThreadExecutor.java 16672 2013-08-29 15:26:41Z colin $
* @since 2.0.0
*/
@ClassVersion("$Id: DisplayThreadExecutor.java 16672 2013-08-29 15:26:41Z colin $")
@ThreadSafe
public final class DisplayThreadExecutor extends SimpleExecutorService
implements GuiExecutor {
private static final LoadingCache<Display,DisplayThreadExecutor> sMap = CacheBuilder.newBuilder().build(new CacheLoader<Display,DisplayThreadExecutor>() {
@Override
public DisplayThreadExecutor load(Display from)
throws Exception
{
return new DisplayThreadExecutor(from);
}});
/**
* Returns the singleton executor for the given SWT display.
*
* @param display
* the SWT display
* @return the executor service
* @throws IllegalArgumentException
* if display is null
*/
public static ExecutorService getInstance(final Display display) {
Validate.notNull(display, "display"); //$NON-NLS-1$
try {
return sMap.get(display);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
private final Display mDisplay;
private DisplayThreadExecutor(Display display) {
mDisplay = display;
}
@Override
public void doExecute(Runnable command) {
if (mDisplay.equals(Display.getCurrent())) {
command.run();
} else {
mDisplay.asyncExec(command);
}
}
}