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.
*/
interface BlockLayer : Disposable {
val width: Int
val height: Int
val bytesPerBlock: Long
fun unsafeToBytes(x: Int, y: Int): ByteArray
fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray)
fun unsafeGetTile(x: Int, y: Int): Int
abstract class BlockLayer : Disposable {
abstract val chunkPool: ChunkPool
abstract val width: Int
abstract val height: Int
abstract val bytesPerBlock: Long
abstract fun unsafeToBytes(x: Int, y: Int): ByteArray
abstract fun unsafeSetTile(x: Int, y: Int, bytes: ByteArray)
abstract fun unsafeGetTile(x: Int, y: Int): Int
}

View File

@@ -1,6 +1,11 @@
package net.torvald.terrarum.gameworld
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.unsafe.UnsafeHelper
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.
*/
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
// 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)
val ptrDestroyed: Boolean
@@ -32,14 +66,6 @@ class BlockLayerI16F16(override val width: Int, override val height: Int) : Bloc
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.
*

View File

@@ -1,10 +1,10 @@
package net.torvald.terrarum.gameworld
import com.badlogic.gdx.utils.Disposable
import net.torvald.terrarum.App.printdbg
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.unsafe.UnsafeHelper
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
*/
class BlockLayerI16(
override val width: Int,
override val height: Int,
disk: ClusteredFormatDOM,
layerNum: Int,
world: GameWorld
): BlockLayer() {
class BlockLayerGenericI16: 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, 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
// 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)
val ptrDestroyed: Boolean

View File

@@ -1,6 +1,11 @@
package net.torvald.terrarum.gameworld
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.unsafe.UnsafeHelper
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
* 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
// 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)
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
}
/**
* @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.
*

View File

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