From eff161fb24dfdf297367fad5a02a719f9d316f1f Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 10 Dec 2022 09:34:19 -0600 Subject: [PATCH] Remove IWorldGenerator (everything is handled in IDhApiWorldGen) --- .../IDhApiWorldGeneratorOverrideRegister.java | 4 +- .../lod/core/generation/BatchGenerator.java | 3 +- .../lod/core/generation/IWorldGenerator.java | 50 ------------------- .../core/generation/WorldGenerationQueue.java | 49 ++++++++++++++++-- .../lod/core/level/DhClientServerLevel.java | 36 ++++++------- 5 files changed, 69 insertions(+), 73 deletions(-) delete mode 100644 core/src/main/java/com/seibel/lod/core/generation/IWorldGenerator.java diff --git a/api/src/main/java/com/seibel/lod/api/interfaces/override/worldGenerator/IDhApiWorldGeneratorOverrideRegister.java b/api/src/main/java/com/seibel/lod/api/interfaces/override/worldGenerator/IDhApiWorldGeneratorOverrideRegister.java index 3ea5bae22..6e56212ed 100644 --- a/api/src/main/java/com/seibel/lod/api/interfaces/override/worldGenerator/IDhApiWorldGeneratorOverrideRegister.java +++ b/api/src/main/java/com/seibel/lod/api/interfaces/override/worldGenerator/IDhApiWorldGeneratorOverrideRegister.java @@ -19,7 +19,7 @@ public interface IDhApiWorldGeneratorOverrideRegister * If another world generator has already been registered, DhApiResult will return * the name of the previously registered generator and success = false. */ - DhApiResult registerWorldGeneratorOverride(IDhApiWorldGenerator worldGenerator); + DhApiResult registerWorldGeneratorOverride(IDhApiWorldGenerator worldGenerator); /** * Registers the given world generator for the given level.

@@ -28,6 +28,6 @@ public interface IDhApiWorldGeneratorOverrideRegister * If another world generator has already been registered, DhApiResult will return * the name of the previously registered generator and success = false. */ - DhApiResult registerWorldGeneratorOverride(IDhApiLevelWrapper levelWrapper, IDhApiWorldGenerator worldGenerator); + DhApiResult registerWorldGeneratorOverride(IDhApiLevelWrapper levelWrapper, IDhApiWorldGenerator worldGenerator); } 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 01330d185..724869ecf 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 @@ -20,6 +20,7 @@ package com.seibel.lod.core.generation; import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenThreadMode; +import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGenerator; import com.seibel.lod.core.level.IDhLevel; import com.seibel.lod.core.config.Config; import com.seibel.lod.api.enums.config.EDistanceGenerationMode; @@ -40,7 +41,7 @@ import java.util.function.Consumer; * @author Leetom * @version 2022-11-25 */ -public class BatchGenerator implements IWorldGenerator +public class BatchGenerator implements IDhApiWorldGenerator { private static final IWrapperFactory FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class); private static final Logger LOGGER = DhLoggerBuilder.getLogger(); diff --git a/core/src/main/java/com/seibel/lod/core/generation/IWorldGenerator.java b/core/src/main/java/com/seibel/lod/core/generation/IWorldGenerator.java deleted file mode 100644 index d9b200257..000000000 --- a/core/src/main/java/com/seibel/lod/core/generation/IWorldGenerator.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.seibel.lod.core.generation; - -import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGenerator; -import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.datatype.full.ChunkSizedData; -import com.seibel.lod.core.datatype.transform.LodDataBuilder; -import com.seibel.lod.core.dependencyInjection.SingletonInjector; -import com.seibel.lod.core.logging.DhLoggerBuilder; -import com.seibel.lod.core.pos.DhChunkPos; -import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; -import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; - -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; - -/** - * Most logic is in {@link IDhApiWorldGenerator}, this mainly contains default - * methods that are useful for Core. - * - * @author James Seibel - * @author Leetom - * @version 2022-12-5 - */ -public interface IWorldGenerator extends IDhApiWorldGenerator -{ - /** - * Start a generation event - * (Note that the chunkPos is always aligned to the granularity) - * (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, - Consumer resultConsumer) - { - return this.generateChunks(chunkPosMin.x, chunkPosMin.z, granularity, targetDataDetail, (objectArray) -> - { - try - { - IChunkWrapper chunk = SingletonInjector.INSTANCE.get(IWrapperFactory.class).createChunkWrapper(objectArray); - resultConsumer.accept(LodDataBuilder.createChunkData(chunk)); - } - catch (ClassCastException e) - { - DhLoggerBuilder.getLogger().error("World generator return type incorrect. Error: [" + e.getMessage() + "].", e); - Config.Client.WorldGenerator.enableDistantGeneration.set(false); - } - }); - } - -} 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 6ffa7b743..455304e9d 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 @@ -1,5 +1,10 @@ package com.seibel.lod.core.generation; +import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGenerator; +import com.seibel.lod.core.config.Config; +import com.seibel.lod.core.datatype.full.ChunkSizedData; +import com.seibel.lod.core.datatype.transform.LodDataBuilder; +import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.generation.tasks.*; import com.seibel.lod.core.pos.DhBlockPos2D; import com.seibel.lod.core.pos.DhLodPos; @@ -8,11 +13,14 @@ import com.seibel.lod.core.util.objects.UncheckedInterruptedException; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.pos.DhChunkPos; import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; +import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import org.apache.logging.log4j.Logger; import java.io.Closeable; import java.util.*; import java.util.concurrent.*; +import java.util.function.Consumer; /** * @author Leetom @@ -25,7 +33,7 @@ public class WorldGenerationQueue implements Closeable private static final Logger LOGGER = DhLoggerBuilder.getLogger(); - private final IWorldGenerator generator; + private final IDhApiWorldGenerator generator; private final ConcurrentLinkedQueue looseTasks = new ConcurrentLinkedQueue<>(); // FIXME: Concurrency issue on close! @@ -57,7 +65,7 @@ public class WorldGenerationQueue implements Closeable - public WorldGenerationQueue(IWorldGenerator generator) + public WorldGenerationQueue(IDhApiWorldGenerator generator) { this.generator = generator; this.maxGranularity = generator.getMaxGenerationGranularity(); @@ -73,6 +81,10 @@ public class WorldGenerationQueue implements Closeable + //=================// + // world generator // + // task handling // + //=================// public CompletableFuture submitGenTask(DhLodPos pos, byte requiredDataDetail, AbstractWorldGenTaskTracker tracker) { @@ -410,7 +422,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 = startGenerationEvent(this.generator, chunkPosMin, granularity, dataDetail, task.group::accept); task.genFuture.whenComplete((v, ex) -> { if (ex != null) { @@ -428,6 +440,12 @@ public class WorldGenerationQueue implements Closeable }); } + + + //==========// + // shutdown // + //==========// + public CompletableFuture startClosing(boolean cancelCurrentGeneration, boolean alsoInterruptRunning) { this.taskGroups.values().forEach(g -> g.generatorTasks.forEach(t -> t.future.complete(false))); @@ -499,4 +517,29 @@ public class WorldGenerationQueue implements Closeable return index; } + + /** + * The chunkPos is always aligned to the granularity. + * 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. + */ + private static CompletableFuture startGenerationEvent(IDhApiWorldGenerator worldGenerator, + DhChunkPos chunkPosMin, + byte granularity, byte targetDataDetail, + Consumer resultConsumer) + { + return worldGenerator.generateChunks(chunkPosMin.x, chunkPosMin.z, granularity, targetDataDetail, (objectArray) -> + { + try + { + IChunkWrapper chunk = SingletonInjector.INSTANCE.get(IWrapperFactory.class).createChunkWrapper(objectArray); + resultConsumer.accept(LodDataBuilder.createChunkData(chunk)); + } + catch (ClassCastException e) + { + DhLoggerBuilder.getLogger().error("World generator return type incorrect. Error: [" + e.getMessage() + "].", e); + Config.Client.WorldGenerator.enableDistantGeneration.set(false); + } + }); + } + } 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 8159b84cc..04e3f6beb 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 @@ -1,11 +1,14 @@ package com.seibel.lod.core.level; +import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGenerator; +import com.seibel.lod.api.interfaces.world.IDhApiLevelWrapper; +import com.seibel.lod.core.DependencyInjection.WorldGeneratorInjector; import com.seibel.lod.core.config.AppliedConfigState; 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.IWorldGenerator; +import com.seibel.lod.core.generation.BatchGenerator; import com.seibel.lod.core.generation.WorldGenerationQueue; import com.seibel.lod.core.pos.DhLodPos; import com.seibel.lod.core.pos.DhSectionPos; @@ -16,7 +19,6 @@ import com.seibel.lod.core.file.renderfile.RenderFileHandler; import com.seibel.lod.core.pos.DhBlockPos2D; import com.seibel.lod.core.render.RenderBufferHandler; import com.seibel.lod.core.file.structure.LocalSaveStructure; -import com.seibel.lod.core.generation.BatchGenerator; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.logging.DhLoggerBuilder; @@ -145,7 +147,7 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel this.generatorEnabled.pollNewValue(); if (this.generatorEnabled.get() && this.worldGenState.get() == null) { - WorldGenState wgs = new WorldGenState(); + WorldGenState wgs = new WorldGenState(this); if (!this.worldGenState.compareAndSet(null, wgs)) { LOGGER.warn("Failed to start world gen due to concurrency"); @@ -296,7 +298,7 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel boolean shouldDoWorldGen = this.generatorEnabled.get() && this.renderState.get() != null; if (shouldDoWorldGen && wgs == null) { - WorldGenState newWgs = new WorldGenState(); + WorldGenState newWgs = new WorldGenState(this); if (!this.worldGenState.compareAndSet(null, newWgs)) { LOGGER.warn("Failed to start world gen due to concurrency"); @@ -365,12 +367,12 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel private class WorldGenState { - public final IWorldGenerator chunkGenerator; + public final IDhApiWorldGenerator chunkGenerator; public final WorldGenerationQueue worldGenerationQueue; - WorldGenState() + WorldGenState(IDhLevel level) { - this.chunkGenerator = new BatchGenerator(DhClientServerLevel.this); + this.chunkGenerator = new BatchGenerator(level); // WorldGeneratorInjector.INSTANCE.get(level); // this.worldGenerationQueue = new WorldGenerationQueue(this.chunkGenerator); dataFileHandler.setGenerationQueue(this.worldGenerationQueue); } @@ -379,16 +381,16 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel { dataFileHandler.popGenerationQueue(); return this.worldGenerationQueue.startClosing(true, doInterrupt) - .exceptionally(ex -> - { - LOGGER.error("Error closing generation queue", ex); - return null; - }).thenRun(this.chunkGenerator::close) - .exceptionally(ex -> - { - LOGGER.error("Error closing world gen", ex); - return null; - }); + .exceptionally(ex -> + { + LOGGER.error("Error closing generation queue", ex); + return null; + }).thenRun(this.chunkGenerator::close) + .exceptionally(ex -> + { + LOGGER.error("Error closing world gen", ex); + return null; + }); } }