Remove IWorldGenerator (everything is handled in IDhApiWorldGen)

This commit is contained in:
James Seibel
2022-12-10 09:34:19 -06:00
parent 1489cb0bdb
commit eff161fb24
5 changed files with 69 additions and 73 deletions
@@ -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<Void> registerWorldGeneratorOverride(IDhApiWorldGenerator worldGenerator);
/**
* Registers the given world generator for the given level. <Br> <Br>
@@ -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<Void> registerWorldGeneratorOverride(IDhApiLevelWrapper levelWrapper, IDhApiWorldGenerator worldGenerator);
}
@@ -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();
@@ -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<Void> generate(DhChunkPos chunkPosMin,
byte granularity, byte targetDataDetail,
Consumer<ChunkSizedData> 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);
}
});
}
}
@@ -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<WorldGenTask> 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<Boolean> 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<Void> 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<Void> startGenerationEvent(IDhApiWorldGenerator worldGenerator,
DhChunkPos chunkPosMin,
byte granularity, byte targetDataDetail,
Consumer<ChunkSizedData> 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);
}
});
}
}
@@ -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;
});
}
}