Simplify chunkgenerationthread by putting the overly simple loading unloading outside it.

This commit is contained in:
IntegratedQuantum 2019-03-31 12:40:23 +02:00
parent 524e704e34
commit f7c07b4285
4 changed files with 34 additions and 58 deletions

View File

@ -392,7 +392,7 @@ public class Cubyz implements IGameLogic {
if (buildCooldown == 0) { if (buildCooldown == 0) {
buildCooldown = 10; buildCooldown = 10;
Vector3i pos = msd.getEmptyPlace(ctx.getCamera().getPosition()); Vector3i pos = msd.getEmptyPlace(ctx.getCamera().getPosition());
Block b = inventory.getBlock(inventorySelection); // TODO: add inventory Block b = inventory.getBlock(inventorySelection);
if (b != null && pos != null) { if (b != null && pos != null) {
world.placeBlock(pos.x, pos.y, pos.z, b); world.placeBlock(pos.x, pos.y, pos.z, b);
inventory.addBlock(b, -1); inventory.addBlock(b, -1);

View File

@ -36,7 +36,7 @@ public class RemoteWorld extends World {
public void removeBlock(int x, int y, int z) {} public void removeBlock(int x, int y, int z) {}
@Override @Override
public void queueChunk(ChunkAction action) { public void queueChunk(Chunk ch) {
// LOAD would be loading from server, UNLOAD would be unloading from client, and GENERATE would do nothing // LOAD would be loading from server, UNLOAD would be unloading from client, and GENERATE would do nothing
} }

View File

@ -32,29 +32,26 @@ public class LocalWorld extends World {
private ChunkGenerationThread thread; private ChunkGenerationThread thread;
private class ChunkGenerationThread extends Thread { private class ChunkGenerationThread extends Thread {
Deque<ChunkAction> loadList = new ArrayDeque<>(); // FIFO order (First In, First Out)
private static final int MAX_QUEUE_SIZE = 16; private static final int MAX_QUEUE_SIZE = 16;
Deque<Chunk> loadList = new ArrayDeque<>(MAX_QUEUE_SIZE); // FIFO order (First In, First Out)
public void queue(ChunkAction ca) { public void queue(Chunk ch) {
if (!isQueued(ca)) { if (!isQueued(ch)) {
if (loadList.size() > MAX_QUEUE_SIZE) { if (loadList.size() == MAX_QUEUE_SIZE) {
CubyzLogger.instance.info("Hang on, the Local-Chunk-Thread's queue is full, blocking!"); CubyzLogger.instance.info("Hang on, the Local-Chunk-Thread's queue is full, blocking!");
while (!loadList.isEmpty()) { while (!loadList.isEmpty()) {
System.out.print(""); // again, used as replacement to Thread.onSpinWait(), also necessary due to some JVM oddities System.out.print(""); // again, used as replacement to Thread.onSpinWait(), also necessary due to some JVM oddities
} }
} }
loadList.add(ca); loadList.add(ch);
} }
} }
public boolean isQueued(ChunkAction ca) { public boolean isQueued(Chunk ch) {
ChunkAction[] list = loadList.toArray(new ChunkAction[0]); Chunk[] list = loadList.toArray(new Chunk[0]);
for (ChunkAction ch : list) { for (Chunk ch2 : list) {
if (ch != null) { if (ch2 == ch) {
if (ch.chunk == ca.chunk) { return true;
ch.type = ca.type;
return true;
}
} }
} }
return false; return false;
@ -63,23 +60,11 @@ public class LocalWorld extends World {
public void run() { public void run() {
while (true) { while (true) {
if (!loadList.isEmpty()) { if (!loadList.isEmpty()) {
ChunkAction popped = loadList.pop(); Chunk popped = loadList.pop();
if (popped.type == ChunkActionType.GENERATE) { // CubyzLogger.instance.fine("Generating " + popped.chunk.getX() + "," + popped.chunk.getZ());
// CubyzLogger.instance.fine("Generating " + popped.chunk.getX() + "," + popped.chunk.getZ()); synchronousGenerate(popped);
synchronousGenerate(popped.chunk); popped.load();
popped.chunk.load(); //seed = (int) System.currentTimeMillis(); // enable it if you want fun (don't forget to disable before commit!!!)
//seed = (int) System.currentTimeMillis(); // enable it if you want fun (don't forget to disable before commit!!!)
}
else if (popped.type == ChunkActionType.LOAD) {
// CubyzLogger.instance.fine("\"Loading\" " + popped.chunk.getX() + "," + popped.chunk.getZ());
if(!popped.chunk.isLoaded()) {
popped.chunk.setLoaded(true);
}
}
else if (popped.type == ChunkActionType.UNLOAD) {
// CubyzLogger.instance.fine("\"Unloading\" " + popped.chunk.getX() + "," + popped.chunk.getZ());
popped.chunk.setLoaded(false);
}
} }
System.out.print(""); System.out.print("");
} }
@ -238,28 +223,29 @@ public class LocalWorld extends World {
} }
@Override @Override
public void queueChunk(ChunkAction action) { public void queueChunk(Chunk ch) {
thread.queue(action); thread.queue(ch);
} }
@Override @Override
public void seek(int x, int z) { public void seek(int x, int z) {
int renderDistance/*minus 1*/ = 4; int renderDistance = 5;
int blockDistance = renderDistance*16; int blockDistance = renderDistance << 4;
for (int x1 = x - blockDistance-48; x1 <= x + blockDistance+48; x1 += 16) { int minX = x-blockDistance; // Avoid
for (int z1 = z - blockDistance-48; z1 <= z + blockDistance+48; z1 += 16) { int maxX = x+blockDistance; // recalculating
int minZ = z-blockDistance; // them
int maxZ = z+blockDistance; // .
for (int x1 = minX-48; x1 <= maxX+48; x1 += 16) {
for (int z1 = minZ-48; z1 <= maxZ+48; z1 += 16) {
Chunk ch = getChunk(x1/16,z1/16); Chunk ch = getChunk(x1/16,z1/16);
if (x1>x-blockDistance&&x1<x+blockDistance&&z1>z-blockDistance&&z1<z+blockDistance && !ch.isLoaded()) { if (!ch.isLoaded() && x1 > minX && x1 < maxX && z1 > minZ && z1 < maxZ) {
if (!ch.isGenerated()) { if (!ch.isGenerated()) {
queueChunk(new ChunkAction(ch, ChunkActionType.GENERATE)); queueChunk(ch);
} } else {
else { ch.setLoaded(true);
queueChunk(new ChunkAction(ch, ChunkActionType.LOAD));
}
} else if (x1 < x-blockDistance - 16 || x1 > x + blockDistance + 16 || z1 < z - blockDistance - 16 || z1 > z + blockDistance +16) {
if (ch.isLoaded()) {
queueChunk(new ChunkAction(ch, ChunkActionType.UNLOAD));
} }
} else if (ch.isLoaded() && (x1 < minX || x1 > maxX || z1 < minZ || z1 > maxZ)) {
ch.setLoaded(false);
} }
} }
} }

View File

@ -33,16 +33,6 @@ public abstract class World {
UNLOAD; UNLOAD;
} }
public static class ChunkAction {
public Chunk chunk;
public ChunkActionType type;
public ChunkAction(Chunk chunk, ChunkActionType type) {
this.chunk = chunk;
this.type = type;
}
}
public abstract Player getLocalPlayer(); public abstract Player getLocalPlayer();
public int getHeight() { public int getHeight() {
@ -60,7 +50,7 @@ public abstract class World {
* *
* @param action - Chunk action * @param action - Chunk action
*/ */
public abstract void queueChunk(ChunkAction action); public abstract void queueChunk(Chunk ch);
public abstract Chunk getChunk(int x, int z); public abstract Chunk getChunk(int x, int z);
public abstract BlockInstance getBlock(int x, int y, int z); public abstract BlockInstance getBlock(int x, int y, int z);