/** * Until {@link #condition()} becomes <code>true</code> or the timeout elapses, call {@link * Display#sleep()} and run the event loop. * * <p>If <code>timeout < 0</code>, the event loop is never driven and only the condition is * checked. If <code>timeout == 0</code>, the event loop is driven at most once, but <code> * Display.sleep()</code> is never invoked. * * <p>The condition gets rechecked every <code>interval</code> milliseconds, even if no events * were read from the queue. * * @param display the display to run the event loop of * @param timeout the timeout in milliseconds * @param interval the interval to re-check the condition in milliseconds * @return <code>true</code> if the condition became <code>true</code>, <code>false</code> if the * timeout elapsed */ public final boolean waitForCondition(Display display, long timeout, long interval) { // if the condition already holds, succeed if (condition()) return true; if (timeout < 0) return false; // if driving the event loop once makes the condition hold, succeed // without spawning a thread. driveEventQueue(display); if (condition()) return true; // if the timeout is negative or zero, fail if (timeout == 0) return false; // repeatedly sleep until condition becomes true or timeout elapses DisplayWaiter waiter = new DisplayWaiter(display, true); long currentTimeMillis = System.currentTimeMillis(); long finalTimeout = timeout + currentTimeMillis; if (finalTimeout < currentTimeMillis) finalTimeout = Long.MAX_VALUE; boolean condition; try { do { waiter.restart(interval); if (display.sleep()) driveEventQueue(display); condition = condition(); } while (!condition && finalTimeout > System.currentTimeMillis()); } finally { waiter.stop(); } return condition; }
/** * Until {@link #condition()} becomes <code>true</code> or the timeout elapses, call {@link * Display#sleep()} and run the event loop. * * <p>If <code>timeout < 0</code>, the event loop is never driven and only the condition is * checked. If <code>timeout == 0</code>, the event loop is driven at most once, but <code> * Display.sleep()</code> is never invoked. * * @param display the display to run the event loop of * @param timeout the timeout in milliseconds * @return <code>true</code> if the condition became <code>true</code>, <code>false</code> if the * timeout elapsed */ public final boolean waitForCondition(Display display, long timeout) { // if the condition already holds, succeed if (condition()) return true; if (timeout < 0) return false; // if driving the event loop once makes the condition hold, succeed // without spawning a thread. driveEventQueue(display); if (condition()) return true; // if the timeout is negative or zero, fail if (timeout == 0) return false; // repeatedly sleep until condition becomes true or timeout elapses DisplayWaiter waiter = new DisplayWaiter(display); DisplayWaiter.Timeout timeoutState = waiter.start(timeout); boolean condition; try { do { if (display.sleep()) driveEventQueue(display); condition = condition(); } while (!condition && !timeoutState.hasTimedOut()); } finally { waiter.stop(); } return condition; }
/** * Call {@link Display#sleep()} and run the event loop once if <code>sleep</code> returns before * the timeout elapses. Returns <code>true</code> if any events were processed, <code>false</code> * if not. * * <p>If <code>timeout < 0</code>, nothing happens and false is returned. If <code>timeout == 0 * </code>, the event loop is driven exactly once, but <code>Display.sleep()</code> is never * invoked. * * @param display the display to run the event loop of * @param timeout the timeout in milliseconds * @return <code>true</code> if any event was taken off the event queue, <code>false</code> if not */ public static boolean runEventLoop(Display display, long timeout) { if (timeout < 0) return false; if (timeout == 0) return driveEventQueue(display); // repeatedly sleep until condition becomes true or timeout elapses DisplayWaiter waiter = new DisplayWaiter(display); DisplayWaiter.Timeout timeoutState = waiter.start(timeout); boolean events = false; if (display.sleep() && !timeoutState.hasTimedOut()) { driveEventQueue(display); events = true; } waiter.stop(); return events; }