Revert to "Island world chunk generator now pre-generates island values."
This reverts commit e40bf74cb8.
			
			
This commit is contained in:
		| @@ -1,13 +1,17 @@ | ||||
| package ca.recrown.islandsurvivalcraft.caching; | ||||
|  | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| import java.util.concurrent.locks.ReentrantLock; | ||||
| import java.util.concurrent.locks.ReentrantReadWriteLock; | ||||
| import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; | ||||
| import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; | ||||
|  | ||||
| public class Cache<K, V> { | ||||
|     private final int maxSize; | ||||
|     private final ConcurrentHashMap<K, CacheValue<K, V>> data; | ||||
|     private final UsageStack<K, V> usage = new UsageStack<>(); | ||||
|     private final ReentrantLock lock = new ReentrantLock(); | ||||
|     private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); | ||||
|     private final WriteLock writeLock = lock.writeLock(); | ||||
|     private final ReadLock readLock = lock.readLock(); | ||||
|  | ||||
|     public Cache(int maxSize) { | ||||
|         data = new ConcurrentHashMap<>(maxSize + 1, 0.75f, 6); | ||||
| @@ -29,7 +33,7 @@ public class Cache<K, V> { | ||||
|         if (data.containsKey(key)) { | ||||
|             data.get(key).value = value; | ||||
|         } else { | ||||
|             lock.lock(); | ||||
|             writeLock.lock(); | ||||
|             try { | ||||
|                 CacheValue<K, V> val = new CacheValue<>(); | ||||
|                 val.key = key; | ||||
| @@ -40,7 +44,7 @@ public class Cache<K, V> { | ||||
|                     data.remove(usage.pop().key); | ||||
|                 } | ||||
|             } finally { | ||||
|                 lock.unlock(); | ||||
|                 writeLock.unlock(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -53,9 +57,15 @@ public class Cache<K, V> { | ||||
|      * @return the value associated to the key. | ||||
|      */ | ||||
|     public V get(K key) { | ||||
|         CacheValue<K, V> value = data.get(key); | ||||
|         if (value == null) return null; | ||||
|         usage.tryMoveToTop(value); | ||||
|         readLock.lock(); | ||||
|         CacheValue<K, V> value = null; | ||||
|         try { | ||||
|             if (!data.containsKey(key)) return null; | ||||
|             value = data.get(key); | ||||
|             usage.tryMoveToTop(value); | ||||
|         } finally { | ||||
|             readLock.unlock(); | ||||
|         } | ||||
|         return value.value; | ||||
|     } | ||||
|  | ||||
| @@ -63,12 +73,12 @@ public class Cache<K, V> { | ||||
|      * Clears the cache of all values. | ||||
|      */ | ||||
|     public void clearCache() { | ||||
|         lock.lock(); | ||||
|         writeLock.lock(); | ||||
|         try { | ||||
|             data.clear(); | ||||
|             usage.clear(); | ||||
|         } finally { | ||||
|             lock.unlock(); | ||||
|             writeLock.unlock(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -4,6 +4,7 @@ import java.util.LinkedList; | ||||
| 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; | ||||
| @@ -27,83 +28,60 @@ public class IslandWorldChunkGenerator extends ChunkGenerator implements Listene | ||||
|     private final Cache<Point2, Double> blockValueCache = new Cache<>(102400); | ||||
|     private final Cache<Point2, Biome[]> biomeCache = new Cache<>(102400); | ||||
|     private final Cache<Point2, Boolean> chunkExistenceCache = new Cache<>(16384); | ||||
|     private final BiomeSelector biomeSelector = new BiomeSelector(); | ||||
|     private final ExecutorService executor = Utilities.ISC_EXECUTOR; | ||||
|     private volatile World currentWorld; | ||||
|  | ||||
|     public IslandWorldChunkGenerator() { | ||||
|         biomeSelector.initialize(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public ChunkData generateChunkData(World world, Random random, int chunkX, int chunkZ, BiomeGrid biomeGrid) { | ||||
|         this.currentWorld = world; | ||||
|         IslandWorldMapper mapper = new IslandWorldMapper(random, blockValueCache); | ||||
|         TemperatureMapGenerator temperatureMapGenerator = new TemperatureMapGenerator(world.getSeed()); | ||||
|         WorldHeightShader heightShader = new WorldHeightShader(world.getSeed(), mapper, world.getSeaLevel(), world.getMaxHeight(), 3); | ||||
|         BiomeSelector biomeSelector = new BiomeSelector(random); | ||||
|         biomeSelector.initialize(); | ||||
|         WorldHeightShader heightShader = new WorldHeightShader(world.getSeed(), mapper, world.getSeaLevel(), | ||||
|                 world.getMaxHeight(), 3); | ||||
|         BiomeGenerator biomeGenerator = new UniBiomeIslandGenerator(); | ||||
|  | ||||
|         int maxHeight = world.getMaxHeight(); | ||||
|         LinkedList<Future<Boolean>> tasks = new LinkedList<>(); | ||||
|         ChunkData chunkData = createChunkData(world); | ||||
|         Future<Boolean> preLoader = executor.submit(() -> { | ||||
|             for (int x = 0; x < Utilities.CHUNK_SIZE; x++) { | ||||
|                 for (int z = 0; z < Utilities.CHUNK_SIZE; z++) { | ||||
|                     if (Thread.currentThread().isInterrupted()) return false; | ||||
|                     mapper.getWorldBlockValue(Utilities.CHUNK_SIZE * chunkX + x, Utilities.CHUNK_SIZE * chunkZ + z); | ||||
|                 } | ||||
|             } | ||||
|             return true; | ||||
|         }); | ||||
|  | ||||
|         Biome[][] biomes = new Biome[Utilities.CHUNK_SIZE][Utilities.CHUNK_SIZE]; | ||||
|         for (int x = 0; x < Utilities.CHUNK_SIZE; x++) { | ||||
|             for (int z = 0; z < Utilities.CHUNK_SIZE; z++) { | ||||
|                 final int desX = x; | ||||
|                 final int desZ = z; | ||||
|                 if (biomes[desX][desZ] == null) { | ||||
|                     biomeGenerator.generateBiomeColumn(biomes, world, chunkX, chunkZ, desX, desZ, mapper, biomeSelector, | ||||
|         for (int localX = 0; localX < Utilities.CHUNK_SIZE; localX++) { | ||||
|             for (int localZ = 0; localZ < Utilities.CHUNK_SIZE; localZ++) { | ||||
|                 if (biomes[localX][localZ] == null) { | ||||
|                     biomeGenerator.generateBiomeColumn(biomes, world, chunkX, chunkZ, localX, localZ, mapper, biomeSelector, | ||||
|                             temperatureMapGenerator, biomeCache, chunkExistenceCache); | ||||
|                 } | ||||
|                  | ||||
|                 if (biomes[desX][desZ] == 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; | ||||
|                 tasks.add(executor.submit(() -> { | ||||
|                     for (int y = 0; y < maxHeight; y++) { | ||||
|                         biomeGrid.setBiome(desX, y, desZ, biomes[desX][desZ]); | ||||
|                         biomeGrid.setBiome(biomeX, y, biomeZ, biomes[biomeX][biomeZ]); | ||||
|                     } | ||||
|                     return true; | ||||
|                 })); | ||||
|  | ||||
|                 final int worldX = Utilities.CHUNK_SIZE * chunkX + desX; | ||||
|                 final int worldZ = Utilities.CHUNK_SIZE * chunkZ + desZ; | ||||
|                 int height = heightShader.getAltitude(worldX, worldZ, biomes[desX][desZ]); | ||||
|                 chunkData.setRegion(desX, 1, desZ, desX + 1, height, desZ + 1, Material.DIAMOND_BLOCK); | ||||
|                 final int worldX = 16 * chunkX + localX; | ||||
|                 final int worldZ = 16 * chunkZ + 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(0, 0, 0, 16, 1, 16, Material.BEDROCK); | ||||
|  | ||||
|         preLoader.cancel(true); | ||||
|         try { | ||||
|             while (!tasks.isEmpty()) { | ||||
|         while (!tasks.isEmpty()) { | ||||
|             try { | ||||
|                 tasks.poll().get(); | ||||
|             } catch (ExecutionException | InterruptedException e) { | ||||
|                 e.printStackTrace(); | ||||
|                 throw new IllegalStateException(e.getCause().getMessage()); | ||||
|             } | ||||
|         } catch (ExecutionException | InterruptedException e) { | ||||
|             e.printStackTrace(); | ||||
|             throw new IllegalStateException(e.getCause().getMessage()); | ||||
|         } | ||||
|         return chunkData; | ||||
|     } | ||||
|      | ||||
|     @Override | ||||
|     public boolean canSpawn(World world, int x, int z) { | ||||
|         return super.canSpawn(world, x, z); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean isParallelCapable() { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @EventHandler(priority = EventPriority.MONITOR) | ||||
|     public void onChunkLoaded(ChunkLoadEvent event) { | ||||
|         if (event.isNewChunk()) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user