Cap chunk generation to 1 chunk per tick (configurable)
This commit is contained in:
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.");
|
||||
|
Reference in New Issue
Block a user