package org.rx.bot.util;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.NotNull;
import org.rx.core.Disposable;
import org.rx.core.Tasks;
import org.rx.util.function.BiAction;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.rx.core.App.quietly;
import static org.rx.core.App.require;
public class RedoHandler<T> extends Disposable {
public static class RedoData<T> implements Delayed {
@Getter
@Setter
private T data;
private long delayMillis, elapsedTime;
@Getter
@Setter
private volatile boolean done;
private final AtomicInteger redoCount = new AtomicInteger();
public RedoData(T data, long delayMillis) {
this.data = data;
this.delayMillis = delayMillis;
renew();
}
private RedoData<T> renew() {
elapsedTime = System.currentTimeMillis() + delayMillis;
return this;
}
@Override
public long getDelay(@NotNull TimeUnit unit) {
return unit.convert(elapsedTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(@NotNull Delayed o) {
// return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
// // 过期时间长的放置在队列尾部
// if (this.getDelay(TimeUnit.MICROSECONDS) > o.getDelay(TimeUnit.MICROSECONDS)) {
// return 1;
// }
// // 过期时间短的放置在队列头
// if (this.getDelay(TimeUnit.MICROSECONDS) < o.getDelay(TimeUnit.MICROSECONDS)) {
// return -1;
// }
// return 0;
return Long.compare(this.getDelay(TimeUnit.MICROSECONDS), o.getDelay(TimeUnit.MICROSECONDS));
}
}
@Setter
private int maxRedoCount = 1;
private final DelayQueue<RedoData<T>> queue = new DelayQueue<>();
public RedoHandler(BiAction<RedoData<T>> redoCallback) {
require(redoCallback);
Tasks.run(() -> {
while (!isClosed()) {
RedoData<T> redoData = queue.take();
if (redoData.done || redoData.redoCount.get() >= maxRedoCount) {
continue;
}
redoData.redoCount.incrementAndGet();
quietly(() -> redoCallback.invoke(redoData));
queue.offer(redoData.renew());
}
});
}
@Override
protected void freeObjects() {
}
public RedoData<T> monitor(T data, long redoMillis) {
RedoData<T> redoData = new RedoData<>(data, redoMillis);
queue.offer(redoData);
return redoData;
}
}
java RedoHandler
最新推荐文章于 2021-02-27 08:33:14 发布