package org.jnario.lib;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.eclipse.xtext.xbase.lib.Functions.Function0;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.jnario.lib.Clock;
import org.jnario.lib.Sleeper;
import org.jnario.lib.TimeoutError;
/**
* A helper for automatically waiting until a condition turns true. Use it like this:
*
* <code>
* fact "Wait for something"{
* // define wait condition using lambdas
* waitUntil[1 > 0]
* // configuration options
* waitUntil[
* message = "Custom error message"
* duration = 100
* pollingInterval = 10
* 1 > 0
* ]
* }
* </code>
*/
@SuppressWarnings("all")
public class Wait {
/**
* Wait until the provided function evaluates to true.
*/
public static void waitUntil(final Function1<Wait, Boolean> initializer) {
final Wait wait = new Wait(Sleeper.SYSTEM_SLEEPER, Clock.SYSTEM_CLOCK);
final Function0<Boolean> _function = new Function0<Boolean>() {
public Boolean apply() {
return initializer.apply(wait);
}
};
final Function0<Boolean> condition = _function;
wait.until(condition);
}
private final Sleeper sleeper;
private final Clock clock;
private String message = "Timeout occurred";
private long duration = 500l;
private long pollingInterval = 50l;
public Wait(final Sleeper sleeper, final Clock clock) {
this.sleeper = sleeper;
this.clock = clock;
}
public void until(final Function0<Boolean> condition) {
try {
final long start = this.clock.currentTime();
while ((!(condition.apply()).booleanValue())) {
{
boolean _timeOut = this.timeOut(start);
if (_timeOut) {
throw new TimeoutError(this.message);
}
this.sleeper.sleep(this.pollingInterval);
}
}
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
public boolean timeOut(final long start) {
long _currentTime = this.clock.currentTime();
return (_currentTime > (start + this.duration));
}
public String setMessage(final String message) {
return this.message = message;
}
public long setDuration(final long duration) {
return this.duration = duration;
}
public long setPollingInterval(final long pollingInterval) {
return this.pollingInterval = pollingInterval;
}
}