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;

	/**
	 * Standard constructor.
	 */
	private UIBundlingThread() {
		tasksQueue = new ConcurrentLinkedQueue<Runnable>();

		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}.
	 */
	public void run() {
		if(!tasksQueue.isEmpty())
			processQueue();
	}

	/**
	 * Process the complete queue.
	 */
	private synchronized void processQueue() {
		Display display;
		if(PlatformUI.getWorkbench() != null)
			display = PlatformUI.getWorkbench().getDisplay();
		else
			display = Display.getDefault();
		Runnable r;
		while( (r=tasksQueue.poll()) != null){	
			display.asyncExec(r);
		}
	
	}

	/**
	 * Adds the specified runnable to the queue.
	 * 
	 * @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);
	}

}

@@ -987,29 +987,56 @@
 asksQueue;%0A%0A
+%09private Display display;%0A%0A
 %09/**%0A
-
 %09 * Standard
@@ -1138,17 +1138,216 @@
 ble%3E();%0A
+%09%09display = Display.getCurrent();%0A%09%09if(display == null)%7B%0A%09%09%09if(PlatformUI.getWorkbench() != null)%0A%09%09%09%09display = PlatformUI.getWorkbench().getDisplay();%0A%09%09%09else%0A%09%09%09%09display = Display.getDefault();%0A%09%09%7D
 %0A
-
 %09%09Execut
@@ -1440,16 +1440,21 @@
 CONDS);%0A
+%09%09%0A%09%0A
 %09%7D%0A%0A%09/**
@@ -1656,16 +1656,19 @@
 hread();
+%09%09%09
 %0A%09%09%7D%0A%0A%09%09
@@ -1878,162 +1878,10 @@
 () %7B
-%0A
 %09%09
-Display display;%0A%09%09if(PlatformUI.getWorkbench() != null)%0A%09%09%09display = PlatformUI.getWorkbench().getDisplay();%0A%09%09else%0A%09%09%09display = Display.getDefault();
 %0A%09%09R
@@ -1969,24 +1969,24 @@
 %0A%09%0A%09%7D%0A%0A%09/**%0A
-
 %09 * Adds the
@@ -2014,24 +2014,52 @@
 o the queue.
+ Should not be used for RAP.
 %0A%09 * %0A%09 * @p

optimize performance