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 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 allPreparations = new CompletableFuture(); protected CompletableFuture> allDone; final Set 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 of( ResourceManager resourceManager, List listeners, Executor backgroundExecutor, Executor gameExecutor, CompletableFuture 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 listeners, SimpleReloadInstance.StateFactory stateFactory, CompletableFuture alsoWaitedFor ) { this.listenerCount = listeners.size(); this.startedTaskCounter.incrementAndGet(); alsoWaitedFor.thenRun(this.doneTaskCounter::incrementAndGet); List> list = Lists.>newArrayList(); CompletableFuture completableFuture = alsoWaitedFor; this.preparingListeners = Sets.newHashSet(listeners); for (final PreparableReloadListener preparableReloadListener : listeners) { final CompletableFuture completableFuture2 = completableFuture; CompletableFuture completableFuture3 = stateFactory.create(new PreparableReloadListener.PreparationBarrier() { @Override public CompletableFuture 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 listeners, Executor backgroundExecutor, Executor gameExecutor, CompletableFuture alsoWaitedFor, boolean profiled ) { return (ReloadInstance)(profiled ? new ProfiledReloadInstance(resourceManager, listeners, backgroundExecutor, gameExecutor, alsoWaitedFor) : of(resourceManager, listeners, backgroundExecutor, gameExecutor, alsoWaitedFor)); } protected interface StateFactory { CompletableFuture create( PreparableReloadListener.PreparationBarrier preparationBarrier, ResourceManager resourceManager, PreparableReloadListener preparableReloadListener, Executor executor, Executor executor2 ); } }