package org.csstudio.ui.util.thread;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;
/**
*
* A singleton back thread which will help to execute tasks in UI thread.
* This way we avoid slow downs, that occur on several
* operating systems, when Display.asyncExec() is called very often from
* background threads.
*
* This thread sleeps for a time, which is below the processing capacity of
* human eyes and brain - so the user will not feel any delay.
*
* @author Sven Wende, Xihui Chen
*
*/
public final class UIBundlingThread implements Runnable {
/**
* The singleton instance.
*/
private static UIBundlingThread instance;
/**
* A queue, which contains runnables that process the events that occured
* during the last SLEEP_TIME milliseconds.
*/
private Queue<Runnable> tasksQueue;
private Display display;
/**
* Standard constructor.
*/
private UIBundlingThread() {
tasksQueue = new ConcurrentLinkedQueue<Runnable>();
display = Display.getCurrent();
if(display == null){
if(PlatformUI.getWorkbench() != null)
display = PlatformUI.getWorkbench().getDisplay();
else
display = Display.getDefault();
}
Executors.newScheduledThreadPool(1)
.scheduleAtFixedRate(this, 100, 20, TimeUnit.MILLISECONDS);
}
/**
* Gets the singleton instance.
*
* @return the singleton instance
*/
public static synchronized UIBundlingThread getInstance() {
if (instance == null) {
instance = new UIBundlingThread();
}
return instance;
}
/**
* {@inheritDoc}.
*/
@Override
public void run() {
if(!tasksQueue.isEmpty())
processQueue();
}
/**
* Process the complete queue.
*/
private synchronized void processQueue() {
Runnable r;
while( (r=tasksQueue.poll()) != null){
display.asyncExec(r);
}
}
/**
* Adds the specified runnable to the queue. Should not be used for RAP.
*
* @param runnable
* the runnable
*/
public synchronized void addRunnable(final Runnable runnable) {
tasksQueue.add(runnable);
}
/**
* Adds the specified runnable to the queue. Fake method for adapting RAP.
*
* @param runnable
* the runnable
*/
public synchronized void addRunnable(final Display display, final Runnable runnable) {
addRunnable(runnable);
}
}