Added threading for building the biome grid.

This commit is contained in:
Harrison Deng 2020-04-29 13:11:07 -05:00
parent a102f53365
commit 14d0375c7e

View File

@ -1,6 +1,11 @@
package ca.recrown.islandsurvivalcraft.world.generation; package ca.recrown.islandsurvivalcraft.world.generation;
import java.util.LinkedList;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Material; import org.bukkit.Material;
@ -23,39 +28,57 @@ public class IslandWorldChunkGenerator extends ChunkGenerator implements Listene
private final Cache<Point2, Double> blockValueCache = new Cache<>(102400); private final Cache<Point2, Double> blockValueCache = new Cache<>(102400);
private final Cache<Point2, Biome[]> biomeCache = new Cache<>(102400); private final Cache<Point2, Biome[]> biomeCache = new Cache<>(102400);
private final Cache<Point2, Boolean> chunkExistenceCache = new Cache<>(16384); private final Cache<Point2, Boolean> chunkExistenceCache = new Cache<>(16384);
private final ExecutorService executor = Executors.newFixedThreadPool(2);
private volatile World currentWorld; private volatile World currentWorld;
@Override @Override
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) { public ChunkData generateChunkData(World world, Random random, int chunkX, int chunkZ, BiomeGrid biomeGrid) {
this.currentWorld = world; this.currentWorld = world;
IslandWorldMapper mapper = new IslandWorldMapper(random, blockValueCache); IslandWorldMapper mapper = new IslandWorldMapper(random, blockValueCache);
TemperatureMapGenerator temperatureMapGenerator = new TemperatureMapGenerator(world.getSeed()); TemperatureMapGenerator temperatureMapGenerator = new TemperatureMapGenerator(world.getSeed());
BiomeSelector biomeSelector = new BiomeSelector(random); BiomeSelector biomeSelector = new BiomeSelector(random);
biomeSelector.initialize(); biomeSelector.initialize();
WorldHeightShader heightShader = new WorldHeightShader(world.getSeed(), mapper, world.getSeaLevel(), world.getMaxHeight(), 3); WorldHeightShader heightShader = new WorldHeightShader(world.getSeed(), mapper, world.getSeaLevel(),
world.getMaxHeight(), 3);
BiomeGenerator biomeGenerator = new UniBiomeIslandGenerator(); BiomeGenerator biomeGenerator = new UniBiomeIslandGenerator();
int maxHeight = world.getMaxHeight(); int maxHeight = world.getMaxHeight();
LinkedList<Future<Boolean>> biomeColumns = new LinkedList<>();
ChunkData chunkData = createChunkData(world); ChunkData chunkData = createChunkData(world);
Biome[][] biomes = new Biome[Utilities.CHUNK_SIZE][Utilities.CHUNK_SIZE]; Biome[][] biomes = new Biome[Utilities.CHUNK_SIZE][Utilities.CHUNK_SIZE];
for (int localX = 0; localX < Utilities.CHUNK_SIZE; localX++) { for (int localX = 0; localX < Utilities.CHUNK_SIZE; localX++) {
for (int localZ = 0; localZ < Utilities.CHUNK_SIZE; localZ++) { for (int localZ = 0; localZ < Utilities.CHUNK_SIZE; localZ++) {
if (biomes[localX][localZ] == null) { if (biomes[localX][localZ] == null) {
biomeGenerator.generateBiomeColumn(biomes, world, x, z, localX, localZ, mapper, biomeSelector, temperatureMapGenerator, biomeCache, chunkExistenceCache); biomeGenerator.generateBiomeColumn(biomes, world, chunkX, chunkZ, localX, localZ, mapper, biomeSelector,
temperatureMapGenerator, biomeCache, chunkExistenceCache);
} }
if (biomes[localX][localZ] == null) throw new IllegalStateException("Biome was null."); if (biomes[localX][localZ] == null) throw new IllegalStateException("Biome was null.");
final int biomeX = localX;
final int biomeZ = localZ;
biomeColumns.add(executor.submit(() -> {
for (int y = 0; y < maxHeight; y++) { for (int y = 0; y < maxHeight; y++) {
biome.setBiome(x, y, z, biomes[localX][localZ]); biomeGrid.setBiome(biomeX, y, biomeZ, biomes[biomeX][biomeZ]);
} }
int worldX = 16 * x + localX; return true;
int worldZ = 16 * z + localZ; }));
int worldX = 16 * chunkX + localX;
int worldZ = 16 * chunkZ + localZ;
int height = heightShader.getAltitude(worldX, worldZ, biomes[localX][localZ]); int height = heightShader.getAltitude(worldX, worldZ, biomes[localX][localZ]);
chunkData.setRegion(localX, 1, localZ, localX+1, height, localZ+1, Material.DIAMOND_BLOCK); chunkData.setRegion(localX, 1, localZ, localX + 1, height, localZ + 1, Material.DIAMOND_BLOCK);
} }
} }
chunkData.setRegion(0, 0, 0, 16, 1, 16, Material.BEDROCK); chunkData.setRegion(0, 0, 0, 16, 1, 16, Material.BEDROCK);
while (!biomeColumns.isEmpty()) {
try {
biomeColumns.poll().get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
throw new IllegalStateException(e.getCause().getMessage());
}
}
return chunkData; return chunkData;
} }