forked from xjboss/KCauldronX
Cap chunk generation to 1 chunk per tick (configurable)
This commit is contained in:
parent
232bc98881
commit
8d2ba00f70
@ -11,7 +11,15 @@
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Strings;
|
||||
@@ -282,6 +286,7 @@
|
||||
@@ -245,6 +249,7 @@
|
||||
public void onPostServerTick()
|
||||
{
|
||||
bus().post(new TickEvent.ServerTickEvent(Phase.END));
|
||||
+ kcauldron.ChunkGenerator.INSTANCE.chunkGeneratorCycle(); // KCauldron
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,6 +287,7 @@
|
||||
{
|
||||
Loader.instance().serverStarted();
|
||||
sidedDelegate.allowLogins();
|
||||
@ -19,7 +27,7 @@
|
||||
}
|
||||
|
||||
public void handleServerStopping()
|
||||
@@ -385,10 +390,11 @@
|
||||
@@ -385,10 +391,11 @@
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -32,7 +40,7 @@
|
||||
handlerSet.add(handler);
|
||||
handlerToCheck = new WeakReference<SaveHandler>(handler); // for confirmBackupLevelDatUse
|
||||
Map<String,NBTBase> additionalProperties = Maps.newHashMap();
|
||||
@@ -496,7 +502,13 @@
|
||||
@@ -496,7 +503,13 @@
|
||||
|
||||
public String getModName()
|
||||
{
|
||||
@ -47,7 +55,7 @@
|
||||
modNames.add("fml");
|
||||
if (!noForge)
|
||||
{
|
||||
@@ -540,8 +552,17 @@
|
||||
@@ -540,8 +553,17 @@
|
||||
bus().post(new InputEvent.KeyInputEvent());
|
||||
}
|
||||
|
||||
|
@ -15,40 +15,15 @@
|
||||
public class BiomeDecorator
|
||||
{
|
||||
public World currentWorld;
|
||||
@@ -61,6 +69,8 @@
|
||||
@@ -61,6 +69,7 @@
|
||||
public int clayPerChunk;
|
||||
public int bigMushroomsPerChunk;
|
||||
public boolean generateLakes;
|
||||
+ private final List<Chunk> chunksToUnload = new ArrayList<Chunk>(); // Spigot
|
||||
+ private final java.util.concurrent.locks.Lock decorateLock = new java.util.concurrent.locks.ReentrantLock();
|
||||
private static final String __OBFID = "CL_00000164";
|
||||
|
||||
public BiomeDecorator()
|
||||
@@ -92,12 +102,8 @@
|
||||
|
||||
public void decorateChunk(World p_150512_1_, Random p_150512_2_, BiomeGenBase p_150512_3_, int p_150512_4_, int p_150512_5_)
|
||||
{
|
||||
- if (this.currentWorld != null)
|
||||
- {
|
||||
- throw new RuntimeException("Already decorating!!");
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
+ decorateLock.lock();
|
||||
+ try {
|
||||
this.currentWorld = p_150512_1_;
|
||||
this.randomGenerator = p_150512_2_;
|
||||
this.chunk_X = p_150512_4_;
|
||||
@@ -105,6 +111,8 @@
|
||||
this.genDecorations(p_150512_3_);
|
||||
this.currentWorld = null;
|
||||
this.randomGenerator = null;
|
||||
+ } finally {
|
||||
+ decorateLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +202,7 @@
|
||||
@@ -194,7 +196,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
@ -57,7 +32,7 @@
|
||||
WorldGenerator worldgenerator = p_150513_1_.getRandomWorldGenForGrass(this.randomGenerator);
|
||||
worldgenerator.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
@@ -204,7 +212,7 @@
|
||||
@@ -204,7 +206,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
@ -66,7 +41,7 @@
|
||||
(new WorldGenDeadBush(Blocks.deadbush)).generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
|
||||
@@ -214,7 +222,7 @@
|
||||
@@ -214,7 +216,7 @@
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
|
||||
@ -75,7 +50,7 @@
|
||||
{
|
||||
;
|
||||
}
|
||||
@@ -229,7 +237,7 @@
|
||||
@@ -229,7 +231,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
@ -84,7 +59,7 @@
|
||||
this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
|
||||
@@ -237,7 +245,7 @@
|
||||
@@ -237,7 +239,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
@ -93,7 +68,7 @@
|
||||
this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
}
|
||||
@@ -246,7 +254,7 @@
|
||||
@@ -246,7 +248,7 @@
|
||||
{
|
||||
j = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
@ -102,7 +77,7 @@
|
||||
this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, j, l, k);
|
||||
}
|
||||
|
||||
@@ -254,7 +262,7 @@
|
||||
@@ -254,7 +256,7 @@
|
||||
{
|
||||
j = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
@ -111,7 +86,7 @@
|
||||
this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, j, l, k);
|
||||
}
|
||||
|
||||
@@ -263,7 +271,7 @@
|
||||
@@ -263,7 +265,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
@ -120,7 +95,7 @@
|
||||
this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
|
||||
@@ -271,7 +279,7 @@
|
||||
@@ -271,7 +273,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
@ -129,7 +104,7 @@
|
||||
this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
|
||||
@@ -280,7 +288,7 @@
|
||||
@@ -280,7 +282,7 @@
|
||||
{
|
||||
j = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
@ -138,7 +113,7 @@
|
||||
(new WorldGenPumpkin()).generate(this.currentWorld, this.randomGenerator, j, l, k);
|
||||
}
|
||||
|
||||
@@ -289,7 +297,7 @@
|
||||
@@ -289,7 +291,7 @@
|
||||
{
|
||||
k = this.chunk_X + this.randomGenerator.nextInt(16) + 8;
|
||||
l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8;
|
||||
@ -147,7 +122,7 @@
|
||||
this.cactusGen.generate(this.currentWorld, this.randomGenerator, k, i1, l);
|
||||
}
|
||||
|
||||
@@ -313,6 +321,7 @@
|
||||
@@ -313,6 +315,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,7 +130,7 @@
|
||||
MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z));
|
||||
}
|
||||
|
||||
@@ -360,6 +369,31 @@
|
||||
@@ -360,6 +363,31 @@
|
||||
MinecraftForge.ORE_GEN_BUS.post(new OreGenEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z));
|
||||
}
|
||||
|
||||
|
@ -188,13 +188,27 @@
|
||||
// We can only use the queue for already generated chunks
|
||||
if (chunk == null && loader != null && loader.chunkExists(this.worldObj, par1, par2))
|
||||
{
|
||||
@@ -142,18 +213,19 @@
|
||||
@@ -128,6 +199,12 @@
|
||||
}
|
||||
else if (chunk == null)
|
||||
{
|
||||
+ // KCauldron start
|
||||
+ if (runnable != null) {
|
||||
+ kcauldron.ChunkGenerator.INSTANCE.queueChunkGeneration(this, par1, par2, new net.minecraftforge.common.chunkio.ChunkIOExecutor.RunnableCallback(runnable));
|
||||
+ return null;
|
||||
+ }
|
||||
+ // KCauldron end
|
||||
chunk = this.originalLoadChunk(par1, par2);
|
||||
}
|
||||
|
||||
@@ -142,18 +219,20 @@
|
||||
|
||||
public Chunk originalLoadChunk(int p_73158_1_, int p_73158_2_)
|
||||
{
|
||||
- long k = ChunkCoordIntPair.chunkXZ2Int(p_73158_1_, p_73158_2_);
|
||||
- this.chunksToUnload.remove(Long.valueOf(k));
|
||||
- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(k);
|
||||
+ generatorLock.lock(); try { // KCauldron
|
||||
+ this.chunksToUnload.remove(p_73158_1_, p_73158_2_);
|
||||
+ Chunk chunk = (Chunk) this.chunkManager.getChunk(p_73158_1_, p_73158_2_); // KCauldron
|
||||
+ boolean newChunk = false; // CraftBukkit
|
||||
@ -213,7 +227,7 @@
|
||||
if (chunk == null)
|
||||
{
|
||||
chunk = this.safeLoadChunk(p_73158_1_, p_73158_2_);
|
||||
@@ -176,18 +248,53 @@
|
||||
@@ -176,30 +255,84 @@
|
||||
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Exception generating new chunk");
|
||||
CrashReportCategory crashreportcategory = crashreport.makeCategory("Chunk to be generated");
|
||||
crashreportcategory.addCrashSection("Location", String.format("%d,%d", new Object[] {Integer.valueOf(p_73158_1_), Integer.valueOf(p_73158_2_)}));
|
||||
@ -272,7 +286,8 @@
|
||||
}
|
||||
|
||||
return chunk;
|
||||
@@ -195,11 +302,29 @@
|
||||
+ } finally { generatorLock.unlock(); } // KCauldron
|
||||
}
|
||||
|
||||
public Chunk provideChunk(int p_73154_1_, int p_73154_2_)
|
||||
{
|
||||
@ -305,7 +320,7 @@
|
||||
{
|
||||
if (this.currentChunkLoader == null)
|
||||
{
|
||||
@@ -209,6 +334,7 @@
|
||||
@@ -209,6 +342,7 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -313,7 +328,7 @@
|
||||
Chunk chunk = this.currentChunkLoader.loadChunk(this.worldObj, p_73239_1_, p_73239_2_);
|
||||
|
||||
if (chunk != null)
|
||||
@@ -217,8 +343,11 @@
|
||||
@@ -217,8 +351,11 @@
|
||||
|
||||
if (this.currentChunkProvider != null)
|
||||
{
|
||||
@ -325,7 +340,7 @@
|
||||
}
|
||||
|
||||
return chunk;
|
||||
@@ -231,7 +360,7 @@
|
||||
@@ -231,7 +368,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,7 +349,7 @@
|
||||
{
|
||||
if (this.currentChunkLoader != null)
|
||||
{
|
||||
@@ -246,7 +375,7 @@
|
||||
@@ -246,7 +383,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,7 +358,7 @@
|
||||
{
|
||||
if (this.currentChunkLoader != null)
|
||||
{
|
||||
@@ -254,15 +383,18 @@
|
||||
@@ -254,15 +391,18 @@
|
||||
{
|
||||
p_73242_1_.lastSaveTime = this.worldObj.getTotalWorldTime();
|
||||
this.currentChunkLoader.saveChunk(this.worldObj, p_73242_1_);
|
||||
@ -363,7 +378,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,6 +409,35 @@
|
||||
@@ -277,6 +417,35 @@
|
||||
if (this.currentChunkProvider != null)
|
||||
{
|
||||
this.currentChunkProvider.populate(p_73153_1_, p_73153_2_, p_73153_3_);
|
||||
@ -399,7 +414,7 @@
|
||||
GameRegistry.generateWorld(p_73153_2_, p_73153_3_, worldObj, currentChunkProvider, p_73153_1_);
|
||||
chunk.setChunkModified();
|
||||
}
|
||||
@@ -286,11 +447,13 @@
|
||||
@@ -286,11 +455,13 @@
|
||||
public boolean saveChunks(boolean p_73151_1_, IProgressUpdate p_73151_2_)
|
||||
{
|
||||
int i = 0;
|
||||
@ -416,7 +431,7 @@
|
||||
|
||||
if (p_73151_1_)
|
||||
{
|
||||
@@ -325,36 +488,73 @@
|
||||
@@ -325,36 +496,73 @@
|
||||
{
|
||||
if (!this.worldObj.levelSaving)
|
||||
{
|
||||
@ -509,7 +524,7 @@
|
||||
if (this.currentChunkLoader != null)
|
||||
{
|
||||
this.currentChunkLoader.chunkTick();
|
||||
@@ -371,7 +571,7 @@
|
||||
@@ -371,7 +579,7 @@
|
||||
|
||||
public String makeString()
|
||||
{
|
||||
@ -518,7 +533,7 @@
|
||||
}
|
||||
|
||||
public List getPossibleCreatures(EnumCreatureType p_73155_1_, int p_73155_2_, int p_73155_3_, int p_73155_4_)
|
||||
@@ -386,8 +586,30 @@
|
||||
@@ -386,8 +594,53 @@
|
||||
|
||||
public int getLoadedChunkCount()
|
||||
{
|
||||
@ -549,4 +564,27 @@
|
||||
+ return MinecraftServer.getServer().getTickCounter() - chunk.lastAccessedTick > CauldronConfig.chunkGCGracePeriod.getValue();
|
||||
+ }*/
|
||||
+ // Cauldron end
|
||||
+ // KCauldron start
|
||||
+ private final java.util.concurrent.locks.Lock generatorLock = new java.util.concurrent.locks.ReentrantLock();
|
||||
+
|
||||
+ public boolean loadAsync(int x, int z, boolean generateOnRequest, kcauldron.ChunkCallback callback) {
|
||||
+ Chunk chunk = getChunkIfLoaded(x, z);
|
||||
+ if (chunk != null) {
|
||||
+ callback.onChunkLoaded(chunk);
|
||||
+ } else if (((net.minecraft.world.chunk.storage.AnvilChunkLoader) currentChunkLoader).chunkExists(worldObj, x, z)) {
|
||||
+ net.minecraftforge.common.chunkio.ChunkIOExecutor.queueChunkLoad(this.worldObj,
|
||||
+ (net.minecraft.world.chunk.storage.AnvilChunkLoader) currentChunkLoader, this, x, z, callback);
|
||||
+ } else if (generateOnRequest) {
|
||||
+ callback.onChunkLoaded(originalLoadChunk(x, z));
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ public void loadAsync(int x, int z, kcauldron.ChunkCallback callback) {
|
||||
+ if (!loadAsync(x, z, false, callback))
|
||||
+ kcauldron.ChunkGenerator.INSTANCE.queueChunkGeneration(this, x, z, callback);
|
||||
+ }
|
||||
+ // KCauldron end
|
||||
}
|
||||
|
@ -1,6 +1,25 @@
|
||||
--- ../src-base/minecraft/net/minecraftforge/common/chunkio/ChunkIOExecutor.java
|
||||
+++ ../src-work/minecraft/net/minecraftforge/common/chunkio/ChunkIOExecutor.java
|
||||
@@ -22,7 +22,7 @@
|
||||
@@ -6,27 +6,57 @@
|
||||
static final int BASE_THREADS = 1;
|
||||
static final int PLAYERS_PER_THREAD = 50;
|
||||
|
||||
- private static final AsynchronousExecutor<QueuedChunk, net.minecraft.world.chunk.Chunk, Runnable, RuntimeException> instance = new AsynchronousExecutor<QueuedChunk, net.minecraft.world.chunk.Chunk, Runnable, RuntimeException>(new ChunkIOProvider(), BASE_THREADS);
|
||||
+ private static final AsynchronousExecutor<QueuedChunk, net.minecraft.world.chunk.Chunk, kcauldron.ChunkCallback, RuntimeException> instance = new AsynchronousExecutor<QueuedChunk, net.minecraft.world.chunk.Chunk, kcauldron.ChunkCallback, RuntimeException>(new ChunkIOProvider(), BASE_THREADS); // KCauldron
|
||||
|
||||
public static net.minecraft.world.chunk.Chunk syncChunkLoad(net.minecraft.world.World world, net.minecraft.world.chunk.storage.AnvilChunkLoader loader, net.minecraft.world.gen.ChunkProviderServer provider, int x, int z) {
|
||||
return instance.getSkipQueue(new QueuedChunk(x, z, loader, world, provider));
|
||||
}
|
||||
|
||||
public static void queueChunkLoad(net.minecraft.world.World world, net.minecraft.world.chunk.storage.AnvilChunkLoader loader, net.minecraft.world.gen.ChunkProviderServer provider, int x, int z, Runnable runnable) {
|
||||
- instance.add(new QueuedChunk(x, z, loader, world, provider), runnable);
|
||||
+ instance.add(new QueuedChunk(x, z, loader, world, provider), new RunnableCallback(runnable)); // KCauldron
|
||||
}
|
||||
|
||||
// Abuses the fact that hashCode and equals for QueuedChunk only use world and coords
|
||||
public static void dropQueuedChunkLoad(net.minecraft.world.World world, int x, int z, Runnable runnable) {
|
||||
- instance.drop(new QueuedChunk(x, z, null, world, null), runnable);
|
||||
+ instance.drop(new QueuedChunk(x, z, null, world, null), new RunnableCallback(runnable));
|
||||
}
|
||||
|
||||
public static void adjustPoolSize(int players) {
|
||||
@ -9,3 +28,37 @@
|
||||
instance.setActiveThreads(size);
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
instance.finishActive();
|
||||
}
|
||||
+
|
||||
+ // KCauldron start
|
||||
+ public static void queueChunkLoad(net.minecraft.world.World world,
|
||||
+ net.minecraft.world.chunk.storage.AnvilChunkLoader loader,
|
||||
+ net.minecraft.world.gen.ChunkProviderServer provider, int x, int z, kcauldron.ChunkCallback runnable) {
|
||||
+ instance.add(new QueuedChunk(x, z, loader, world, provider), runnable);
|
||||
+ }
|
||||
+
|
||||
+ public static final class RunnableCallback implements kcauldron.ChunkCallback {
|
||||
+ private final Runnable runnable;
|
||||
+
|
||||
+ public RunnableCallback(Runnable runnable) {
|
||||
+ this.runnable = runnable;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onChunkLoaded(net.minecraft.world.chunk.Chunk chunk) {
|
||||
+ runnable.run();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean equals(Object obj) {
|
||||
+ if (obj == this)
|
||||
+ return true;
|
||||
+ Runnable runnable = obj instanceof Runnable ? (Runnable) obj
|
||||
+ : obj instanceof RunnableCallback ? ((RunnableCallback) obj).runnable : null;
|
||||
+ return this.runnable == runnable;
|
||||
+ }
|
||||
+ }
|
||||
+ // KCauldron end
|
||||
}
|
||||
|
@ -1,16 +1,18 @@
|
||||
--- ../src-base/minecraft/net/minecraftforge/common/chunkio/ChunkIOProvider.java
|
||||
+++ ../src-work/minecraft/net/minecraftforge/common/chunkio/ChunkIOProvider.java
|
||||
@@ -9,6 +9,9 @@
|
||||
@@ -9,7 +9,10 @@
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
-class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChunk, net.minecraft.world.chunk.Chunk, Runnable, RuntimeException> {
|
||||
+import org.bukkit.Server;
|
||||
+import org.bukkit.craftbukkit.util.LongHash;
|
||||
+
|
||||
class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChunk, net.minecraft.world.chunk.Chunk, Runnable, RuntimeException> {
|
||||
+class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider<QueuedChunk, net.minecraft.world.chunk.Chunk, kcauldron.ChunkCallback, RuntimeException> {
|
||||
private final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||
|
||||
@@ -41,14 +44,36 @@
|
||||
// async stuff
|
||||
@@ -41,19 +44,41 @@
|
||||
queuedChunk.loader.loadEntities(queuedChunk.world, queuedChunk.compound.getCompoundTag("Level"), chunk);
|
||||
MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(chunk, queuedChunk.compound)); // Don't call ChunkDataEvent.Load async
|
||||
chunk.lastSaveTime = queuedChunk.provider.worldObj.getTotalWorldTime();
|
||||
@ -48,3 +50,10 @@
|
||||
chunk.populateChunk(queuedChunk.provider, queuedChunk.provider, queuedChunk.x, queuedChunk.z);
|
||||
}
|
||||
|
||||
- public void callStage3(QueuedChunk queuedChunk, net.minecraft.world.chunk.Chunk chunk, Runnable runnable) throws RuntimeException {
|
||||
- runnable.run();
|
||||
+ public void callStage3(QueuedChunk queuedChunk, net.minecraft.world.chunk.Chunk chunk, kcauldron.ChunkCallback callback) throws RuntimeException {
|
||||
+ callback.onChunkLoaded(chunk);
|
||||
}
|
||||
|
||||
public Thread newThread(Runnable runnable) {
|
||||
|
@ -0,0 +1,13 @@
|
||||
--- ../src-base/minecraft/net/minecraftforge/common/util/AsynchronousExecutor.java
|
||||
+++ ../src-work/minecraft/net/minecraftforge/common/util/AsynchronousExecutor.java
|
||||
@@ -268,8 +268,8 @@
|
||||
if (task == null) {
|
||||
// Print debug info for QueuedChunk and avoid crash
|
||||
//throw new IllegalStateException("Unknown " + parameter);
|
||||
- FMLLog.info("Unknown %s", parameter);
|
||||
- FMLLog.info("This should not happen. Please report this error to Forge.");
|
||||
+ //FMLLog.info("Unknown %s", parameter); // KCauldron
|
||||
+ //FMLLog.info("This should not happen. Please report this error to Forge."); // KCauldron
|
||||
return false;
|
||||
}
|
||||
if (!task.callbacks.remove(callback)) {
|
7
src/main/java/kcauldron/ChunkCallback.java
Normal file
7
src/main/java/kcauldron/ChunkCallback.java
Normal file
@ -0,0 +1,7 @@
|
||||
package kcauldron;
|
||||
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
|
||||
public interface ChunkCallback {
|
||||
void onChunkLoaded(Chunk chunk);
|
||||
}
|
96
src/main/java/kcauldron/ChunkGenerator.java
Normal file
96
src/main/java/kcauldron/ChunkGenerator.java
Normal file
@ -0,0 +1,96 @@
|
||||
package kcauldron;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Queues;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.LongHashMap;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.gen.ChunkProviderServer;
|
||||
|
||||
public enum ChunkGenerator {
|
||||
INSTANCE;
|
||||
private final Queue<QueuedChunk> queue = Queues.newArrayDeque();
|
||||
private final LongHashMap map = new LongHashMap();
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
public void queueChunkGeneration(ChunkProviderServer provider, int cx, int cz, ChunkCallback callback) {
|
||||
long key = ChunkCoordIntPair.chunkXZ2Int(cx, cz);
|
||||
QueuedChunk chunk;
|
||||
lock.readLock().lock();
|
||||
try {
|
||||
chunk = (QueuedChunk) map.getValueByKey(key);
|
||||
} finally {
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
if (chunk != null) {
|
||||
chunk.callbacks.add(callback);
|
||||
} else {
|
||||
chunk = new QueuedChunk(provider, cx, cz, callback);
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
map.add(key, chunk);
|
||||
queue.add(chunk);
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void chunkGeneratorCycle() {
|
||||
int max = MinecraftServer.kcauldronConfig.commonMaxChunkGenPerTick.getValue();
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
for (int i = 0; i < max && internalGenerate(); i++)
|
||||
;
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean generate() {
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
return internalGenerate();
|
||||
} finally {
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean internalGenerate() {
|
||||
for (QueuedChunk chunk; (chunk = queue.poll()) != null;) {
|
||||
map.remove(ChunkCoordIntPair.chunkXZ2Int(chunk.cx, chunk.cz));
|
||||
if (chunk.provider.loadAsync(chunk.cx, chunk.cz, false, chunk))
|
||||
continue;
|
||||
chunk.onChunkLoaded(chunk.provider.originalLoadChunk(chunk.cx, chunk.cz));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class QueuedChunk implements ChunkCallback {
|
||||
public final ChunkProviderServer provider;
|
||||
public final int cx;
|
||||
public final int cz;
|
||||
public final List<ChunkCallback> callbacks = Lists.newArrayListWithCapacity(1);
|
||||
|
||||
public QueuedChunk(ChunkProviderServer provider, int cx, int cz, ChunkCallback callback) {
|
||||
this.provider = provider;
|
||||
this.cx = cx;
|
||||
this.cz = cz;
|
||||
this.callbacks.add(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkLoaded(Chunk chunk) {
|
||||
for (ChunkCallback cb : callbacks)
|
||||
cb.onChunkLoaded(chunk);
|
||||
}
|
||||
}
|
||||
}
|
@ -36,6 +36,8 @@ public class KCauldronConfig extends ConfigBase {
|
||||
"common.fastLeavesDecay.minTickTime", 5, "Minimal amount of tick between block updates");
|
||||
public IntSetting commonFastLeavesDecayMaxTickTime = new IntSetting(this,
|
||||
"common.fastLeavesDecay.maxTickTime", 10, "Minimal amount of tick between block updates");
|
||||
public IntSetting commonMaxChunkGenPerTick = new IntSetting(this,
|
||||
"common.maxChunkGenPerTick", 1, "How many chunks generate during tick");
|
||||
|
||||
public BoolSetting experimentalTileEntityListRecreation = new BoolSetting(this,
|
||||
"experimental.tileEntityListRecreation", false, "EXPERIMENTAL! Recreate list of TE each tick.");
|
||||
|
Loading…
Reference in New Issue
Block a user