Fix AbstractEnormousPlacement doesnt separate caches for different dimensions

This commit is contained in:
DBotThePony 2025-03-09 12:42:28 +07:00
parent 45d7b30b8a
commit 274b5c059a
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.worldgen.placement
import com.github.benmanes.caffeine.cache.Cache
import com.github.benmanes.caffeine.cache.Caffeine
import com.github.benmanes.caffeine.cache.Scheduler
import com.mojang.serialization.Codec
@ -11,6 +12,8 @@ import net.minecraft.core.BlockPos
import net.minecraft.core.SectionPos
import net.minecraft.util.RandomSource
import net.minecraft.world.level.ChunkPos
import net.minecraft.world.level.Level
import net.minecraft.world.level.WorldGenLevel
import net.minecraft.world.level.levelgen.placement.PlacementContext
import net.minecraft.world.level.levelgen.placement.PlacementModifier
import ru.dbotthepony.kommons.util.XXHash64
@ -19,7 +22,11 @@ import ru.dbotthepony.mc.otm.data.codec.minRange
import ru.dbotthepony.mc.otm.worldgen.placement.AbstractEnormousPlacement.Parameters
import java.io.DataOutputStream
import java.time.Duration
import java.util.Collections
import java.util.WeakHashMap
import java.util.concurrent.locks.ReentrantLock
import java.util.stream.Stream
import kotlin.concurrent.withLock
import kotlin.math.sqrt
/**
@ -73,13 +80,22 @@ abstract class AbstractEnormousPlacement(val parameters: Parameters) : Placement
protected abstract fun getPositions(center: BlockPos, random: RandomSource): Stream<BlockPos>
private val chunkCache = Caffeine.newBuilder()
.scheduler(Scheduler.systemScheduler())
.executor(Util.backgroundExecutor())
.maximumSize(16384L)
.expireAfterWrite(Duration.ofMinutes(5))
.softValues()
.build<ChunkPos, GeneratedChunk>()
private val level2cache = WeakHashMap<WorldGenLevel, Cache<ChunkPos, GeneratedChunk>>()
private val lock = ReentrantLock()
private fun getCache(level: WorldGenLevel): Cache<ChunkPos, GeneratedChunk> {
return lock.withLock {
level2cache.computeIfAbsent(level) {
Caffeine.newBuilder()
.scheduler(Scheduler.systemScheduler())
.executor(Util.backgroundExecutor())
.maximumSize(16384L)
.expireAfterWrite(Duration.ofMinutes(5))
.softValues()
.build()
}
}
}
private fun computeChunk(context: PlacementContext, pos: ChunkPos): GeneratedChunk {
val bytes = FastByteArrayOutputStream()
@ -113,7 +129,7 @@ abstract class AbstractEnormousPlacement(val parameters: Parameters) : Placement
if (radius <= parameters.chunkScanRange) {
val thisPos = ChunkPos(cPos.x + x, cPos.z + z)
instances.add(chunkCache.get(thisPos) { computeChunk(context, thisPos) })
instances.add(getCache(context.level).get(thisPos) { computeChunk(context, thisPos) })
}
}
}