Renderer/src/main/java/electrosphere/server/terrain/manager/ChunkGenerationThread.java
austin 22e468a6d0
Some checks failed
studiorailgun/Renderer/pipeline/pr-master There was a failure building this commit
remove first chunk special gen
2024-11-07 14:44:55 -05:00

137 lines
3.9 KiB
Java

package electrosphere.server.terrain.manager;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import electrosphere.engine.Globals;
import electrosphere.logger.LoggerInterface;
import electrosphere.server.terrain.diskmap.ChunkDiskMap;
import electrosphere.server.terrain.generation.interfaces.ChunkGenerator;
/**
* A job that fetches a chunk, either by generating it or by reading it from disk
*/
public class ChunkGenerationThread implements Runnable {
/**
* The number of milliseconds to wait per iteration
*/
static final int WAIT_TIME_MS = 2;
/**
* The maximum number of iterations to wait before failing
*/
static final int MAX_TIME_TO_WAIT = 10;
/**
* The chunk disk map
*/
ChunkDiskMap chunkDiskMap;
/**
* The chunk cache on the server
*/
ServerChunkCache chunkCache;
/**
* The chunk generator
*/
ChunkGenerator chunkGenerator;
/**
* The world x coordinate
*/
int worldX;
/**
* The world y coordinate
*/
int worldY;
/**
* The world z coordinate
*/
int worldZ;
/**
* The stride of the data
*/
int stride;
/**
* The work to do once the chunk is available
*/
Consumer<ServerTerrainChunk> onLoad;
/**
* Creates the chunk generation job
* @param chunkDiskMap The chunk disk map
* @param chunkCache The chunk cache on the server
* @param chunkGenerator The chunk generator
* @param worldX The world x coordinate
* @param worldY The world y coordinate
* @param worldZ The world z coordinate
* @param stride The stride of the data
* @param onLoad The work to do once the chunk is available
*/
public ChunkGenerationThread(
ChunkDiskMap chunkDiskMap,
ServerChunkCache chunkCache,
ChunkGenerator chunkGenerator,
int worldX, int worldY, int worldZ,
int stride,
Consumer<ServerTerrainChunk> onLoad
){
this.chunkDiskMap = chunkDiskMap;
this.chunkCache = chunkCache;
this.chunkGenerator = chunkGenerator;
this.worldX = worldX;
this.worldY = worldY;
this.worldZ = worldZ;
this.stride = stride;
this.onLoad = onLoad;
}
@Override
public void run() {
ServerTerrainChunk chunk = null;
int i = 0;
try {
while(chunk == null && i < MAX_TIME_TO_WAIT && Globals.threadManager.shouldKeepRunning()){
if(chunkCache.containsChunk(worldX, worldY, worldZ, stride)){
chunk = chunkCache.get(worldX, worldY, worldZ, stride);
} else {
//pull from disk if it exists
if(chunkDiskMap != null){
if(chunkDiskMap.containsTerrainAtPosition(worldX, worldY, worldZ)){
chunk = chunkDiskMap.getTerrainChunk(worldX, worldY, worldZ);
}
}
//generate if it does not exist
if(chunk == null){
chunk = chunkGenerator.generateChunk(worldX, worldY, worldZ, stride);
}
if(chunk != null){
chunkCache.add(worldX, worldY, worldZ, stride, chunk);
}
}
if(chunk == null){
try {
TimeUnit.MILLISECONDS.sleep(WAIT_TIME_MS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i++;
}
if(i >= MAX_TIME_TO_WAIT){
throw new Error("Failed to resolve chunk!");
}
this.onLoad.accept(chunk);
} catch (Error e){
LoggerInterface.loggerEngine.ERROR(e);
}
}
}