Fix gen tasks sometimes not submitting after LOD level changes
This commit is contained in:
+1
-3
@@ -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<WorldGenResult> queuePositionForRetrieval(Long genPos) { return null; }
|
||||
public CompletableFuture<WorldGenResult> 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) { }
|
||||
|
||||
+14
-8
@@ -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<IFullDataSourceRetrievalQueue> worldGenQueueRef = new AtomicReference<>(null);
|
||||
protected final AtomicReference<IFullDataSourceRetrievalQueue> worldGenQueueRef = new AtomicReference<>(null);
|
||||
private final ArrayList<IOnWorldGenCompleteListener> 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<WorldGenResult> queuePositionForRetrieval(Long genPos)
|
||||
public CompletableFuture<WorldGenResult> 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<WorldGenResult> worldGenFuture = worldGenQueue.submitRetrievalTask(genPos, (byte) (DhSectionPos.getDetailLevel(genPos) - DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL), genTaskTracker);
|
||||
worldGenFuture.whenComplete((genTaskResult, ex) ->
|
||||
|
||||
+20
-3
@@ -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<Long> visitedPositions = ConcurrentHashMap.newKeySet();
|
||||
@@ -123,6 +127,19 @@ public class RemoteFullDataSourceProvider extends GeneratedFullDataSourceProvide
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public CompletableFuture<WorldGenResult> 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 //
|
||||
|
||||
+14
-10
@@ -183,7 +183,7 @@ public abstract class AbstractFullDataNetworkRequestQueue implements IDebugRende
|
||||
Map.Entry<Long, RequestQueueEntry> 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 //
|
||||
//================//
|
||||
|
||||
+1
-1
@@ -246,7 +246,7 @@ public class FullDataSourceRequestHandler
|
||||
else
|
||||
{
|
||||
LOGGER.info("sending - queueing [" + DhSectionPos.toString(pos) + "]");
|
||||
this.fullDataSourceProvider().queuePositionForRetrieval(pos);
|
||||
this.fullDataSourceProvider().queuePositionForRetrieval(pos, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user