/*
* Copyright 2015 Nokia Solutions and Networks
* Licensed under the Apache License, Version 2.0,
* see license.txt file for details.
*/
package org.robotframework.red.swt;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.eclipse.swt.widgets.Display;
/**
* @author Michal Anglart
*
*/
public class SwtThread {
public static boolean isSwtThread() {
return Display.getCurrent() != null;
}
public static void syncExec(final Runnable runnable) {
syncExec(Display.getDefault(), runnable);
}
public static void syncExec(final Display display, final Runnable runnable) {
display.syncExec(runnable);
}
public static <T> T syncEval(final Evaluation<T> evaluation) {
return syncEval(Display.getDefault(), evaluation);
}
public static <T> T syncEval(final Display display, final Evaluation<T> evaluation) {
display.syncExec(evaluation);
return evaluation.result;
}
public static void asyncExec(final Runnable runnable) {
asyncExec(Display.getDefault(), runnable);
}
public static void asyncExec(final Display display, final Runnable runnable) {
display.asyncExec(runnable);
}
public static <T> Future<T> asyncEval(final Evaluation<T> evaluation) {
return asyncEval(Display.getDefault(), evaluation);
}
public static <T> Future<T> asyncEval(final Display display, final Evaluation<T> evaluation) {
display.asyncExec(evaluation);
return new EvaluationPromise<>(evaluation);
}
public abstract static class Evaluation<T> implements Runnable {
private T result = null;
private boolean isDone = false;
@Override
public final void run() {
result = runCalculation();
isDone = true;
}
public abstract T runCalculation();
}
private static class EvaluationPromise<T> implements Future<T> {
private final Evaluation<T> evaluation;
public EvaluationPromise(final Evaluation<T> evaluation) {
this.evaluation = evaluation;
}
@Override
public boolean cancel(final boolean mayInterruptIfRunning) {
return false;
}
@Override
public boolean isCancelled() {
return false;
}
@Override
public boolean isDone() {
return evaluation.isDone;
}
@Override
public T get() throws InterruptedException, ExecutionException {
while (!isDone()) {
Thread.sleep(500);
}
return evaluation.result;
}
@Override
public T get(final long timeout, final TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException {
final long timeoutInMs = TimeUnit.MILLISECONDS.convert(timeout, unit);
final long start = System.currentTimeMillis();
while (timeoutIsNotReached(start, timeoutInMs)) {
if (isDone()) {
return evaluation.result;
}
Thread.sleep(500);
}
throw new TimeoutException("Timeout has been reached");
}
private boolean timeoutIsNotReached(final long start, final long timeout) {
final long current = System.currentTimeMillis();
return current - start < timeout;
}
}
}