Some checks failed
studiorailgun/Renderer/pipeline/pr-master There was a failure building this commit
137 lines
3.9 KiB
Java
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);
|
|
}
|
|
}
|
|
|
|
}
|