From 24260a057a1ec25c59a662248d1e3c616dd38868 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 3 Dec 2022 19:45:44 -0600 Subject: [PATCH] Prep the IChunkGenerator/BatchGenerator for using the API --- .../lod/core/generation/BatchGenerator.java | 66 ++++++++++--------- .../lod/core/generation/IChunkGenerator.java | 31 +++++++-- .../core/generation/WorldGenerationQueue.java | 3 +- .../lod/core/level/DhClientServerLevel.java | 17 ++--- 4 files changed, 70 insertions(+), 47 deletions(-) diff --git a/core/src/main/java/com/seibel/lod/core/generation/BatchGenerator.java b/core/src/main/java/com/seibel/lod/core/generation/BatchGenerator.java index 7b17eab9f..8c4f2c385 100644 --- a/core/src/main/java/com/seibel/lod/core/generation/BatchGenerator.java +++ b/core/src/main/java/com/seibel/lod/core/generation/BatchGenerator.java @@ -29,7 +29,6 @@ import com.seibel.lod.core.util.BitShiftUtil; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; -import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper; import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper.Steps; import org.apache.logging.log4j.Logger; @@ -44,26 +43,49 @@ import java.util.function.Consumer; */ public class BatchGenerator implements IChunkGenerator { - public static final boolean ENABLE_GENERATOR_STATS_LOGGING = false; - - private static final IMinecraftClientWrapper MC = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); private static final IWrapperFactory FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); + private static final Logger LOGGER = DhLoggerBuilder.getLogger(); + public AbstractBatchGenerationEnvionmentWrapper generationGroup; - public IDhLevel targetLodLevel; - public static final int generationGroupSize = 4; - private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName()); + public IDhLevel targetDhLevel; - public BatchGenerator(IDhLevel targetLodLevel) + + public BatchGenerator(IDhLevel targetDhLevel) { - this.targetLodLevel = targetLodLevel; - this.generationGroup = FACTORY.createBatchGenerator(targetLodLevel); + this.targetDhLevel = targetDhLevel; + this.generationGroup = FACTORY.createBatchGenerator(targetDhLevel); LOGGER.info("Batch Chunk Generator initialized"); } + //======================// + // generator parameters // + //======================// + + @Override + public byte getMinDataDetailLevel() { return LodUtil.BLOCK_DETAIL_LEVEL; } + + @Override + public byte getMaxDataDetailLevel() { return LodUtil.BLOCK_DETAIL_LEVEL; } + + @Override + public byte getMinGenerationGranularity() { return LodUtil.CHUNK_DETAIL_LEVEL; } + + @Override + public byte getMaxGenerationGranularity() { return LodUtil.CHUNK_DETAIL_LEVEL + 2; } + + + + + //===================// + // generator methods // + //===================// + + @Override + public void close() { this.stop(true); } public void stop(boolean blocking) { LOGGER.info("Batch Chunk Generator shutting down..."); @@ -87,7 +109,7 @@ public class BatchGenerator implements IChunkGenerator targetStep = Steps.Empty; // NOTE: Only load in existing chunks. No new chunk generation break; case BIOME_ONLY: - targetStep = Steps.Biomes; // NOTE: No block. Require fake height in LodBuilder + targetStep = Steps.Biomes; // NOTE: No blocks. Require fake height in LodBuilder break; case BIOME_ONLY_SIMULATE_HEIGHT: targetStep = Steps.Noise; // NOTE: Stone only. Require fake surface @@ -100,11 +122,10 @@ public class BatchGenerator implements IChunkGenerator targetStep = Steps.Features; break; } - ; int chunkXMin = chunkPosMin.x; int chunkZMin = chunkPosMin.z; - int genChunkSize = BitShiftUtil.powerOfTwo(granularity - 4); // minus 4 for chunk size is equal to dividing by 16 + int genChunkSize = BitShiftUtil.powerOfTwo(granularity - 4); // minus 4 is equal to dividing by 16 to convert to chunk scale double runTimeRatio = Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get() > 1 ? 1.0 : Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get(); @@ -112,23 +133,6 @@ public class BatchGenerator implements IChunkGenerator } @Override - public byte getMinDataDetailLevel() { return LodUtil.BLOCK_DETAIL_LEVEL; } - - @Override - public byte getMaxDataDetailLevel() { return LodUtil.BLOCK_DETAIL_LEVEL; } - - @Override - public int getPriority() { return LodUtil.BLOCK_DETAIL_LEVEL; } - - @Override - public byte getMinGenerationGranularity() { return LodUtil.CHUNK_DETAIL_LEVEL; } - - @Override - public byte getMaxGenerationGranularity() { return LodUtil.CHUNK_DETAIL_LEVEL + 2; } - - @Override - public void close() { this.stop(true); } - - public void update() { this.generationGroup.updateAllFutures(); } + public void preGeneratorTaskStart() { this.generationGroup.updateAllFutures(); } } diff --git a/core/src/main/java/com/seibel/lod/core/generation/IChunkGenerator.java b/core/src/main/java/com/seibel/lod/core/generation/IChunkGenerator.java index 358e32725..edb5d9a94 100644 --- a/core/src/main/java/com/seibel/lod/core/generation/IChunkGenerator.java +++ b/core/src/main/java/com/seibel/lod/core/generation/IChunkGenerator.java @@ -22,18 +22,16 @@ public interface IChunkGenerator extends Closeable /** * What is the detail/resolution of the data? (This will offset the generation granularity) * (minimum detail is 0, maximum detail is 255) (though that high isn't really... realistic) - * (0 = 1x1 block per data, 1 = 2x2 block per data, 2 = 4x4 block per data... etc.) + * (0 = 1x1 block per data, 1 = 2x2 block per data, 2 = 4x4 block per data, etc. This measured in the same units as LOD Detail Level.) * TODO: System currently only supports 1x1 block per data. */ byte getMinDataDetailLevel(); byte getMaxDataDetailLevel(); - int getPriority(); - /** * What is the min batch size of a single generation call? * (minimum return value is 4 since that's the MC chunk size) - * (4 -> 16x16 data per call, 5 -> 32x32 data per call, 6 -> 64x64 data per call... etc.) + * (4 -> 16x16 data per call, 5 -> 32x32 data per call, 6 -> 64x64 data per call, etc. This measured in the same units as LOD Detail Level.) */ byte getMinGenerationGranularity(); @@ -41,7 +39,7 @@ public interface IChunkGenerator extends Closeable * What is the max batch size of a single generation call? * The system will try to group tasks to the max batch size if possible * (minimum return value is 4 since that's the MC chunk size) - * (4 -> 16x16 data per call, 5 -> 32x32 data per call, 6 -> 64x64 data per call... etc.) + * (4 -> 16x16 data per call, 5 -> 32x32 data per call, 6 -> 64x64 data per call, etc. This measured in the same units as LOD Detail Level.) */ byte getMaxGenerationGranularity(); @@ -62,7 +60,7 @@ public interface IChunkGenerator extends Closeable /** * Start a generation event * (Note that the chunkPos is always aligned to the granularity) - * (For example, if the granularity is 4, data detail is 0, the chunkPos will be aligned to 16x16 blocks) + * (For example, if the granularity is 4 (chunk sized) with a data detail level of 0 (block sized), the chunkPos will be aligned to 16x16 blocks) */ default CompletableFuture generate(DhChunkPos chunkPosMin, byte granularity, byte targetDataDetail, @@ -75,4 +73,25 @@ public interface IChunkGenerator extends Closeable } + //===============// + // event methods // + //===============// + + /** + * Called before a new generator task is started.
+ * This can be used to run cleanup on existing tasks before new tasks are started. + */ + void preGeneratorTaskStart(); + + + + //===========// + // overrides // + //===========// + + // This is overridden to remove the "throws IOException" + // that is present in the default Closeable.close() method + @Override + void close(); + } diff --git a/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java b/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java index e2c2931c9..ec40612c5 100644 --- a/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java +++ b/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java @@ -410,8 +410,7 @@ public class WorldGenerationQueue implements Closeable DhChunkPos chunkPosMin = new DhChunkPos(pos.getCorner()); LOGGER.info("Generating section {} with granularity {} at {}", pos, granularity, chunkPosMin); - task.genFuture = this.generator.generate( - chunkPosMin, granularity, dataDetail, task.group::accept); + task.genFuture = this.generator.generate(chunkPosMin, granularity, dataDetail, task.group::accept); task.genFuture.whenComplete((v, ex) -> { if (ex != null) { diff --git a/core/src/main/java/com/seibel/lod/core/level/DhClientServerLevel.java b/core/src/main/java/com/seibel/lod/core/level/DhClientServerLevel.java index 979b65d4d..635f64802 100644 --- a/core/src/main/java/com/seibel/lod/core/level/DhClientServerLevel.java +++ b/core/src/main/java/com/seibel/lod/core/level/DhClientServerLevel.java @@ -5,6 +5,7 @@ import com.seibel.lod.core.datatype.full.ChunkSizedData; import com.seibel.lod.core.datatype.full.FullDataSource; import com.seibel.lod.core.datatype.transform.ChunkToLodBuilder; import com.seibel.lod.core.file.datafile.IDataSourceProvider; +import com.seibel.lod.core.generation.IChunkGenerator; import com.seibel.lod.core.generation.WorldGenerationQueue; import com.seibel.lod.core.pos.DhLodPos; import com.seibel.lod.core.pos.DhSectionPos; @@ -316,7 +317,7 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel if (wgs != null) { - wgs.batchGenerator.update(); + wgs.chunkGenerator.preGeneratorTaskStart(); wgs.worldGenerationQueue.pollAndStartClosest(new DhBlockPos2D(MC_CLIENT.getPlayerBlockPos())); } } @@ -334,7 +335,7 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel // helper classes // //================// - class RenderState + private class RenderState { final IClientLevelWrapper clientLevel; final LodQuadTree tree; @@ -362,15 +363,15 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel } } - class WorldGenState + private class WorldGenState { - final BatchGenerator batchGenerator; - final WorldGenerationQueue worldGenerationQueue; + public final IChunkGenerator chunkGenerator; + public final WorldGenerationQueue worldGenerationQueue; WorldGenState() { - this.batchGenerator = new BatchGenerator(DhClientServerLevel.this); - this.worldGenerationQueue = new WorldGenerationQueue(this.batchGenerator); + this.chunkGenerator = new BatchGenerator(DhClientServerLevel.this); + this.worldGenerationQueue = new WorldGenerationQueue(this.chunkGenerator); dataFileHandler.setGenerationQueue(this.worldGenerationQueue); } @@ -382,7 +383,7 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel { LOGGER.error("Error closing generation queue", ex); return null; - }).thenRun(this.batchGenerator::close) + }).thenRun(this.chunkGenerator::close) .exceptionally(ex -> { LOGGER.error("Error closing world gen", ex);