diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt index 7d379e4e..9a30e428 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt @@ -116,7 +116,7 @@ fun main() { val rand = Random() - for (i in 0 .. 128) { + for (i in 0 until 0) { val item = ItemEntity(client.world!!, Registries.items.keys.values.random().value) item.position = Vector2d(225.0 - i, 785.0) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt index 8f19fc62..c9cb3d3a 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/client/StarboundClient.kt @@ -613,7 +613,7 @@ class StarboundClient : Closeable { } val tileRenderers = TileRenderers(this) - var world: ClientWorld? = ClientWorld(this, 0L, Vector2i(3000, 2000), true) + var world: ClientWorld? = ClientWorld(this, 0L, Vector2i(16000, 8000), true) init { clearColor = RGBAColor.SLATE_GRAY diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/util/HashTableInterner.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/util/HashTableInterner.kt index be56ad6d..d6fdafb2 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/util/HashTableInterner.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/util/HashTableInterner.kt @@ -9,11 +9,13 @@ import java.lang.ref.WeakReference import java.util.concurrent.locks.LockSupport import java.util.concurrent.locks.ReentrantLock import kotlin.concurrent.withLock +import kotlin.math.log +import kotlin.math.roundToInt // hand-rolled interner, which has similar performance to ConcurrentHashMap // (given there is no strong congestion, otherwise it performs somewhere above Caffeine interner), // while yielding significantly better memory utilization than both -class HashTableInterner(private val segmentBits: Int) : Interner { +class HashTableInterner(private val segmentBits: Int = log(Runtime.getRuntime().availableProcessors().toDouble(), 2.0).roundToInt().coerceAtLeast(4)) : Interner { companion object { private val interners = ArrayList>>() diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/AbstractCell.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/AbstractCell.kt index 6d63a2e4..5ad2ea27 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/AbstractCell.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/AbstractCell.kt @@ -1,5 +1,7 @@ package ru.dbotthepony.kstarbound.world.api +import com.github.benmanes.caffeine.cache.Interner +import ru.dbotthepony.kstarbound.util.HashTableInterner import java.io.DataInputStream sealed class AbstractCell { @@ -23,7 +25,10 @@ sealed class AbstractCell { stream.skipNBytes(1 + 2 + 1 + 1 + 1 + 1) } - val EMPTY = ImmutableCell(AbstractTileState.EMPTY, AbstractTileState.EMPTY, AbstractLiquidState.EMPTY, 0, 0, 0, false) - val NULL = ImmutableCell(AbstractTileState.NULL, AbstractTileState.NULL, AbstractLiquidState.EMPTY, 0, 0, 0, false) + @JvmStatic + protected val POOL: Interner = HashTableInterner() + + val EMPTY: ImmutableCell = POOL.intern(ImmutableCell(AbstractTileState.EMPTY, AbstractTileState.EMPTY, AbstractLiquidState.EMPTY, 0, 0, 0, false)) + val NULL: ImmutableCell = POOL.intern(ImmutableCell(AbstractTileState.NULL, AbstractTileState.NULL, AbstractLiquidState.EMPTY, 0, 0, 0, false)) } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/AbstractTileState.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/AbstractTileState.kt index 85ba8f17..83ae20b0 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/AbstractTileState.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/AbstractTileState.kt @@ -1,9 +1,11 @@ package ru.dbotthepony.kstarbound.world.api +import com.github.benmanes.caffeine.cache.Interner import ru.dbotthepony.kstarbound.Registry import ru.dbotthepony.kstarbound.defs.tile.BuiltinMetaMaterials import ru.dbotthepony.kstarbound.defs.tile.MaterialModifier import ru.dbotthepony.kstarbound.defs.tile.TileDefinition +import ru.dbotthepony.kstarbound.util.HashTableInterner import java.io.DataInputStream sealed class AbstractTileState { @@ -21,7 +23,10 @@ sealed class AbstractTileState { stream.skipNBytes(2 + 1 + 1 + 2 + 1) } - val EMPTY = ImmutableTileState(BuiltinMetaMaterials.EMPTY) - val NULL = ImmutableTileState(BuiltinMetaMaterials.NULL) + @JvmStatic + protected val POOL: Interner = HashTableInterner() + + val EMPTY: ImmutableTileState = POOL.intern(ImmutableTileState(BuiltinMetaMaterials.EMPTY)) + val NULL: ImmutableTileState = POOL.intern(ImmutableTileState(BuiltinMetaMaterials.NULL)) } } diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/MutableCell.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/MutableCell.kt index 2b4266d3..9f7f7614 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/MutableCell.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/MutableCell.kt @@ -29,10 +29,7 @@ data class MutableCell( } override fun immutable(): ImmutableCell { - val result = ImmutableCell(foreground.immutable(), background.immutable(), liquid.immutable(), dungeonId, biome, envBiome, isIndestructible) - if (result == NULL) return NULL - if (result == EMPTY) return EMPTY - return result + return POOL.intern(ImmutableCell(foreground.immutable(), background.immutable(), liquid.immutable(), dungeonId, biome, envBiome, isIndestructible)) } override fun mutable(): MutableCell { diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/MutableTileState.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/MutableTileState.kt index c65a47cc..67a6b8f3 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/MutableTileState.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/world/api/MutableTileState.kt @@ -15,10 +15,7 @@ data class MutableTileState( override var modifierHueShift: Float = 0f, ) : AbstractTileState() { override fun immutable(): ImmutableTileState { - val result = ImmutableTileState(material, modifier, color, hueShift, modifierHueShift) - if (result == NULL) return NULL - if (result == EMPTY) return EMPTY - return result + return POOL.intern(ImmutableTileState(material, modifier, color, hueShift, modifierHueShift)) } override fun mutable(): MutableTileState {