mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-10 02:24:05 +09:00
BlockLayer temporarily use DirectByteBuffer (averting the issue #26)
This commit is contained in:
@@ -2,7 +2,7 @@ package net.torvald.terrarum.gameworld
|
|||||||
|
|
||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
import net.torvald.terrarum.AppLoader.printdbg
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
import sun.misc.Unsafe
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Original version Created by minjaesong on 2016-01-17.
|
* 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 {
|
open class BlockLayer(val width: Int, val height: Int) : Disposable {
|
||||||
|
|
||||||
private val unsafe: Unsafe
|
private var unsafeArrayDestroyed = false
|
||||||
|
|
||||||
|
/*private val unsafe: Unsafe
|
||||||
init {
|
init {
|
||||||
val unsafeConstructor = Unsafe::class.java.getDeclaredConstructor()
|
val unsafeConstructor = Unsafe::class.java.getDeclaredConstructor()
|
||||||
unsafeConstructor.isAccessible = true
|
unsafeConstructor.isAccessible = true
|
||||||
unsafe = unsafeConstructor.newInstance()
|
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 {
|
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
|
* TL;DR: LITTLE ENDIAN PLEASE
|
||||||
*/
|
*/
|
||||||
constructor(width: Int, height: Int, data: ByteArray) : this(width, height) {
|
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
|
iteratorCount += 2
|
||||||
|
|
||||||
val offset = 2 * (y * width + x)
|
val offset = 2 * (y * width + x)
|
||||||
val lsb = unsafe.getByte(layerPtr + offset)
|
//val lsb = unsafe.getByte(layerPtr + offset)
|
||||||
val msb = unsafe.getByte(layerPtr + offset + 1)
|
val lsb = directByteBuffer[offset]
|
||||||
|
//val msb = unsafe.getByte(layerPtr + offset + 1)
|
||||||
|
val msb = directByteBuffer[offset + 1]
|
||||||
|
|
||||||
//return data[y * width + x]
|
//return data[y * width + x]
|
||||||
return lsb.toUint() + msb.toUint().shl(8)
|
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 {
|
override fun next(): Byte {
|
||||||
iteratorCount += 1
|
iteratorCount += 1
|
||||||
|
|
||||||
return unsafe.getByte(layerPtr + iteratorCount)
|
//return unsafe.getByte(layerPtr + iteratorCount)
|
||||||
|
return directByteBuffer[iteratorCount]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun unsafeGetTile(x: Int, y: Int): Int {
|
internal fun unsafeGetTile(x: Int, y: Int): Int {
|
||||||
val offset = BYTES_PER_BLOCK * (y * width + x)
|
val offset = BYTES_PER_BLOCK * (y * width + x)
|
||||||
val lsb = unsafe.getByte(layerPtr + offset)
|
//val lsb = unsafe.getByte(layerPtr + offset)
|
||||||
val msb = unsafe.getByte(layerPtr + offset + 1)
|
//val msb = unsafe.getByte(layerPtr + offset + 1)
|
||||||
|
val lsb = directByteBuffer[offset]
|
||||||
|
val msb = directByteBuffer[offset + 1]
|
||||||
|
|
||||||
return lsb.toUint() + msb.toUint().shl(8)
|
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 lsb = tile.and(0xff).toByte()
|
||||||
val msb = tile.ushr(8).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```
|
* @param blockOffset Offset in blocks. BlockOffset of 0x100 is equal to ```layerPtr + 0x200```
|
||||||
*/
|
*/
|
||||||
internal fun unsafeSetTile(blockOffset: Long, tile: Int) {
|
/*internal fun unsafeSetTile(blockOffset: Long, tile: Int) {
|
||||||
val offset = 2 * blockOffset
|
val offset = BYTES_PER_BLOCK * blockOffset
|
||||||
|
|
||||||
val lsb = tile.and(0xff).toByte()
|
val lsb = tile.and(0xff).toByte()
|
||||||
val msb = tile.ushr(8).and(0xff).toByte()
|
val msb = tile.ushr(8).and(0xff).toByte()
|
||||||
|
|
||||||
unsafe.putByte(layerPtr + offset, lsb)
|
unsafe.putByte(layerPtr + offset, lsb)
|
||||||
unsafe.putByte(layerPtr + offset + 1, msb)
|
unsafe.putByte(layerPtr + offset + 1, msb)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
|
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
if (!unsafeArrayDestroyed) {
|
if (!unsafeArrayDestroyed) {
|
||||||
unsafe.freeMemory(layerPtr)
|
//unsafe.freeMemory(layerPtr)
|
||||||
|
directByteBuffer.clear()
|
||||||
unsafeArrayDestroyed = true
|
unsafeArrayDestroyed = true
|
||||||
printdbg(this, "BlockLayer successfully freed")
|
printdbg(this, "BlockLayer successfully freed")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user