DataFetcher.java
com.mojang.realmsclient.gui.task.DataFetcher
信息
- 全限定名:com.mojang.realmsclient.gui.task.DataFetcher
- 类型:public class
- 包:com.mojang.realmsclient.gui.task
- 源码路径:src/main/java/com/mojang/realmsclient/gui/task/DataFetcher.java
- 起始行号:L21
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L22 - 说明:
TODO
- 类型:
-
executor- 类型:
Executor - 修饰符:
private final - 源码定位:
L23 - 说明:
TODO
- 类型:
-
resolution- 类型:
TimeUnit - 修饰符:
private final - 源码定位:
L24 - 说明:
TODO
- 类型:
-
timeSource- 类型:
TimeSource - 修饰符:
private final - 源码定位:
L25 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
com.mojang.realmsclient.gui.task.DataFetcher.ComputationResult- 类型:
record - 修饰符:
private - 源码定位:
L47 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.gui.task.DataFetcher.SubscribedTask- 类型:
class - 修饰符:
private - 源码定位:
L51 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.gui.task.DataFetcher.Subscription- 类型:
class - 修饰符:
public - 源码定位:
L92 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.gui.task.DataFetcher.SuccessfulComputationResult- 类型:
record - 修饰符:
private - 源码定位:
L127 - 说明:
TODO
- 类型:
-
com.mojang.realmsclient.gui.task.DataFetcher.Task- 类型:
class - 修饰符:
public - 源码定位:
L131 - 说明:
TODO
- 类型:
构造器
public DataFetcher(Executor executor, TimeUnit resolution, TimeSource timeSource) @ L27
- 构造器名:DataFetcher
- 源码定位:L27
- 修饰符:public
参数:
- executor: Executor
- resolution: TimeUnit
- timeSource: TimeSource
说明:
TODO
方法
下面的方法块按源码顺序生成。
public <T> DataFetcher.Task<T> createTask(String id, Callable<T> updater, Duration period, RepeatedDelayStrategy repeatStrategy) @ L33
- 方法名:createTask
- 源码定位:L33
- 返回类型:
DataFetcher.Task - 修饰符:public
参数:
- id: String
- updater: Callable
- period: Duration
- repeatStrategy: RepeatedDelayStrategy
说明:
TODO
public DataFetcher.Subscription createSubscription() @ L42
- 方法名:createSubscription
- 源码定位:L42
- 返回类型:DataFetcher.Subscription
- 修饰符:public
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class DataFetcher {
private static final Logger LOGGER = LogUtils.getLogger();
private final Executor executor;
private final TimeUnit resolution;
private final TimeSource timeSource;
public DataFetcher(Executor executor, TimeUnit resolution, TimeSource timeSource) {
this.executor = executor;
this.resolution = resolution;
this.timeSource = timeSource;
}
public <T> DataFetcher.Task<T> createTask(String id, Callable<T> updater, Duration period, RepeatedDelayStrategy repeatStrategy) {
long periodInUnit = this.resolution.convert(period);
if (periodInUnit == 0L) {
throw new IllegalArgumentException("Period of " + period + " too short for selected resolution of " + this.resolution);
} else {
return new DataFetcher.Task<>(id, updater, periodInUnit, repeatStrategy);
}
}
public DataFetcher.Subscription createSubscription() {
return new DataFetcher.Subscription();
}
@OnlyIn(Dist.CLIENT)
private record ComputationResult<T>(Either<T, Exception> value, long time) {
}
@OnlyIn(Dist.CLIENT)
private class SubscribedTask<T> {
private final DataFetcher.Task<T> task;
private final Consumer<T> output;
private long lastCheckTime;
private SubscribedTask(DataFetcher.Task<T> task, Consumer<T> output) {
Objects.requireNonNull(DataFetcher.this);
super();
this.lastCheckTime = -1L;
this.task = task;
this.output = output;
}
private void update(long currentTime) {
this.task.updateIfNeeded(currentTime);
this.runCallbackIfNeeded();
}
private void runCallbackIfNeeded() {
DataFetcher.SuccessfulComputationResult<T> lastResult = this.task.lastResult;
if (lastResult != null && this.lastCheckTime < lastResult.time) {
this.output.accept(lastResult.value);
this.lastCheckTime = lastResult.time;
}
}
private void runCallback() {
DataFetcher.SuccessfulComputationResult<T> lastResult = this.task.lastResult;
if (lastResult != null) {
this.output.accept(lastResult.value);
this.lastCheckTime = lastResult.time;
}
}
private void reset() {
this.task.reset();
this.lastCheckTime = -1L;
}
}
@OnlyIn(Dist.CLIENT)
public class Subscription {
private final List<DataFetcher.SubscribedTask<?>> subscriptions;
public Subscription() {
Objects.requireNonNull(DataFetcher.this);
super();
this.subscriptions = new ArrayList<>();
}
public <T> void subscribe(DataFetcher.Task<T> task, Consumer<T> output) {
DataFetcher.SubscribedTask<T> subscription = DataFetcher.this.new SubscribedTask<>(task, output);
this.subscriptions.add(subscription);
subscription.runCallbackIfNeeded();
}
public void forceUpdate() {
for (DataFetcher.SubscribedTask<?> subscription : this.subscriptions) {
subscription.runCallback();
}
}
public void tick() {
for (DataFetcher.SubscribedTask<?> subscription : this.subscriptions) {
subscription.update(DataFetcher.this.timeSource.get(DataFetcher.this.resolution));
}
}
public void reset() {
for (DataFetcher.SubscribedTask<?> subscription : this.subscriptions) {
subscription.reset();
}
}
}
@OnlyIn(Dist.CLIENT)
private record SuccessfulComputationResult<T>(T value, long time) {
}
@OnlyIn(Dist.CLIENT)
public class Task<T> {
private final String id;
private final Callable<T> updater;
private final long period;
private final RepeatedDelayStrategy repeatStrategy;
private @Nullable CompletableFuture<DataFetcher.ComputationResult<T>> pendingTask;
private DataFetcher.@Nullable SuccessfulComputationResult<T> lastResult;
private long nextUpdate;
private Task(String id, Callable<T> updater, long period, RepeatedDelayStrategy repeatStrategy) {
Objects.requireNonNull(DataFetcher.this);
super();
this.nextUpdate = -1L;
this.id = id;
this.updater = updater;
this.period = period;
this.repeatStrategy = repeatStrategy;
}
private void updateIfNeeded(long currentTime) {
if (this.pendingTask != null) {
DataFetcher.ComputationResult<T> result = this.pendingTask.getNow(null);
if (result == null) {
return;
}
this.pendingTask = null;
long completionTime = result.time;
result.value().ifLeft(value -> {
this.lastResult = new DataFetcher.SuccessfulComputationResult<>((T)value, completionTime);
this.nextUpdate = completionTime + this.period * this.repeatStrategy.delayCyclesAfterSuccess();
}).ifRight(e -> {
long cycles = this.repeatStrategy.delayCyclesAfterFailure();
DataFetcher.LOGGER.warn("Failed to process task {}, will repeat after {} cycles", this.id, cycles, e);
this.nextUpdate = completionTime + this.period * cycles;
});
}
if (this.nextUpdate <= currentTime) {
this.pendingTask = CompletableFuture.supplyAsync(() -> {
try {
T resultx = this.updater.call();
long completionTimex = DataFetcher.this.timeSource.get(DataFetcher.this.resolution);
return new DataFetcher.ComputationResult<>(Either.left(resultx), completionTimex);
} catch (Exception var4x) {
long completionTimex = DataFetcher.this.timeSource.get(DataFetcher.this.resolution);
return new DataFetcher.ComputationResult<>(Either.right(var4x), completionTimex);
}
}, DataFetcher.this.executor);
}
}
public void reset() {
this.pendingTask = null;
this.lastResult = null;
this.nextUpdate = -1L;
}
}
}引用的其他类
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置: