chunkpoolnig wip

This commit is contained in:
minjaesong
2024-10-22 11:47:21 +09:00
parent 3de4018d75
commit 39cfc3a4d9
5 changed files with 172 additions and 57 deletions

View File

@@ -5,14 +5,14 @@ import com.badlogic.gdx.utils.Disposable
/** /**
* Created by minjaesong on 2023-10-10. * Created by minjaesong on 2023-10-10.
*/ */
interface BlockLayer : Disposable { abstract class BlockLayer : Disposable {
abstract val chunkPool: ChunkPool
val width: Int abstract val width: Int
val height: Int abstract val height: Int
val bytesPerBlock: Long abstract val bytesPerBlock: Long
fun unsafeToBytes(x: Int, y: Int): ByteArray abstract fun unsafeToBytes(x: Int, y: Int): ByteArray
fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray) abstract fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray)
fun unsafeGetTile(x: Int, y: Int): Int abstract fun unsafeGetTile(x: Int, y: Int): Int
} }

View File

@@ -1,6 +1,11 @@
package net.torvald.terrarum.gameworld package net.torvald.terrarum.gameworld
import net.torvald.terrarum.App import net.torvald.terrarum.App
import net.torvald.terrarum.gameworld.BlockLayerGenericI16.Companion
import net.torvald.terrarum.gameworld.GameWorld.Companion.TERRAIN
import net.torvald.terrarum.gameworld.GameWorld.Companion.WALL
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClusteredFormatDOM
import net.torvald.terrarum.savegame.DiskSkimmer
import net.torvald.terrarum.serialise.toUint import net.torvald.terrarum.serialise.toUint
import net.torvald.unsafe.UnsafeHelper import net.torvald.unsafe.UnsafeHelper
import net.torvald.unsafe.UnsafePtr import net.torvald.unsafe.UnsafePtr
@@ -17,12 +22,41 @@ const val FLUID_MIN_MASS = 1f / 1024f //Ignore cells that are almost dry (smalle
* *
* Created by minjaesong on 2023-10-10. * Created by minjaesong on 2023-10-10.
*/ */
class BlockLayerI16F16(override val width: Int, override val height: Int) : BlockLayer { class BlockLayerFluidI16F16 : BlockLayer {
override val width: Int
override val height: Int
override val chunkPool: ChunkPool
constructor(
width: Int,
height: Int,
disk: ClusteredFormatDOM,
layerNum: Int,
world: GameWorld
) {
this.width = width
this.height = height
chunkPool = ChunkPool(disk, layerNum, BlockLayerGenericI16.BYTES_PER_BLOCK, world, -1, ChunkPool.getRenameFunFluids(world))
}
constructor(
width: Int,
height: Int,
disk: DiskSkimmer,
layerNum: Int,
world: GameWorld
) {
this.width = width
this.height = height
chunkPool = ChunkPool(disk, layerNum, BlockLayerGenericI16.BYTES_PER_BLOCK, world, -1, ChunkPool.getRenameFunFluids(world))
}
override val bytesPerBlock = BYTES_PER_BLOCK override val bytesPerBlock = BYTES_PER_BLOCK
// for some reason, all the efforts of saving the memory space were futile.
// using unsafe pointer gets you 100 fps, whereas using directbytebuffer gets you 90
internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * bytesPerBlock) internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * bytesPerBlock)
val ptrDestroyed: Boolean val ptrDestroyed: Boolean
@@ -32,14 +66,6 @@ class BlockLayerI16F16(override val width: Int, override val height: Int) : Bloc
ptr.fillWith(-1) ptr.fillWith(-1)
} }
/**
* @param data Byte array representation of the layer
*/
constructor(width: Int, height: Int, data: ByteArray) : this(width, height) {
TODO()
data.forEachIndexed { index, byte -> UnsafeHelper.unsafe.putByte(ptr.ptr + index, byte) }
}
/** /**
* Returns an iterator over stored bytes. * Returns an iterator over stored bytes.
* *

View File

@@ -1,10 +1,10 @@
package net.torvald.terrarum.gameworld package net.torvald.terrarum.gameworld
import com.badlogic.gdx.utils.Disposable
import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.gameworld.GameWorld.Companion.TERRAIN import net.torvald.terrarum.gameworld.GameWorld.Companion.TERRAIN
import net.torvald.terrarum.gameworld.GameWorld.Companion.WALL import net.torvald.terrarum.gameworld.GameWorld.Companion.WALL
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClusteredFormatDOM import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClusteredFormatDOM
import net.torvald.terrarum.savegame.DiskSkimmer
import net.torvald.terrarum.serialise.toUint import net.torvald.terrarum.serialise.toUint
import net.torvald.unsafe.UnsafeHelper import net.torvald.unsafe.UnsafeHelper
import net.torvald.unsafe.UnsafePtr import net.torvald.unsafe.UnsafePtr
@@ -21,25 +21,49 @@ import net.torvald.unsafe.UnsafePtr
* *
* Note to self: refrain from using shorts--just do away with two bytes: different system have different endianness * Note to self: refrain from using shorts--just do away with two bytes: different system have different endianness
*/ */
class BlockLayerI16( class BlockLayerGenericI16: BlockLayer {
override val width: Int,
override val height: Int, override val width: Int
disk: ClusteredFormatDOM, override val height: Int
layerNum: Int, override val chunkPool: ChunkPool
world: GameWorld
): BlockLayer() { constructor(
width: Int,
height: Int,
disk: ClusteredFormatDOM,
layerNum: Int,
world: GameWorld
) {
this.width = width
this.height = height
chunkPool = ChunkPool(disk, layerNum, BYTES_PER_BLOCK, world, -1, when (layerNum) {
TERRAIN -> ChunkPool.getRenameFunTerrain(world)
WALL -> ChunkPool.getRenameFunTerrain(world)
else -> throw IllegalArgumentException("Unknown layer number for I16: $layerNum")
})
}
constructor(
width: Int,
height: Int,
disk: DiskSkimmer,
layerNum: Int,
world: GameWorld
) {
this.width = width
this.height = height
chunkPool = ChunkPool(disk, layerNum, BYTES_PER_BLOCK, world, -1, when (layerNum) {
TERRAIN -> ChunkPool.getRenameFunTerrain(world)
WALL -> ChunkPool.getRenameFunTerrain(world)
else -> throw IllegalArgumentException("Unknown layer number for I16: $layerNum")
})
}
override val chunkPool = ChunkPool(disk, layerNum, BYTES_PER_BLOCK, world, when (layerNum) {
TERRAIN -> ChunkPool.getRenameFunTerrain(world)
WALL -> ChunkPool.getRenameFunTerrain(world)
else -> throw IllegalArgumentException("Unknown layer number for I16: $layerNum")
})
override val bytesPerBlock = BYTES_PER_BLOCK override val bytesPerBlock = BYTES_PER_BLOCK
// for some reason, all the efforts of saving the memory space were futile.
// using unsafe pointer gets you 100 fps, whereas using directbytebuffer gets you 90
internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * bytesPerBlock) internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * bytesPerBlock)
val ptrDestroyed: Boolean val ptrDestroyed: Boolean

