BlockLayer temporarily use DirectByteBuffer (averting the issue #26)

This commit is contained in:
minjaesong
2019-06-23 01:43:56 +09:00
parent 64bbe6b53b
commit 41b68aa132

View File

@@ -2,7 +2,7 @@ package net.torvald.terrarum.gameworld
import com.badlogic.gdx.utils.Disposable
import net.torvald.terrarum.AppLoader.printdbg
import sun.misc.Unsafe
import java.nio.ByteBuffer
/**
* Original version Created by minjaesong on 2016-01-17.
@@ -12,17 +12,23 @@ import sun.misc.Unsafe
*/
open class BlockLayer(val width: Int, val height: Int) : Disposable {
private val unsafe: Unsafe
private var unsafeArrayDestroyed = false
/*private val unsafe: Unsafe
init {
val unsafeConstructor = Unsafe::class.java.getDeclaredConstructor()
unsafeConstructor.isAccessible = true
unsafe = unsafeConstructor.newInstance()
}
private var unsafeArrayDestroyed = false
private var layerPtr = unsafe.allocateMemory(width * height * BYTES_PER_BLOCK.toLong())
private val layerPtr = unsafe.allocateMemory(width * height * BYTES_PER_BLOCK.toLong())*/
private val directByteBuffer: ByteBuffer
init {
unsafe.setMemory(layerPtr, width * height * BYTES_PER_BLOCK.toLong(), 0) // does reliably fill the memory with zeroes
//unsafe.setMemory(layerPtr, width * height * BYTES_PER_BLOCK.toLong(), 0) // does reliably fill the memory with zeroes
directByteBuffer = ByteBuffer.allocateDirect(width * height * BYTES_PER_BLOCK)
}
/**
@@ -40,7 +46,8 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable {
* TL;DR: LITTLE ENDIAN PLEASE
*/
constructor(width: Int, height: Int, data: ByteArray) : this(width, height) {
data.forEachIndexed { index, byte -> unsafe.putByte(layerPtr + index, byte) }
TODO()
//data.forEachIndexed { index, byte -> unsafe.putByte(layerPtr + index, byte) }
}
@@ -65,8 +72,10 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable {
iteratorCount += 2
val offset = 2 * (y * width + x)
val lsb = unsafe.getByte(layerPtr + offset)
val msb = unsafe.getByte(layerPtr + offset + 1)
//val lsb = unsafe.getByte(layerPtr + offset)
val lsb = directByteBuffer[offset]
//val msb = unsafe.getByte(layerPtr + offset + 1)
val msb = directByteBuffer[offset + 1]
//return data[y * width + x]
return lsb.toUint() + msb.toUint().shl(8)
@@ -91,15 +100,18 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable {
override fun next(): Byte {
iteratorCount += 1
return unsafe.getByte(layerPtr + iteratorCount)
//return unsafe.getByte(layerPtr + iteratorCount)
return directByteBuffer[iteratorCount]
}
}
}
internal fun unsafeGetTile(x: Int, y: Int): Int {
val offset = BYTES_PER_BLOCK * (y * width + x)
val lsb = unsafe.getByte(layerPtr + offset)
val msb = unsafe.getByte(layerPtr + offset + 1)
//val lsb = unsafe.getByte(layerPtr + offset)
//val msb = unsafe.getByte(layerPtr + offset + 1)
val lsb = directByteBuffer[offset]
val msb = directByteBuffer[offset + 1]
return lsb.toUint() + msb.toUint().shl(8)
}
@@ -110,28 +122,32 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable {
val lsb = tile.and(0xff).toByte()
val msb = tile.ushr(8).and(0xff).toByte()
unsafe.putByte(layerPtr + offset, lsb)
unsafe.putByte(layerPtr + offset + 1, msb)
directByteBuffer.put(offset, lsb)
directByteBuffer.put(offset + 1, msb)
//unsafe.putByte(layerPtr + offset, lsb)
//unsafe.putByte(layerPtr + offset + 1, msb)
}
/**
* @param blockOffset Offset in blocks. BlockOffset of 0x100 is equal to ```layerPtr + 0x200```
*/
internal fun unsafeSetTile(blockOffset: Long, tile: Int) {
val offset = 2 * blockOffset
/*internal fun unsafeSetTile(blockOffset: Long, tile: Int) {
val offset = BYTES_PER_BLOCK * blockOffset
val lsb = tile.and(0xff).toByte()
val msb = tile.ushr(8).and(0xff).toByte()
unsafe.putByte(layerPtr + offset, lsb)
unsafe.putByte(layerPtr + offset + 1, msb)
}
}*/
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
override fun dispose() {
if (!unsafeArrayDestroyed) {
unsafe.freeMemory(layerPtr)
//unsafe.freeMemory(layerPtr)
directByteBuffer.clear()
unsafeArrayDestroyed = true
printdbg(this, "BlockLayer successfully freed")
}