128 lines
4.5 KiB
Java
128 lines
4.5 KiB
Java
package net.minecraft.server.packs.resources;
|
|
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Sets;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.concurrent.CompletableFuture;
|
|
import java.util.concurrent.Executor;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import net.minecraft.Util;
|
|
import net.minecraft.util.Unit;
|
|
|
|
public class SimpleReloadInstance<S> implements ReloadInstance {
|
|
private static final int PREPARATION_PROGRESS_WEIGHT = 2;
|
|
private static final int EXTRA_RELOAD_PROGRESS_WEIGHT = 2;
|
|
private static final int LISTENER_PROGRESS_WEIGHT = 1;
|
|
protected final CompletableFuture<Unit> allPreparations = new CompletableFuture();
|
|
protected CompletableFuture<List<S>> allDone;
|
|
final Set<PreparableReloadListener> preparingListeners;
|
|
private final int listenerCount;
|
|
private int startedReloads;
|
|
private int finishedReloads;
|
|
private final AtomicInteger startedTaskCounter = new AtomicInteger();
|
|
private final AtomicInteger doneTaskCounter = new AtomicInteger();
|
|
|
|
public static SimpleReloadInstance<Void> of(
|
|
ResourceManager resourceManager,
|
|
List<PreparableReloadListener> listeners,
|
|
Executor backgroundExecutor,
|
|
Executor gameExecutor,
|
|
CompletableFuture<Unit> alsoWaitedFor
|
|
) {
|
|
return new SimpleReloadInstance<>(
|
|
backgroundExecutor,
|
|
gameExecutor,
|
|
resourceManager,
|
|
listeners,
|
|
(preparationBarrier, resourceManagerx, preparableReloadListener, executor2, executor3) -> preparableReloadListener.reload(
|
|
preparationBarrier, resourceManagerx, backgroundExecutor, executor3
|
|
),
|
|
alsoWaitedFor
|
|
);
|
|
}
|
|
|
|
protected SimpleReloadInstance(
|
|
Executor backgroundExecutor,
|
|
Executor gameExecutor,
|
|
ResourceManager resourceManager,
|
|
List<PreparableReloadListener> listeners,
|
|
SimpleReloadInstance.StateFactory<S> stateFactory,
|
|
CompletableFuture<Unit> alsoWaitedFor
|
|
) {
|
|
this.listenerCount = listeners.size();
|
|
this.startedTaskCounter.incrementAndGet();
|
|
alsoWaitedFor.thenRun(this.doneTaskCounter::incrementAndGet);
|
|
List<CompletableFuture<S>> list = Lists.<CompletableFuture<S>>newArrayList();
|
|
CompletableFuture<?> completableFuture = alsoWaitedFor;
|
|
this.preparingListeners = Sets.<PreparableReloadListener>newHashSet(listeners);
|
|
|
|
for (final PreparableReloadListener preparableReloadListener : listeners) {
|
|
final CompletableFuture<?> completableFuture2 = completableFuture;
|
|
CompletableFuture<S> completableFuture3 = stateFactory.create(new PreparableReloadListener.PreparationBarrier() {
|
|
@Override
|
|
public <T> CompletableFuture<T> wait(T backgroundResult) {
|
|
gameExecutor.execute(() -> {
|
|
SimpleReloadInstance.this.preparingListeners.remove(preparableReloadListener);
|
|
if (SimpleReloadInstance.this.preparingListeners.isEmpty()) {
|
|
SimpleReloadInstance.this.allPreparations.complete(Unit.INSTANCE);
|
|
}
|
|
});
|
|
return SimpleReloadInstance.this.allPreparations.thenCombine(completableFuture2, (unit, object2) -> backgroundResult);
|
|
}
|
|
}, resourceManager, preparableReloadListener, runnable -> {
|
|
this.startedTaskCounter.incrementAndGet();
|
|
backgroundExecutor.execute(() -> {
|
|
runnable.run();
|
|
this.doneTaskCounter.incrementAndGet();
|
|
});
|
|
}, runnable -> {
|
|
this.startedReloads++;
|
|
gameExecutor.execute(() -> {
|
|
runnable.run();
|
|
this.finishedReloads++;
|
|
});
|
|
});
|
|
list.add(completableFuture3);
|
|
completableFuture = completableFuture3;
|
|
}
|
|
|
|
this.allDone = Util.sequenceFailFast(list);
|
|
}
|
|
|
|
@Override
|
|
public CompletableFuture<?> done() {
|
|
return this.allDone;
|
|
}
|
|
|
|
@Override
|
|
public float getActualProgress() {
|
|
int i = this.listenerCount - this.preparingListeners.size();
|
|
float f = this.doneTaskCounter.get() * 2 + this.finishedReloads * 2 + i * 1;
|
|
float g = this.startedTaskCounter.get() * 2 + this.startedReloads * 2 + this.listenerCount * 1;
|
|
return f / g;
|
|
}
|
|
|
|
public static ReloadInstance create(
|
|
ResourceManager resourceManager,
|
|
List<PreparableReloadListener> listeners,
|
|
Executor backgroundExecutor,
|
|
Executor gameExecutor,
|
|
CompletableFuture<Unit> alsoWaitedFor,
|
|
boolean profiled
|
|
) {
|
|
return (ReloadInstance)(profiled
|
|
? new ProfiledReloadInstance(resourceManager, listeners, backgroundExecutor, gameExecutor, alsoWaitedFor)
|
|
: of(resourceManager, listeners, backgroundExecutor, gameExecutor, alsoWaitedFor));
|
|
}
|
|
|
|
protected interface StateFactory<S> {
|
|
CompletableFuture<S> create(
|
|
PreparableReloadListener.PreparationBarrier preparationBarrier,
|
|
ResourceManager resourceManager,
|
|
PreparableReloadListener preparableReloadListener,
|
|
Executor executor,
|
|
Executor executor2
|
|
);
|
|
}
|
|
}
|