View File

@@ -1,6 +1,11 @@
package net.torvald.terrarum.gameworld package net.torvald.terrarum.gameworld
import net.torvald.terrarum.App import net.torvald.terrarum.App
import net.torvald.terrarum.gameworld.BlockLayerFluidI16F16.Companion
import net.torvald.terrarum.gameworld.GameWorld.Companion.TERRAIN
import net.torvald.terrarum.gameworld.GameWorld.Companion.WALL
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.archivers.ClusteredFormatDOM
import net.torvald.terrarum.savegame.DiskSkimmer
import net.torvald.terrarum.serialise.toUint import net.torvald.terrarum.serialise.toUint
import net.torvald.unsafe.UnsafeHelper import net.torvald.unsafe.UnsafeHelper
import net.torvald.unsafe.UnsafePtr import net.torvald.unsafe.UnsafePtr
@@ -13,12 +18,41 @@ import net.torvald.unsafe.UnsafePtr
* where a_n is a tile number, p_n is a placement index * where a_n is a tile number, p_n is a placement index
* Created by minjaesong on 2023-10-10. * Created by minjaesong on 2023-10-10.
*/ */
class BlockLayerOresI16I8 (override val width: Int, override val height: Int) : BlockLayer { class BlockLayerOresI16I8 : BlockLayer {
override val width: Int
override val height: Int
override val chunkPool: ChunkPool
constructor(
width: Int,
height: Int,
disk: ClusteredFormatDOM,
layerNum: Int,
world: GameWorld
) {
this.width = width
this.height = height
chunkPool = ChunkPool(disk, layerNum, BlockLayerGenericI16.BYTES_PER_BLOCK, world, 0, ChunkPool.getRenameFunOres(world))
}
constructor(
width: Int,
height: Int,
disk: DiskSkimmer,
layerNum: Int,
world: GameWorld
) {
this.width = width
this.height = height
chunkPool = ChunkPool(disk, layerNum, BlockLayerGenericI16.BYTES_PER_BLOCK, world, 0, ChunkPool.getRenameFunOres(world))
}
override val bytesPerBlock = BYTES_PER_BLOCK override val bytesPerBlock = BYTES_PER_BLOCK
// for some reason, all the efforts of saving the memory space were futile.
// using unsafe pointer gets you 100 fps, whereas using directbytebuffer gets you 90
internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * bytesPerBlock) internal val ptr: UnsafePtr = UnsafeHelper.allocate(width * height * bytesPerBlock)
val ptrDestroyed: Boolean val ptrDestroyed: Boolean
@@ -28,14 +62,6 @@ class BlockLayerOresI16I8 (override val width: Int, override val height: Int) :
ptr.fillWith(0) // there is no NOT-GENERATED for ores, keep it as 0 ptr.fillWith(0) // there is no NOT-GENERATED for ores, keep it as 0
} }
/**
* @param data Byte array representation of the layer
*/
constructor(width: Int, height: Int, data: ByteArray) : this(width, height) {
TODO()
data.forEachIndexed { index, byte -> UnsafeHelper.unsafe.putByte(ptr.ptr + index, byte) }
}
/** /**
* Returns an iterator over stored bytes. * Returns an iterator over stored bytes.
* *

View File

@@ -39,21 +39,60 @@ enum class ChunkAllocClass {
* *
* Created by minjaesong on 2024-09-07. * Created by minjaesong on 2024-09-07.
*/ */
open class ChunkPool( open class ChunkPool {
// `DiskSkimmer` or `ClusteredFormatDOM` // `DiskSkimmer` or `ClusteredFormatDOM`
val disk: Any, private val disk: Any
val layerIndex: Int, private val layerIndex: Int
val wordSizeInBytes: Long, private val wordSizeInBytes: Long
val world: GameWorld, private val world: GameWorld
val renumberFun: (Int) -> Int, private val initialValue: Int // bytes to fill the new chunk
) { private val renumberFun: (Int) -> Int
private val pointers = TreeMap<Long, Long>() private val pointers = TreeMap<Long, Long>()
private var allocCap = 32 private var allocCap = 32
private var allocMap = Array<ChunkAllocation?>(allocCap) { null } private var allocMap = Array<ChunkAllocation?>(allocCap) { null }
private var allocCounter = 0 private var allocCounter = 0
private val chunkSize: Long
private val pool: UnsafePtr
private val chunkSize = (wordSizeInBytes * CHUNK_W * CHUNK_H) constructor(
private val pool = UnsafeHelper.allocate(chunkSize * allocCap) disk: DiskSkimmer,
layerIndex: Int,
wordSizeInBytes: Long,
world: GameWorld,
initialValue: Int,
renumberFun: (Int) -> Int,
) {
this.disk = disk
this.layerIndex = layerIndex
this.wordSizeInBytes = wordSizeInBytes
this.world = world
this.initialValue = initialValue
this.renumberFun = renumberFun
chunkSize = wordSizeInBytes * CHUNK_W * CHUNK_H
pool = UnsafeHelper.allocate(chunkSize * allocCap)
}
constructor(
disk: ClusteredFormatDOM,
layerIndex: Int,
wordSizeInBytes: Long,
world: GameWorld,
initialValue: Int,
renumberFun: (Int) -> Int,
) {
this.disk = disk
this.layerIndex = layerIndex
this.wordSizeInBytes = wordSizeInBytes
this.world = world
this.initialValue = initialValue
this.renumberFun = renumberFun
chunkSize = wordSizeInBytes * CHUNK_W * CHUNK_H
pool = UnsafeHelper.allocate(chunkSize * allocCap)
}
init { init {
allocMap.fill(null) allocMap.fill(null)