mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-14 23:56:07 +09:00
chunkpoolnig wip
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user