From 585a288f686347c9d7d7f0d6a8a4cbf141e534d1 Mon Sep 17 00:00:00 2001 From: s809 <43530948+s809@users.noreply.github.com> Date: Tue, 3 Dec 2024 21:10:58 +0500 Subject: [PATCH] Fix gen tasks sometimes not submitting after LOD level changes --- .../FullDataSourceProviderV2.java | 4 +--- .../GeneratedFullDataSourceProvider.java | 22 ++++++++++------- .../RemoteFullDataSourceProvider.java | 23 +++++++++++++++--- .../AbstractFullDataNetworkRequestQueue.java | 24 +++++++++++-------- .../server/FullDataSourceRequestHandler.java | 2 +- .../core/render/LodRenderSection.java | 8 +------ 6 files changed, 51 insertions(+), 32 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataSourceProviderV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataSourceProviderV2.java index 901301b00..024eb7345 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataSourceProviderV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataSourceProviderV2.java @@ -21,7 +21,6 @@ package com.seibel.distanthorizons.core.file.fullDatafile; import com.seibel.distanthorizons.api.enums.config.EDhApiDataCompressionMode; import com.seibel.distanthorizons.core.api.internal.ClientApi; -import com.seibel.distanthorizons.core.api.internal.SharedApi; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV1; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; @@ -41,7 +40,6 @@ import com.seibel.distanthorizons.core.sql.repo.FullDataSourceV2Repo; import com.seibel.distanthorizons.core.util.ThreadUtil; import com.seibel.distanthorizons.core.util.objects.DataCorruptedException; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; -import com.seibel.distanthorizons.core.world.EWorldEnvironment; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import it.unimi.dsi.fastutil.longs.LongArrayList; import org.apache.logging.log4j.Logger; @@ -606,7 +604,7 @@ public class FullDataSourceProviderV2 /** @return true if the position was queued, false if not */ @Nullable - public CompletableFuture queuePositionForRetrieval(Long genPos) { return null; } + public CompletableFuture queuePositionForRetrieval(long genPos, boolean allowAboveMaxGenRequests) { return null; } /** does nothing if the given position isn't present in the queue */ public void removeRetrievalRequestIf(DhSectionPos.ICancelablePrimitiveLongConsumer removeIf) { } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/GeneratedFullDataSourceProvider.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/GeneratedFullDataSourceProvider.java index b16f55cb4..1d106e572 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/GeneratedFullDataSourceProvider.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/GeneratedFullDataSourceProvider.java @@ -63,10 +63,10 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im * TODO this should be dynamically allocated based on CPU load * and abilities. */ - public static final int MAX_WORLD_GEN_REQUESTS_PER_THREAD = 20; + public static final int MAX_WORLD_GEN_REQUESTS_PER_THREAD = 20; - private final AtomicReference worldGenQueueRef = new AtomicReference<>(null); + protected final AtomicReference worldGenQueueRef = new AtomicReference<>(null); private final ArrayList onWorldGenTaskCompleteListeners = new ArrayList<>(); protected final DelayedFullDataSourceSaveCache delayedFullDataSourceSaveCache = new DelayedFullDataSourceSaveCache(this::onDataSourceSave, 5_000); @@ -173,8 +173,7 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im } - IFullDataSourceRetrievalQueue worldGenQueue = this.worldGenQueueRef.get(); - if (worldGenQueue == null) + if (this.worldGenQueueRef.get() == null) { // we can't queue anything if the world generator isn't set up yet return false; @@ -211,13 +210,11 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im return false; } - - // don't queue additional world gen requests beyond the max allotted count - return worldGenQueue.getWaitingTaskCount() < maxQueueCount; + return true; } @Override - public CompletableFuture queuePositionForRetrieval(Long genPos) + public CompletableFuture queuePositionForRetrieval(long genPos, boolean allowAboveMaxGenRequests) { IFullDataSourceRetrievalQueue worldGenQueue = this.worldGenQueueRef.get(); if (worldGenQueue == null) @@ -225,6 +222,15 @@ public class GeneratedFullDataSourceProvider extends FullDataSourceProviderV2 im return null; } + if (!allowAboveMaxGenRequests) + { + int maxQueueCount = MAX_WORLD_GEN_REQUESTS_PER_THREAD * Config.Common.MultiThreading.numberOfWorldGenerationThreads.get(); + if (worldGenQueue.getWaitingTaskCount() >= maxQueueCount) + { + return null; + } + } + WorldGenTaskTracker genTaskTracker = new WorldGenTaskTracker(genPos); CompletableFuture worldGenFuture = worldGenQueue.submitRetrievalTask(genPos, (byte) (DhSectionPos.getDetailLevel(genPos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL), genTaskTracker); worldGenFuture.whenComplete((genTaskResult, ex) -> diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/RemoteFullDataSourceProvider.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/RemoteFullDataSourceProvider.java index 41c9fda74..c251fdcfd 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/RemoteFullDataSourceProvider.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/RemoteFullDataSourceProvider.java @@ -20,18 +20,20 @@ package com.seibel.distanthorizons.core.file.fullDatafile; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; +import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.file.structure.ISaveStructure; import com.seibel.distanthorizons.core.generation.RemoteWorldRetrievalQueue; +import com.seibel.distanthorizons.core.generation.tasks.WorldGenResult; import com.seibel.distanthorizons.core.level.IDhLevel; import com.seibel.distanthorizons.core.level.WorldGenModule; import com.seibel.distanthorizons.core.multiplayer.client.SyncOnLoadRequestQueue; -import com.seibel.distanthorizons.core.pos.DhSectionPos; -import com.seibel.distanthorizons.coreapi.util.BitShiftUtil; +import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos2D; +import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import org.jetbrains.annotations.Nullable; import java.io.File; -import java.util.Map; import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; /** @@ -40,6 +42,8 @@ import java.util.concurrent.ConcurrentHashMap; */ public class RemoteFullDataSourceProvider extends GeneratedFullDataSourceProvider { + private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); + @Nullable private final SyncOnLoadRequestQueue syncOnLoadRequestQueue; private final Set visitedPositions = ConcurrentHashMap.newKeySet(); @@ -123,6 +127,19 @@ public class RemoteFullDataSourceProvider extends GeneratedFullDataSourceProvide } + @Override + public CompletableFuture queuePositionForRetrieval(long genPos, boolean allowAboveMaxGenRequests) + { + RemoteWorldRetrievalQueue worldGenQueue = (RemoteWorldRetrievalQueue) this.worldGenQueueRef.get(); + if (worldGenQueue == null) + { + return null; + } + + return super.queuePositionForRetrieval(genPos, worldGenQueue.isPosCloserThanFarthestWaiting(new DhBlockPos2D(MC_CLIENT.getPlayerBlockPos()), genPos)); + } + + //==========// // shutdown // diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java index b2ae7d5f7..e3df80701 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/client/AbstractFullDataNetworkRequestQueue.java @@ -183,7 +183,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende Map.Entry mapEntry = this.waitingTasksBySectionPos .entrySet().stream() .filter(task -> task.getValue().networkDataSourceFuture == null) - .min(Comparator.comparingInt(x -> posDistanceSquared(targetPos, x.getKey()))) + .min(Comparator.comparingInt(x -> DhSectionPos.getChebyshevSignedBlockDistance(x.getKey(), targetPos))) .orElse(null); if (mapEntry == null) @@ -305,6 +305,19 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende } + public boolean isPosCloserThanFarthestWaiting(DhBlockPos2D targetPos, long pos) + { + Long farthestPos = this.waitingTasksBySectionPos + .keySet().stream() + .max(Comparator.comparingInt(x -> DhSectionPos.getChebyshevSignedBlockDistance(x, targetPos))) + .orElse(null); + if (farthestPos == null) + { + return true; + } + + return DhSectionPos.getChebyshevSignedBlockDistance(pos, targetPos) <= DhSectionPos.getChebyshevSignedBlockDistance(farthestPos, targetPos); + } //=========================================// @@ -404,15 +417,6 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende - //================// - // helper methods // - //================// - - protected static int posDistanceSquared(DhBlockPos2D targetPos, long pos) - { return (int) DhSectionPos.getCenterBlockPos(pos).distSquared(targetPos); } - - - //================// // helper classes // //================// diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/FullDataSourceRequestHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/FullDataSourceRequestHandler.java index 52cf38fd3..f52d623fb 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/FullDataSourceRequestHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/FullDataSourceRequestHandler.java @@ -246,7 +246,7 @@ public class FullDataSourceRequestHandler else { LOGGER.info("sending - queueing [" + DhSectionPos.toString(pos) + "]"); - this.fullDataSourceProvider().queuePositionForRetrieval(pos); + this.fullDataSourceProvider().queuePositionForRetrieval(pos, true); } }); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java b/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java index f58eb02c1..01987440d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java @@ -475,14 +475,8 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable // queue from last to first to prevent shifting the array unnecessarily for (int i = this.missingGenerationPos.size() - 1; i >= 0; i--) { - if (!this.fullDataSourceProvider.canQueueRetrieval()) - { - // the data source provider isn't accepting any more jobs - break; - } - long pos = this.missingGenerationPos.removeLong(i); - boolean positionQueued = (this.fullDataSourceProvider.queuePositionForRetrieval(pos) != null); + boolean positionQueued = (this.fullDataSourceProvider.queuePositionForRetrieval(pos, false) != null); if (!positionQueued) { // shouldn't normally happen, but just in case