cache biome providers on Bukkit

This commit is contained in:
dfsek
2022-06-17 17:39:27 -07:00
parent 4dd43ea86d
commit 915dcf9b9b
3 changed files with 48 additions and 11 deletions

View File

@@ -17,11 +17,13 @@
package com.dfsek.terra.bukkit.generator;
import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
import com.dfsek.terra.api.world.biome.generation.ChunkLocalCachingBiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
import org.bukkit.Location;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.LimitedRegion;
@@ -49,6 +51,31 @@ public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGener
private final BlockState air;
private ChunkGenerator delegate;
private ConfigPack pack;
private final LoadingCache<SeededVector, ChunkLocalCachingBiomeProvider> biomeProviderCache = CacheBuilder.newBuilder()
.maximumSize(128)
.build(new CacheLoader<>() {
@Override
public @NotNull ChunkLocalCachingBiomeProvider load(@NotNull SeededVector key) {
return pack.getBiomeProvider().caching(key.worldProperties, key.x, key.z);
}
});
private record SeededVector(int x, int z, WorldProperties worldProperties) {
@Override
public boolean equals(Object obj) {
if(obj instanceof SeededVector that) {
return this.z == that.z && this.x == that.x && this.worldProperties.equals(that.worldProperties);
}
return false;
}
@Override
public int hashCode() {
int code = x;
code = 31 * code + z;
return 31 * code + worldProperties.hashCode();
}
}
public BukkitChunkGeneratorWrapper(ChunkGenerator delegate, ConfigPack pack, BlockState air) {
this.delegate = delegate;
@@ -68,7 +95,7 @@ public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGener
@Override
public void generateNoise(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z, @NotNull ChunkData chunkData) {
BukkitWorldProperties properties = new BukkitWorldProperties(worldInfo);
delegate.generateChunkData(new BukkitProtoChunk(chunkData), properties, pack.getBiomeProvider().caching(properties), x, z);
delegate.generateChunkData(new BukkitProtoChunk(chunkData), properties, biomeProviderCache.getUnchecked(new SeededVector(x, z, new BukkitWorldProperties(worldInfo))), x, z);
}
@Override
@@ -79,7 +106,7 @@ public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGener
@Override
public void populate(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z,
@NotNull LimitedRegion limitedRegion) {
generationStage.populate(new BukkitProtoWorld(limitedRegion, air));
generationStage.populate(new BukkitProtoWorld(limitedRegion, air, biomeProviderCache.getUnchecked(new SeededVector(x, z, new BukkitWorldProperties(worldInfo)))));
}
})
.collect(Collectors.toList());

View File

@@ -1,7 +1,5 @@
package com.dfsek.terra.bukkit.world;
import com.dfsek.terra.api.util.generic.Lazy;
import com.dfsek.terra.api.world.biome.generation.ChunkLocalCachingBiomeProvider;
import org.bukkit.Location;
@@ -35,13 +33,12 @@ public class BukkitProtoWorld implements ProtoWorld {
private final LimitedRegion delegate;
private final BlockState air;
private final ChunkLocalCachingBiomeProvider biomeProvider;
private final BiomeProvider biomeProvider;
public BukkitProtoWorld(LimitedRegion delegate, BlockState air) {
public BukkitProtoWorld(LimitedRegion delegate, BlockState air, BiomeProvider provider) {
this.delegate = delegate;
this.air = air;
this.biomeProvider = ((BukkitChunkGeneratorWrapper) delegate.getWorld().getGenerator()).getPack().getBiomeProvider().caching(new BukkitWorldProperties(
delegate.getWorld()), delegate.getCenterChunkX(), delegate.getCenterChunkZ());
this.biomeProvider = provider;
}
@Override

View File

@@ -31,4 +31,17 @@ public class BukkitWorldProperties implements WorldProperties {
public int getMinHeight() {
return delegate.getMinHeight();
}
@Override
public int hashCode() {
return delegate.hashCode();
}
@Override
public boolean equals(Object obj) {
if(obj instanceof WorldProperties that) {
return this.delegate.equals(that.getHandle());
}
return false;
}
}