Improve enhanced placed feature performance
This commit is contained in:
parent
e2369b3a24
commit
7a5a979169
@ -3,13 +3,11 @@ package ru.dbotthepony.mc.otm.worldgen
|
|||||||
import com.github.benmanes.caffeine.cache.Cache
|
import com.github.benmanes.caffeine.cache.Cache
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine
|
import com.github.benmanes.caffeine.cache.Caffeine
|
||||||
import com.github.benmanes.caffeine.cache.Scheduler
|
import com.github.benmanes.caffeine.cache.Scheduler
|
||||||
import com.mojang.datafixers.util.Either
|
|
||||||
import com.mojang.datafixers.util.Pair
|
|
||||||
import com.mojang.serialization.Codec
|
import com.mojang.serialization.Codec
|
||||||
import com.mojang.serialization.DataResult
|
|
||||||
import com.mojang.serialization.DynamicOps
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder
|
import com.mojang.serialization.codecs.RecordCodecBuilder
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap
|
||||||
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
import it.unimi.dsi.fastutil.io.FastByteArrayOutputStream
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet
|
import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet
|
||||||
import net.minecraft.Util
|
import net.minecraft.Util
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
@ -23,15 +21,16 @@ import net.minecraft.world.level.levelgen.feature.Feature
|
|||||||
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext
|
import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext
|
||||||
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration
|
import net.minecraft.world.level.levelgen.feature.configurations.FeatureConfiguration
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature
|
import net.minecraft.world.level.levelgen.placement.PlacedFeature
|
||||||
import net.minecraft.world.level.levelgen.placement.PlacementModifier
|
|
||||||
import ru.dbotthepony.kommons.util.XXHash64
|
import ru.dbotthepony.kommons.util.XXHash64
|
||||||
|
import ru.dbotthepony.mc.otm.THREAD_LOCAL_RANDOM
|
||||||
|
import ru.dbotthepony.mc.otm.core.shuffle
|
||||||
import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource
|
import ru.dbotthepony.mc.otm.core.util.GJRAND64RandomSource
|
||||||
import ru.dbotthepony.mc.otm.data.codec.minRange
|
import ru.dbotthepony.mc.otm.data.codec.minRange
|
||||||
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
import ru.dbotthepony.mc.otm.worldgen.feature.EnhancedFeature
|
||||||
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacement
|
import ru.dbotthepony.mc.otm.worldgen.placement.EnhancedPlacement
|
||||||
import java.io.DataOutputStream
|
import java.io.DataOutputStream
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.LinkedList
|
import java.util.*
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
||||||
@ -137,7 +136,7 @@ object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
|||||||
fun place(context: FeaturePlaceContext<*>): Boolean {
|
fun place(context: FeaturePlaceContext<*>): Boolean {
|
||||||
val cache = getCache(context.level())
|
val cache = getCache(context.level())
|
||||||
val chunkPos = ChunkPos(context.origin())
|
val chunkPos = ChunkPos(context.origin())
|
||||||
val instances = ArrayList<GeneratedChunk>()
|
val chunkPositions = ArrayList<ChunkPos>()
|
||||||
|
|
||||||
for (x in -chunkScanRange .. chunkScanRange) {
|
for (x in -chunkScanRange .. chunkScanRange) {
|
||||||
for (z in -chunkScanRange .. chunkScanRange) {
|
for (z in -chunkScanRange .. chunkScanRange) {
|
||||||
@ -146,13 +145,24 @@ object EnhancedPlacedFeature : Feature<EnhancedPlacedFeature.Config>(
|
|||||||
|
|
||||||
if (radius <= chunkScanRange) {
|
if (radius <= chunkScanRange) {
|
||||||
val thisPos = ChunkPos(chunkPos.x + x, chunkPos.z + z)
|
val thisPos = ChunkPos(chunkPos.x + x, chunkPos.z + z)
|
||||||
instances.add(cache.get(thisPos) { evaluate(context, thisPos) })
|
chunkPositions.add(thisPos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val withIndex = ObjectArrayList(chunkPositions.withIndex().iterator())
|
||||||
|
// evaluate chunks in random order, so in multithreaded environments we experience less congestion
|
||||||
|
// between threads which lookup cache while it is being populated on neighbouring chunks
|
||||||
|
withIndex.shuffle(THREAD_LOCAL_RANDOM)
|
||||||
|
|
||||||
|
val instances = Int2ObjectRBTreeMap<GeneratedChunk>()
|
||||||
|
|
||||||
|
withIndex.forEach { (i, it) ->
|
||||||
|
instances.put(i, cache.get(it) { evaluate(context, it) })
|
||||||
|
}
|
||||||
|
|
||||||
var any = false
|
var any = false
|
||||||
instances.forEach { any = it.place(context) }
|
instances.values.forEach { any = it.place(context) }
|
||||||
return any
|
return any
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user