From 03d5cb928958a7ba5b35f1114b4a03a8be0c3ec3 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 1 Dec 2024 17:06:53 -0600 Subject: [PATCH] Fix compiling for Java 8 --- .../BatchGenerationEnvironment.java | 109 +++++++++++------- .../worldGeneration/GenerationEvent.java | 62 ++++++---- 2 files changed, 108 insertions(+), 63 deletions(-) diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java index c952f4921..ecfa5df8e 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/BatchGenerationEnvironment.java @@ -566,44 +566,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv /** @param extraRadius in both the positive and negative directions */ private static Stream getChunkPosToGenerateStream(int genMinX, int genMinZ, int width, int extraRadius) { - final int widthPlusExtra = width + (extraRadius * 2); - - final int minX = genMinX - extraRadius; - final int minZ = genMinZ - extraRadius; - - final int maxX = genMinX + (width - 1) + extraRadius; - final int maxZ = genMinZ + (width - 1) + extraRadius; - - return StreamSupport.stream( - new Spliterators.AbstractSpliterator<>((long) widthPlusExtra * widthPlusExtra, Spliterator.SIZED) - { - // X starts at 1 minus the minX so we can immediately re-add 1 in the tryAdvance() loop - private int x = minX - 1; - private int z = minZ; - - public boolean tryAdvance(Consumer consumer) - { - if (this.x == maxX && this.z == maxZ) - { - // the last returned position was the final valid position - return false; - } - - if (this.x == maxX) - { - // we reached the max X position, loop back around in the next Z row - this.x = minX; - this.z++; - } - else - { - this.x++; - } - - consumer.accept(new ChunkPos(this.x, this.z)); - return true; - } - }, false); + return StreamSupport.stream(new InclusiveChunkPosStream(genMinX, genMinZ, width, extraRadius), false); // method this is replacing //return ChunkPos.rangeClosed( @@ -974,6 +937,74 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv ChunkAccess getChunk(int chunkPosX, int chunkPosZ); } - + private static class InclusiveChunkPosStream extends Spliterators.AbstractSpliterator + { + private final int minX; + private final int minZ; + + private final int maxX; + private final int maxZ; + + + /** current X pos */ + int x; + /** current Z pos */ + private int z; + + + + //=============// + // constructor // + //=============// + + protected InclusiveChunkPosStream(int genMinX, int genMinZ, int width, int extraRadius) + { + super(getCount(width, extraRadius), Spliterator.SIZED); + + this.minX = genMinX - extraRadius; + this.minZ = genMinZ - extraRadius; + + this.maxX = genMinX + (width - 1) + extraRadius; + this.maxZ = genMinZ + (width - 1) + extraRadius; + + // X starts at 1 minus the minX so we can immediately re-add 1 in the tryAdvance() loop + this.x = this.minX - 1; + this.z = this.minZ; + } + private static int getCount(int width, int extraRadius) + { + int widthPlusExtra = width + (extraRadius * 2); + return widthPlusExtra * widthPlusExtra; + } + + + + //=================// + // iterator method // + //=================// + + public boolean tryAdvance(Consumer consumer) + { + if (this.x == this.maxX && this.z == this.maxZ) + { + // the last returned position was the final valid position + return false; + } + + if (this.x == this.maxX) + { + // we reached the max X position, loop back around in the next Z row + this.x = this.minX; + this.z++; + } + else + { + this.x++; + } + + consumer.accept(new ChunkPos(this.x, this.z)); + return true; + } + } } \ No newline at end of file diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/GenerationEvent.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/GenerationEvent.java index 22b005a9a..33900530c 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/GenerationEvent.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/worldGeneration/GenerationEvent.java @@ -22,10 +22,8 @@ package com.seibel.distanthorizons.common.wrappers.worldGeneration; import java.lang.invoke.MethodHandles; import java.util.concurrent.*; import java.util.function.Consumer; -import java.util.function.Function; import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGenerationStep; -import com.seibel.distanthorizons.core.dataObjects.render.bufferBuilding.LodQuadBuilder; import com.seibel.distanthorizons.core.util.objects.UncheckedInterruptedException; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhChunkPos; @@ -83,9 +81,10 @@ public final class GenerationEvent generationEvent.timer = new EventTimer("setup"); BatchGenerationEnvironment.isDistantGeneratorThread.set(true); + try { - return genEnvironment.generateLodFromListAsync(generationEvent, (runnable) -> + genEnvironment.generateLodFromListAsync(generationEvent, (runnable) -> { worldGeneratorThreadPool.execute(() -> { @@ -99,6 +98,10 @@ public final class GenerationEvent { runnable.run(); } + catch (Throwable throwable) + { + handleWorldGenThrowable(generationEvent, throwable); + } finally { if (!alreadyMarked) @@ -107,35 +110,46 @@ public final class GenerationEvent } } }); - }).exceptionallyCompose(throwable -> - { - while (throwable instanceof CompletionException completionException) - { - throwable = completionException.getCause(); - } - - if (throwable instanceof InterruptedException - || throwable instanceof UncheckedInterruptedException - || throwable instanceof RejectedExecutionException) - { - return CompletableFuture.completedFuture(null); - } - else - { - return CompletableFuture.failedFuture(throwable); - } }); } + catch (Throwable initialThrowable) + { + handleWorldGenThrowable(generationEvent, initialThrowable); + } finally { BatchGenerationEnvironment.isDistantGeneratorThread.remove(); } - }, worldGeneratorThreadPool) - // un-wrap future so we can go from CompletableFuture> -> CompletableFuture - // TODO can we remove this double future wrapping? - .thenCompose(Function.identity()); + + return null; + }, worldGeneratorThreadPool); return generationEvent; } + /** There's probably a better way to handle this, but it'll work for now */ + private static void handleWorldGenThrowable(GenerationEvent generationEvent, Throwable initialThrowable) + { + Throwable throwable = initialThrowable; + while (throwable instanceof CompletionException) + { + throwable = throwable.getCause(); + } + + if (throwable instanceof InterruptedException + || throwable instanceof UncheckedInterruptedException + || throwable instanceof RejectedExecutionException) + { + // these exceptions can be ignored, generally they just mean + // the thread is busy so it'll need to try again later. + // FIXME this should cause the world gen task to be re-queued so we can try again later + // however, currently it can cause large gaps in the world gen instead. + // These gaps will generate correctly if the level is reloaded and the world gen is re-queued, + // however this is makes it look like the generator isn't working or skipped something. + } + else + { + generationEvent.future.completeExceptionally(throwable); + } + } public boolean isComplete() { return this.future.isDone(); }