xapi.time.impl.RunOnce Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of xapi-gwt Show documentation
Show all versions of xapi-gwt Show documentation
This module exists solely to package all other gwt modules into a single
uber jar. This makes deploying to non-mavenized targets much easier.
Of course, you would be wise to inherit your dependencies individually;
the uber jar is intended for projects like collide,
which have complex configuration, and adding many jars would be a pain.
The newest version!
package xapi.time.impl;
import static xapi.time.X_Time.threadStart;
import xapi.time.api.Moment;
import xapi.util.api.ReceivesValue;
public class RunOnce {
private static final Runnable NO_OP = new Runnable() {
@Override
public void run() {}
};
@SuppressWarnings("rawtypes")
private static final ReceivesValue NO_OP_RECEIVER = new ReceivesValue.NoOp();
public static Runnable runOnce(final Runnable job) {
return runOnce(job, false);
}
public static Runnable runOnce(final Runnable job, final boolean oncePerMoment) {
if (oncePerMoment) {
return new Runnable() {
RunOnce lock = new RunOnce();
@Override
public void run() {
if (lock.shouldRun(oncePerMoment)) {
job.run();
}
}
};
} else {
return new Runnable() {
Runnable once = job;
@Override
public void run() {
once.run();
once = NO_OP;
}
};
}
}
public static ReceivesValue setOnce(final ReceivesValue job) {
return setOnce(job, false);
}
public static ReceivesValue setOnce(final ReceivesValue job, final boolean oncePerMoment) {
if (oncePerMoment) {
return new ReceivesValue() {
RunOnce lock = new RunOnce();
@Override
public void set(X from) {
if (lock.shouldRun(oncePerMoment)) {
job.set(from);
}
}
};
} else {
return new ReceivesValue() {
ReceivesValue once = job;
@Override
@SuppressWarnings("unchecked")
public void set(X from) {
once.set(from);
once = NO_OP_RECEIVER;
}
};
}
}
private Moment once;
public boolean shouldRun(boolean oncePerMoment) {
if (once == null) {
synchronized (this) {
if (once != null) {
return false;
}
once = threadStart();
return true;
}
} else {
if (oncePerMoment) {
//do not run more than once per tick of X_Time.
//this allows you to call this method as many times as you want,
//but only perform the heavyweight operation of synchronization once.
Moment now = threadStart();
synchronized (this) {
if (once.equals(now)){
return false;
}
once = now;
}
return true;
} else {
return false;
}
}
}
}