diff --git a/src/net/torvald/UnsafePtr.kt b/src/net/torvald/UnsafePtr.kt index 721115894..91e7cd4e7 100644 --- a/src/net/torvald/UnsafePtr.kt +++ b/src/net/torvald/UnsafePtr.kt @@ -37,10 +37,10 @@ class UnsafePtr(val ptr: Long, val allocSize: Long) { } private inline fun checkNullPtr(index: Long) { - if (destroyed) throw NullPointerException() + if (destroyed) throw NullPointerException("The pointer is already destroyed (0x${ptr.toString(16)})") // OOB Check: debugging purposes only -- comment out for the production - //if (index !in 0 until allocSize) throw NullPointerException("Out of bounds: $index; alloc size: $allocSize") + //if (index !in 0 until allocSize) throw IndexOutOfBoundsException("Index: $index; alloc size: $allocSize") } operator fun get(index: Long): Byte { @@ -63,4 +63,8 @@ class UnsafePtr(val ptr: Long, val allocSize: Long) { UnsafeHelper.unsafe.putFloat(ptr + index, value) } + fun fillWith(byte: Byte) { + UnsafeHelper.unsafe.setMemory(ptr, allocSize, byte) + } + } \ No newline at end of file diff --git a/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt b/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt index c1bbba2b5..f583548b8 100644 --- a/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt +++ b/src/net/torvald/gdx/graphics/UnsafeCvecArray.kt @@ -13,7 +13,7 @@ internal class UnsafeCvecArray(val width: Int, val height: Int) { private inline fun toAddr(x: Int, y: Int) = 16L * (y * width + x) - fun zerofill() = UnsafeHelper.unsafe.setMemory(this.array.ptr, TOTAL_SIZE_IN_BYTES, 0) + fun zerofill() = array.fillWith(0) init { zerofill() diff --git a/src/net/torvald/terrarum/gameworld/BlockLayer.kt b/src/net/torvald/terrarum/gameworld/BlockLayer.kt index e79b23cc9..f8301cc40 100644 --- a/src/net/torvald/terrarum/gameworld/BlockLayer.kt +++ b/src/net/torvald/terrarum/gameworld/BlockLayer.kt @@ -1,8 +1,8 @@ package net.torvald.terrarum.gameworld import com.badlogic.gdx.utils.Disposable +import net.torvald.UnsafeHelper import net.torvald.terrarum.AppLoader.printdbg -import java.nio.ByteBuffer /** * Original version Created by minjaesong on 2016-01-17. @@ -12,23 +12,14 @@ import java.nio.ByteBuffer */ open class BlockLayer(val width: Int, val height: Int) : Disposable { - private var unsafeArrayDestroyed = false + private val ptr = UnsafeHelper.allocate(width * height * BYTES_PER_BLOCK) - /*private val unsafe: Unsafe - init { - val unsafeConstructor = Unsafe::class.java.getDeclaredConstructor() - unsafeConstructor.isAccessible = true - unsafe = unsafeConstructor.newInstance() - } - - private val layerPtr = unsafe.allocateMemory(width * height * BYTES_PER_BLOCK.toLong())*/ - - private val directByteBuffer: ByteBuffer + //private val directByteBuffer: ByteBuffer init { - //unsafe.setMemory(layerPtr, width * height * BYTES_PER_BLOCK.toLong(), 0) // does reliably fill the memory with zeroes + ptr.fillWith(0) - directByteBuffer = ByteBuffer.allocateDirect(width * height * BYTES_PER_BLOCK) + //directByteBuffer = ByteBuffer.allocateDirect(width * height * BYTES_PER_BLOCK) } /** @@ -71,13 +62,13 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable { // advance counter iteratorCount += 2 - val offset = 2 * (y * width + x) - //val lsb = unsafe.getByte(layerPtr + offset) - val lsb = directByteBuffer[offset] - //val msb = unsafe.getByte(layerPtr + offset + 1) - val msb = directByteBuffer[offset + 1] + val offset = 2L * (y * width + x) + val lsb = ptr[offset] + //val lsb = directByteBuffer[offset] + val msb = ptr[offset + 1] + //val msb = directByteBuffer[offset + 1] + - //return data[y * width + x] return lsb.toUint() + msb.toUint().shl(8) } } @@ -91,7 +82,7 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable { fun bytesIterator(): Iterator { return object : Iterator { - private var iteratorCount = 0 + private var iteratorCount = 0L override fun hasNext(): Boolean { return iteratorCount < width * height @@ -100,18 +91,18 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable { override fun next(): Byte { iteratorCount += 1 - //return unsafe.getByte(layerPtr + iteratorCount) - return directByteBuffer[iteratorCount] + return ptr[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 = directByteBuffer[offset] - val msb = directByteBuffer[offset + 1] + val lsb = ptr[offset] + val msb = ptr[offset + 1] + //val lsb = directByteBuffer[offset] + //val msb = directByteBuffer[offset + 1] return lsb.toUint() + msb.toUint().shl(8) } @@ -123,10 +114,10 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable { val msb = tile.ushr(8).and(0xff).toByte() - directByteBuffer.put(offset, lsb) - directByteBuffer.put(offset + 1, msb) - //unsafe.putByte(layerPtr + offset, lsb) - //unsafe.putByte(layerPtr + offset + 1, msb) + ptr[offset] = lsb + ptr[offset + 1] = msb + //directByteBuffer.put(offset, lsb) + //directByteBuffer.put(offset + 1, msb) } /** @@ -145,16 +136,15 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable { fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height) override fun dispose() { - if (!unsafeArrayDestroyed) { - //unsafe.freeMemory(layerPtr) - directByteBuffer.clear() - unsafeArrayDestroyed = true - printdbg(this, "BlockLayer successfully freed") - } + ptr.destroy() + //directByteBuffer.clear() + printdbg(this, "BlockLayer successfully freed") } + internal fun getPtr() = ptr.ptr + companion object { - @Transient val BYTES_PER_BLOCK = 2 + @Transient val BYTES_PER_BLOCK = 2L } } diff --git a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt index 9d0c3ecc1..0aebcbae6 100644 --- a/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt +++ b/src/net/torvald/terrarum/worlddrawer/LightmapRendererNew.kt @@ -211,6 +211,12 @@ object LightmapRenderer { catch (e: UninitializedPropertyAccessException) { return // quit prematurely } + catch (e: NullPointerException) { + System.err.println("[LightmapRendererNew.fireRecalculateEvent] Attempted to refer destroyed unsafe array " + + "(world size: ${world.layerTerrain.width} x ${world.layerTerrain.height}; " + + "ptr: 0x${world.layerTerrain.getPtr().toString(16)})") + return + } if (world.worldIndex == -1) return