/* * Decompiled with CFR 0.152. * * Could not load the following classes: * org.jspecify.annotations.Nullable */ package net.minecraft.server.packs.resources; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; import net.minecraft.server.packs.resources.PreparableReloadListener; import net.minecraft.server.packs.resources.ProfiledReloadInstance; import net.minecraft.server.packs.resources.ReloadInstance; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.util.Unit; import net.minecraft.util.Util; import org.jspecify.annotations.Nullable; 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; private final CompletableFuture allPreparations = new CompletableFuture(); private @Nullable CompletableFuture> allDone; private final Set preparingListeners; private final int listenerCount; private final AtomicInteger startedTasks = new AtomicInteger(); private final AtomicInteger finishedTasks = new AtomicInteger(); private final AtomicInteger startedReloads = new AtomicInteger(); private final AtomicInteger finishedReloads = new AtomicInteger(); public static ReloadInstance of(ResourceManager resourceManager, List listeners, Executor taskExecutor, Executor mainThreadExecutor, CompletableFuture initialTask) { SimpleReloadInstance result = new SimpleReloadInstance(listeners); result.startTasks(taskExecutor, mainThreadExecutor, resourceManager, listeners, StateFactory.SIMPLE, initialTask); return result; } protected SimpleReloadInstance(List listeners) { this.listenerCount = listeners.size(); this.preparingListeners = new HashSet(listeners); } protected void startTasks(Executor taskExecutor, Executor mainThreadExecutor, ResourceManager resourceManager, List listeners, StateFactory stateFactory, CompletableFuture initialTask) { this.allDone = this.prepareTasks(taskExecutor, mainThreadExecutor, resourceManager, listeners, stateFactory, initialTask); } protected CompletableFuture> prepareTasks(Executor taskExecutor, Executor mainThreadExecutor, ResourceManager resourceManager, List listeners, StateFactory stateFactory, CompletableFuture initialTask) { Executor countingTaskExecutor = r -> { this.startedTasks.incrementAndGet(); taskExecutor.execute(() -> { r.run(); this.finishedTasks.incrementAndGet(); }); }; Executor countingReloadExecutor = r -> { this.startedReloads.incrementAndGet(); mainThreadExecutor.execute(() -> { r.run(); this.finishedReloads.incrementAndGet(); }); }; this.startedTasks.incrementAndGet(); initialTask.thenRun(this.finishedTasks::incrementAndGet); PreparableReloadListener.SharedState sharedState = new PreparableReloadListener.SharedState(resourceManager); listeners.forEach(listener -> listener.prepareSharedState(sharedState)); CompletableFuture barrier = initialTask; ArrayList> allSteps = new ArrayList>(); for (PreparableReloadListener listener2 : listeners) { PreparableReloadListener.PreparationBarrier barrierForCurrentTask = this.createBarrierForListener(listener2, barrier, mainThreadExecutor); CompletableFuture state = stateFactory.create(sharedState, barrierForCurrentTask, listener2, countingTaskExecutor, countingReloadExecutor); allSteps.add(state); barrier = state; } return Util.sequenceFailFast(allSteps); } private PreparableReloadListener.PreparationBarrier createBarrierForListener(final PreparableReloadListener listener, final CompletableFuture previousBarrier, final Executor mainThreadExecutor) { return new PreparableReloadListener.PreparationBarrier(){ @Override public CompletableFuture wait(T t) { mainThreadExecutor.execute(() -> { SimpleReloadInstance.this.preparingListeners.remove(listener); if (SimpleReloadInstance.this.preparingListeners.isEmpty()) { SimpleReloadInstance.this.allPreparations.complete(Unit.INSTANCE); } }); return SimpleReloadInstance.this.allPreparations.thenCombine((CompletionStage)previousBarrier, (v1, v2) -> t); } }; } @Override public CompletableFuture done() { return Objects.requireNonNull(this.allDone, "not started"); } @Override public float getActualProgress() { int preparationsDone = this.listenerCount - this.preparingListeners.size(); float doneCount = SimpleReloadInstance.weightProgress(this.finishedTasks.get(), this.finishedReloads.get(), preparationsDone); float totalCount = SimpleReloadInstance.weightProgress(this.startedTasks.get(), this.startedReloads.get(), this.listenerCount); return doneCount / totalCount; } private static int weightProgress(int preparationTasks, int reloadTasks, int listeners) { return preparationTasks * 2 + reloadTasks * 2 + listeners * 1; } public static ReloadInstance create(ResourceManager resourceManager, List listeners, Executor backgroundExecutor, Executor mainThreadExecutor, CompletableFuture initialTask, boolean enableProfiling) { if (enableProfiling) { return ProfiledReloadInstance.of(resourceManager, listeners, backgroundExecutor, mainThreadExecutor, initialTask); } return SimpleReloadInstance.of(resourceManager, listeners, backgroundExecutor, mainThreadExecutor, initialTask); } @FunctionalInterface protected static interface StateFactory { public static final StateFactory SIMPLE = (currentReload, previousStep, listener, taskExecutor, reloadExecutor) -> listener.reload(currentReload, taskExecutor, previousStep, reloadExecutor); public CompletableFuture create(PreparableReloadListener.SharedState var1, PreparableReloadListener.PreparationBarrier var2, PreparableReloadListener var3, Executor var4, Executor var5); } }