Fix and port batch generator to new Generator API. Now if we just fix up forge, and there's no bugs (impossible), then there's enough implemented to finally have something shown! Yay!

This commit is contained in:
TomTheFurry
2022-07-25 13:38:33 +08:00
parent 5f486b6258
commit 973be40324
9 changed files with 299 additions and 211 deletions
@@ -37,7 +37,7 @@ public class DhClientLevel implements IClientLevel {
save.getDataFolder(level).mkdirs();
save.getRenderCacheFolder(level).mkdirs();
dataFileHandler = new RemoteDataFileHandler();
renderFileHandler = new RenderFileHandler(dataFileHandler, this, save.getRenderCacheFolder(level));
renderFileHandler = new RenderFileHandler(dataFileHandler, this, save.getRenderCacheFolder(level), null);
tree = new LodQuadTree(this, Config.Client.Graphics.Quality.lodChunkRenderDistance.get()*16,
MC_CLIENT.getPlayerBlockPos().x, MC_CLIENT.getPlayerBlockPos().z, renderFileHandler);
renderBufferHandler = new RenderBufferHandler(tree);
@@ -1,6 +1,7 @@
package com.seibel.lod.core.a7.level;
import com.seibel.lod.core.a7.generation.GenerationQueue;
import com.seibel.lod.core.a7.generation.IGenerator;
import com.seibel.lod.core.a7.render.LodQuadTree;
import com.seibel.lod.core.a7.util.FileScanner;
import com.seibel.lod.core.a7.save.io.file.LocalDataFileHandler;
@@ -8,6 +9,7 @@ import com.seibel.lod.core.a7.save.io.render.RenderFileHandler;
import com.seibel.lod.core.a7.pos.DhBlockPos2D;
import com.seibel.lod.core.a7.render.RenderBufferHandler;
import com.seibel.lod.core.a7.save.structure.LocalSaveStructure;
import com.seibel.lod.core.builders.worldGeneration.BatchGenerator;
import com.seibel.lod.core.config.Config;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonInjector;
import com.seibel.lod.core.logging.DhLoggerBuilder;
@@ -33,6 +35,7 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel {
public final ILevelWrapper level;
public a7LodRenderer renderer = null;
public LodQuadTree tree = null;
public IGenerator worldGenerator = null;
public DhClientServerLevel(LocalSaveStructure save, ILevelWrapper level) {
this.level = level;
@@ -57,7 +60,7 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel {
return;
}
generationQueue = new GenerationQueue((a,b) -> renderFileHandler.write(a,b)); // FIXME: Ops. A need B and B need A... Does this work?
generationQueue = new GenerationQueue((a,b) -> this.renderFileHandler.write(a,b));
renderFileHandler = new RenderFileHandler(dataFileHandler, this, save.getRenderCacheFolder(level), generationQueue);
tree = new LodQuadTree(this, Config.Client.Graphics.Quality.lodChunkRenderDistance.get()*16,
MC_CLIENT.getPlayerBlockPos().x, MC_CLIENT.getPlayerBlockPos().z, renderFileHandler);
@@ -117,15 +120,27 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel {
//Note: saving renderFileHandler will also save the dataFileHandler.
}
private BatchGenerator batchGenerator = null;
@Override
public void close() {
if (batchGenerator != null) batchGenerator.close();
if (renderer != null) renderer.close();
if (renderBufferHandler != null) renderBufferHandler.close();
if (renderFileHandler != null) renderFileHandler.close();
dataFileHandler.close();
LOGGER.info("Closed DHLevel for {}", level);
}
@Override
public void doWorldGen() {
//TODO
if (worldGenerator == null) {
// TODO: Make a registry for generators for modding support.
batchGenerator = new BatchGenerator(this);
worldGenerator = batchGenerator;
} else {
batchGenerator.update();
}
}
@Override
@@ -54,13 +54,7 @@ public class DhServerLevel implements IServerLevel {
@Override
public void doWorldGen() {
}
@Override
public void submitChunkData(DHChunkPos chunkPos, ChunkSizedData data) {
DhSectionPos sectionPos = new DhSectionPos((byte)4, chunkPos.x, chunkPos.z);
dataFileHandler.write(sectionPos, data);
// FIXME: No world gen for server side only for now
}
@Override
@@ -12,6 +12,7 @@ import com.seibel.lod.core.logging.DhLoggerBuilder;
import com.seibel.lod.core.util.LodUtil;
import org.apache.logging.log4j.Logger;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.*;
@@ -26,9 +27,10 @@ public class RenderFileHandler implements IRenderSourceProvider {
final IClientLevel level;
final File saveDir;
final IDataSourceProvider dataSourceProvider;
@Nullable
final PlaceHolderQueue placeHolderQueue;
public RenderFileHandler(IDataSourceProvider sourceProvider, IClientLevel level, File saveRootDir, PlaceHolderQueue placeHolderQueue) {
public RenderFileHandler(IDataSourceProvider sourceProvider, IClientLevel level, File saveRootDir, @Nullable PlaceHolderQueue placeHolderQueue) {
this.dataSourceProvider = sourceProvider;
this.level = level;
this.saveDir = saveRootDir;
@@ -114,7 +116,7 @@ public class RenderFileHandler implements IRenderSourceProvider {
}
if (render != null) return render;
PlaceHolderRenderSource placeHolder = new PlaceHolderRenderSource(pos);
placeHolderQueue.track(placeHolder);
if (placeHolderQueue != null) placeHolderQueue.track(placeHolder);
return placeHolder;
}
);
@@ -53,8 +53,8 @@ public class BatchGenerator implements IChunkGenerator
public static int previousThreadCount = Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get()<1 ? 1 : (int) Math.ceil(Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get());
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
private int estimatedSampleNeeded = 128;
private int estimatedPointsToQueue = 1;
// private int estimatedSampleNeeded = 128;
// private int estimatedPointsToQueue = 1;
public BatchGenerator(ILevel targetLodLevel) {
this.targetLodLevel = targetLodLevel;
@@ -62,197 +62,197 @@ public class BatchGenerator implements IChunkGenerator
LOGGER.info("Batch Chunk Generator initialized");
}
@SuppressWarnings("unused")
public void queueGenerationRequests() {
EDistanceGenerationMode mode = Config.Client.WorldGenerator.distanceGenerationMode.get();
int newThreadCount = Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get()<1 ? 1 : (int) Math.ceil(Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get());
if (newThreadCount != previousThreadCount) {
generationGroup.resizeThreadPool(newThreadCount);
previousThreadCount = newThreadCount;
}
if (estimatedPointsToQueue < newThreadCount)
estimatedPointsToQueue = newThreadCount;
EGenerationPriority priority = Config.Client.WorldGenerator.generationPriority.get();
if (priority == EGenerationPriority.AUTO)
priority = MC.hasSinglePlayerServer() ? EGenerationPriority.FAR_FIRST : EGenerationPriority.NEAR_FIRST;
generationGroup.updateAllFutures();
if (!MC.hasSinglePlayerServer())
return;
if (!LodUtil.checkRamUsage(0.1, 64)) return;
int eventsCount = generationGroup.getEventCount();
// If we still all jobs running, return.
if (eventsCount >= estimatedPointsToQueue) {
estimatedPointsToQueue--;
if (estimatedPointsToQueue < newThreadCount)
estimatedPointsToQueue = newThreadCount;
return;
}
final int targetToGenerate = estimatedPointsToQueue - eventsCount;
int toGenerate = targetToGenerate;
int positionGoneThough = 0;
// round the player's block position down to the nearest chunk BlockPos
int playerPosX = MC.getPlayerBlockPos().getX();
int playerPosZ = MC.getPlayerBlockPos().getZ();
double runTimeRatio = Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get()>1 ? 1.0 : Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get();
//FIXME
PosToGenerateContainer posToGenerate = null;//lodDim.getPosToGenerate(estimatedSampleNeeded, playerPosX, playerPosZ,
//priority, mode);
if (eventsCount == 0 && posToGenerate.getNumberOfPos() >= estimatedSampleNeeded) {
estimatedPointsToQueue++;
if (estimatedPointsToQueue > newThreadCount * 10)
estimatedPointsToQueue = newThreadCount * 10;
}
// ApiShared.LOGGER.info("PosToGenerate: {}", posToGenerate);
// Find the max number of iterations we need to go though.
// We are checking one FarPos, and one NearPos per iterations.
// This ensures we aren't just always picking one or the other.
Steps targetStep;
switch (mode) {
case NONE:
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
break;
case BIOME_ONLY_SIMULATE_HEIGHT:
targetStep = Steps.Noise; // NOTE: Stone only. Require fake surface
break;
case SURFACE:
targetStep = Steps.Surface; // Carvers or Surface???
break;
case FEATURES:
case FULL:
targetStep = Steps.Features;
break;
default:
assert false;
return;
}
if (ENABLE_GENERATOR_STATS_LOGGING)
LOGGER.info("WorldGen. Near:" + posToGenerate.getNumberOfNearPos() + " Far:"
+ posToGenerate.getNumberOfFarPos());
if (priority == EGenerationPriority.FAR_FIRST || priority == EGenerationPriority.BALANCED) {
int nearCount = posToGenerate.getNumberOfNearPos();
int farCount = posToGenerate.getNumberOfFarPos();
if (ENABLE_GENERATOR_STATS_LOGGING)
LOGGER.info("WorldGen. Near:" + nearCount + " Far:" + farCount);
int maxIteration = Math.max(nearCount, farCount);
for (int i = 0; i < maxIteration; i++) {
// We have farPos to go though
if (i < farCount && posToGenerate.getNthDetail(i, false) != 0) {
positionGoneThough++;
byte detailLevel = (byte) (posToGenerate.getNthDetail(i, false) - 1);
int chunkX = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosX(i, false));
int chunkZ = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosZ(i, false));
int genSize = detailLevel > LodUtil.CHUNK_DETAIL_LEVEL ? 0 : generationGroupSize;
if (generationGroup.tryAddPoint(chunkX, chunkZ, genSize, targetStep, false, runTimeRatio)) {
toGenerate--;
}
}
if (toGenerate <= 0)
break;
// We have nearPos to go though
if (i < nearCount && posToGenerate.getNthDetail(i, true) != 0) {
positionGoneThough++;
byte detailLevel = (byte) (posToGenerate.getNthDetail(i, true) - 1);
int chunkX = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosX(i, true));
int chunkZ = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosZ(i, true));
int genSize = detailLevel > LodUtil.CHUNK_DETAIL_LEVEL ? 0 : generationGroupSize;
if (generationGroup.tryAddPoint(chunkX, chunkZ, genSize, targetStep, true, runTimeRatio)) {
toGenerate--;
}
}
if (toGenerate <= 0)
break;
}
} else {
int nearCount = posToGenerate.getNumberOfNearPos();
for (int i = 0; i < nearCount; i++) {
// We have nearPos to go though
if (posToGenerate.getNthDetail(i, true) != 0) {
positionGoneThough++;
byte detailLevel = (byte) (posToGenerate.getNthDetail(i, true) - 1);
int chunkX = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosX(i, true));
int chunkZ = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosZ(i, true));
int genSize = detailLevel > LodUtil.CHUNK_DETAIL_LEVEL ? 0 : generationGroupSize;
if (generationGroup.tryAddPoint(chunkX, chunkZ, genSize, targetStep, true, runTimeRatio)) {
toGenerate--;
}
if (toGenerate <= 0)
break;
}
}
// Only do far gen if toGenerate is non 0 and that we have requested all samples
// we can get.
if (toGenerate > 0 && estimatedSampleNeeded > posToGenerate.getNumberOfPos()) {
int farCount = posToGenerate.getNumberOfFarPos();
for (int i = 0; i < farCount; i++) {
// We have farPos to go though
if (posToGenerate.getNthDetail(i, false) != 0) {
positionGoneThough++;
byte detailLevel = (byte) (posToGenerate.getNthDetail(i, false) - 1);
int chunkX = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosX(i, false));
int chunkZ = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosZ(i, false));
int genSize = detailLevel > LodUtil.CHUNK_DETAIL_LEVEL ? 0 : generationGroupSize;
if (generationGroup.tryAddPoint(chunkX, chunkZ, genSize, targetStep, false, runTimeRatio)) {
toGenerate--;
}
}
if (toGenerate <= 0)
break;
}
}
}
if (targetToGenerate != toGenerate && ENABLE_GENERATOR_STATS_LOGGING) {
if (toGenerate <= 0) {
LOGGER.info(
"WorldGenerator: Sampled " + posToGenerate.getNumberOfPos() + " out of " + estimatedSampleNeeded
+ " points, started all targeted " + targetToGenerate + " generations.");
} else {
LOGGER.info("WorldGenerator: Sampled " + posToGenerate.getNumberOfPos() + " out of "
+ estimatedSampleNeeded + " points, started " + (targetToGenerate - toGenerate)
+ " out of targeted " + targetToGenerate + " generations.");
}
}
if (toGenerate > 0 && estimatedSampleNeeded <= posToGenerate.getNumberOfPos()) {
// We failed to generate enough points from the samples.
// Let's increase the estimatedSampleNeeded.
estimatedSampleNeeded *= 1.3;
// Ensure wee don't go to basically infinity
if (estimatedSampleNeeded > 32768)
estimatedSampleNeeded = 32768;
if (ENABLE_GENERATOR_STATS_LOGGING)
LOGGER.info("WorldGenerator: Increasing estimatedSampleNeeded to " + estimatedSampleNeeded);
} else if (toGenerate <= 0 && positionGoneThough * 1.5 < posToGenerate.getNumberOfPos()) {
// We haven't gone through half of them, and it's already enough.
// Let's shrink the estimatedSampleNeeded.
estimatedSampleNeeded /= 1.2;
// Ensure we don't go near zero.
if (estimatedSampleNeeded < 4)
estimatedSampleNeeded = 4;
if (ENABLE_GENERATOR_STATS_LOGGING)
LOGGER.info("WorldGenerator: Decreasing estimatedSampleNeeded to " + estimatedSampleNeeded);
}
}
// @SuppressWarnings("unused")
// public void queueGenerationRequests() {
// EDistanceGenerationMode mode = Config.Client.WorldGenerator.distanceGenerationMode.get();
// int newThreadCount = Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get()<1 ? 1 : (int) Math.ceil(Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get());
// if (newThreadCount != previousThreadCount) {
// generationGroup.resizeThreadPool(newThreadCount);
// previousThreadCount = newThreadCount;
// }
// if (estimatedPointsToQueue < newThreadCount)
// estimatedPointsToQueue = newThreadCount;
//
// EGenerationPriority priority = Config.Client.WorldGenerator.generationPriority.get();
// if (priority == EGenerationPriority.AUTO)
// priority = MC.hasSinglePlayerServer() ? EGenerationPriority.FAR_FIRST : EGenerationPriority.NEAR_FIRST;
//
// generationGroup.updateAllFutures();
// if (!MC.hasSinglePlayerServer())
// return;
// if (!LodUtil.checkRamUsage(0.1, 64)) return;
//
// int eventsCount = generationGroup.getEventCount();
// // If we still all jobs running, return.
// if (eventsCount >= estimatedPointsToQueue) {
// estimatedPointsToQueue--;
// if (estimatedPointsToQueue < newThreadCount)
// estimatedPointsToQueue = newThreadCount;
// return;
// }
//
// final int targetToGenerate = estimatedPointsToQueue - eventsCount;
// int toGenerate = targetToGenerate;
// int positionGoneThough = 0;
//
// // round the player's block position down to the nearest chunk BlockPos
// int playerPosX = MC.getPlayerBlockPos().getX();
// int playerPosZ = MC.getPlayerBlockPos().getZ();
// double runTimeRatio = Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get()>1 ? 1.0 : Config.Client.Advanced.Threading.numberOfWorldGenerationThreads.get();
//
// //FIXME
// PosToGenerateContainer posToGenerate = null;//lodDim.getPosToGenerate(estimatedSampleNeeded, playerPosX, playerPosZ,
// //priority, mode);
//
// if (eventsCount == 0 && posToGenerate.getNumberOfPos() >= estimatedSampleNeeded) {
// estimatedPointsToQueue++;
// if (estimatedPointsToQueue > newThreadCount * 10)
// estimatedPointsToQueue = newThreadCount * 10;
// }
//
// // ApiShared.LOGGER.info("PosToGenerate: {}", posToGenerate);
//
// // Find the max number of iterations we need to go though.
// // We are checking one FarPos, and one NearPos per iterations.
// // This ensures we aren't just always picking one or the other.
// Steps targetStep;
// switch (mode) {
// case NONE:
// 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
// break;
// case BIOME_ONLY_SIMULATE_HEIGHT:
// targetStep = Steps.Noise; // NOTE: Stone only. Require fake surface
// break;
// case SURFACE:
// targetStep = Steps.Surface; // Carvers or Surface???
// break;
// case FEATURES:
// case FULL:
// targetStep = Steps.Features;
// break;
// default:
// assert false;
// return;
// }
//
// if (ENABLE_GENERATOR_STATS_LOGGING)
// LOGGER.info("WorldGen. Near:" + posToGenerate.getNumberOfNearPos() + " Far:"
// + posToGenerate.getNumberOfFarPos());
// if (priority == EGenerationPriority.FAR_FIRST || priority == EGenerationPriority.BALANCED) {
//
// int nearCount = posToGenerate.getNumberOfNearPos();
// int farCount = posToGenerate.getNumberOfFarPos();
// if (ENABLE_GENERATOR_STATS_LOGGING)
// LOGGER.info("WorldGen. Near:" + nearCount + " Far:" + farCount);
// int maxIteration = Math.max(nearCount, farCount);
// for (int i = 0; i < maxIteration; i++) {
//
// // We have farPos to go though
// if (i < farCount && posToGenerate.getNthDetail(i, false) != 0) {
// positionGoneThough++;
// byte detailLevel = (byte) (posToGenerate.getNthDetail(i, false) - 1);
// int chunkX = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosX(i, false));
// int chunkZ = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosZ(i, false));
// int genSize = detailLevel > LodUtil.CHUNK_DETAIL_LEVEL ? 0 : generationGroupSize;
// if (generationGroup.tryAddPoint(chunkX, chunkZ, genSize, targetStep, false, runTimeRatio)) {
// toGenerate--;
// }
// }
// if (toGenerate <= 0)
// break;
//
// // We have nearPos to go though
// if (i < nearCount && posToGenerate.getNthDetail(i, true) != 0) {
// positionGoneThough++;
// byte detailLevel = (byte) (posToGenerate.getNthDetail(i, true) - 1);
// int chunkX = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosX(i, true));
// int chunkZ = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosZ(i, true));
// int genSize = detailLevel > LodUtil.CHUNK_DETAIL_LEVEL ? 0 : generationGroupSize;
// if (generationGroup.tryAddPoint(chunkX, chunkZ, genSize, targetStep, true, runTimeRatio)) {
// toGenerate--;
// }
// }
//
// if (toGenerate <= 0)
// break;
// }
// } else {
// int nearCount = posToGenerate.getNumberOfNearPos();
// for (int i = 0; i < nearCount; i++) {
//
// // We have nearPos to go though
// if (posToGenerate.getNthDetail(i, true) != 0) {
// positionGoneThough++;
// byte detailLevel = (byte) (posToGenerate.getNthDetail(i, true) - 1);
// int chunkX = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosX(i, true));
// int chunkZ = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosZ(i, true));
// int genSize = detailLevel > LodUtil.CHUNK_DETAIL_LEVEL ? 0 : generationGroupSize;
// if (generationGroup.tryAddPoint(chunkX, chunkZ, genSize, targetStep, true, runTimeRatio)) {
// toGenerate--;
// }
// if (toGenerate <= 0)
// break;
// }
// }
// // Only do far gen if toGenerate is non 0 and that we have requested all samples
// // we can get.
// if (toGenerate > 0 && estimatedSampleNeeded > posToGenerate.getNumberOfPos()) {
// int farCount = posToGenerate.getNumberOfFarPos();
// for (int i = 0; i < farCount; i++) {
// // We have farPos to go though
// if (posToGenerate.getNthDetail(i, false) != 0) {
// positionGoneThough++;
// byte detailLevel = (byte) (posToGenerate.getNthDetail(i, false) - 1);
// int chunkX = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosX(i, false));
// int chunkZ = LevelPosUtil.getChunkPos(detailLevel, posToGenerate.getNthPosZ(i, false));
// int genSize = detailLevel > LodUtil.CHUNK_DETAIL_LEVEL ? 0 : generationGroupSize;
// if (generationGroup.tryAddPoint(chunkX, chunkZ, genSize, targetStep, false, runTimeRatio)) {
// toGenerate--;
// }
// }
// if (toGenerate <= 0)
// break;
// }
// }
// }
//
// if (targetToGenerate != toGenerate && ENABLE_GENERATOR_STATS_LOGGING) {
// if (toGenerate <= 0) {
// LOGGER.info(
// "WorldGenerator: Sampled " + posToGenerate.getNumberOfPos() + " out of " + estimatedSampleNeeded
// + " points, started all targeted " + targetToGenerate + " generations.");
// } else {
// LOGGER.info("WorldGenerator: Sampled " + posToGenerate.getNumberOfPos() + " out of "
// + estimatedSampleNeeded + " points, started " + (targetToGenerate - toGenerate)
// + " out of targeted " + targetToGenerate + " generations.");
// }
// }
//
// if (toGenerate > 0 && estimatedSampleNeeded <= posToGenerate.getNumberOfPos()) {
// // We failed to generate enough points from the samples.
// // Let's increase the estimatedSampleNeeded.
// estimatedSampleNeeded *= 1.3;
// // Ensure wee don't go to basically infinity
// if (estimatedSampleNeeded > 32768)
// estimatedSampleNeeded = 32768;
// if (ENABLE_GENERATOR_STATS_LOGGING)
// LOGGER.info("WorldGenerator: Increasing estimatedSampleNeeded to " + estimatedSampleNeeded);
//
// } else if (toGenerate <= 0 && positionGoneThough * 1.5 < posToGenerate.getNumberOfPos()) {
// // We haven't gone through half of them, and it's already enough.
// // Let's shrink the estimatedSampleNeeded.
// estimatedSampleNeeded /= 1.2;
// // Ensure we don't go near zero.
// if (estimatedSampleNeeded < 4)
// estimatedSampleNeeded = 4;
// if (ENABLE_GENERATOR_STATS_LOGGING)
// LOGGER.info("WorldGenerator: Decreasing estimatedSampleNeeded to " + estimatedSampleNeeded);
// }
//
// }
public void stop(boolean blocking) {
LOGGER.info("1.18 Experimental Chunk Generator shutting down...");
@@ -315,4 +315,9 @@ public class BatchGenerator implements IChunkGenerator
public void close() {
stop(true);
}
public void update() {
generationGroup.updateAllFutures();
}
}
@@ -102,11 +102,11 @@ public class DhApiEventInjector extends DependencyInjector<IDhApiEvent>
* @return if any of the events returned that this event should be canceled.
* @param <T> the parameter type taken by the event handlers.
*/
public <T> boolean fireAllEvents(Class<? extends IDhApiEvent<T>> dependencyInterface, T eventParameterObject)
public <T, U extends IDhApiEvent<T>> boolean fireAllEvents(Class<U> dependencyInterface, T eventParameterObject)
{
boolean cancelEvent = false;
ArrayList<IDhApiEvent<T>> eventList = this.getAll(dependencyInterface);
ArrayList<U> eventList = this.getAll(dependencyInterface);
for (IDhApiEvent<T> event : eventList)
{
if (event != null)
@@ -0,0 +1,70 @@
package com.seibel.lod.core.util;
import java.time.Duration;
import java.util.ArrayList;
public class EventTimer {
public static class Event {
public long timeNs = -1;
public String name;
Event(String name) {
this.name = name;
}
}
long lastEventNs = -1;
public ArrayList<Event> events = new ArrayList<>();
public EventTimer(String firstEventName) {
lastEventNs = System.nanoTime();
events.add(new Event(firstEventName));
}
public void nextEvent(String name) {
long timeNs = System.nanoTime();
if (lastEventNs != -1 && !events.isEmpty() && events.get(events.size()-1).timeNs == -1) {
events.get(events.size()-1).timeNs = timeNs - lastEventNs;
}
lastEventNs = timeNs;
events.add(new Event(name));
}
public void complete() {
long timeNs = System.nanoTime();
if (lastEventNs != -1 && !events.isEmpty() && events.get(events.size()-1).timeNs == -1) {
events.get(events.size()-1).timeNs = timeNs - lastEventNs;
}
lastEventNs = -1;
}
public long getEventTimeNs(String name) {
for (Event e : events) {
if (e.name.equals(name)) {
return e.timeNs;
}
}
return -1;
}
public long getTotalTimeNs() {
long total = 0;
for (Event e : events) {
if (e.timeNs != -1) {
total += e.timeNs;
}
}
return total;
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (Event e : events) {
if (e.timeNs != -1) {
sb.append(e.name).append(": ").append(Duration.ofNanos(e.timeNs)).append('\n');
} else {
sb.append(e.name).append(": ").append("N/A").append('\n');
}
}
return sb.toString();
}
}
@@ -443,6 +443,12 @@ public class LodUtil
public static void assertTrue(boolean condition, String message) {
if (!condition) throw new RuntimeException("Assertion failed: " + message);
}
public static void assertNotReach(String message) {
throw new RuntimeException("Assert Not Reach failed: " + message);
}
public static void assertNotReach() {
throw new RuntimeException("Assert Not Reach failed");
}
public static ExecutorService makeSingleThreadPool(String name, int relativePriority) {
return Executors.newSingleThreadExecutor(new LodThreadFactory(name, Thread.NORM_PRIORITY+relativePriority));
}
@@ -35,14 +35,10 @@ public abstract class AbstractBatchGenerationEnvionmentWrapper {
public abstract void resizeThreadPool(int newThreadCount);
@Deprecated
public abstract void updateAllFutures();
public abstract int getEventCount();
@Deprecated
public abstract boolean tryAddPoint(int chunkX, int chunkZ, int genSize, Steps targetStep, boolean genAllDetails, double runTimeRatio);
public abstract void stop(boolean blocking);
public abstract CompletableFuture<ArrayGridList<IChunkWrapper>> generateChunks(int minX, int minZ, int genSize, Steps targetStep, double runTimeRatio);