mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-16 08:36:07 +09:00
issue #26: the reason was the dangling pointer?
This commit is contained in:
@@ -37,10 +37,10 @@ class UnsafePtr(val ptr: Long, val allocSize: Long) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private inline fun checkNullPtr(index: 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
|
// 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 {
|
operator fun get(index: Long): Byte {
|
||||||
@@ -63,4 +63,8 @@ class UnsafePtr(val ptr: Long, val allocSize: Long) {
|
|||||||
UnsafeHelper.unsafe.putFloat(ptr + index, value)
|
UnsafeHelper.unsafe.putFloat(ptr + index, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun fillWith(byte: Byte) {
|
||||||
|
UnsafeHelper.unsafe.setMemory(ptr, allocSize, byte)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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)
|
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 {
|
init {
|
||||||
zerofill()
|
zerofill()
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package net.torvald.terrarum.gameworld
|
package net.torvald.terrarum.gameworld
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.Disposable
|
import com.badlogic.gdx.utils.Disposable
|
||||||
|
import net.torvald.UnsafeHelper
|
||||||
import net.torvald.terrarum.AppLoader.printdbg
|
import net.torvald.terrarum.AppLoader.printdbg
|
||||||
import java.nio.ByteBuffer
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Original version Created by minjaesong on 2016-01-17.
|
* 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 {
|
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
|
//private val directByteBuffer: ByteBuffer
|
||||||
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
|
|
||||||
|
|
||||||
init {
|
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
|
// advance counter
|
||||||
iteratorCount += 2
|
iteratorCount += 2
|
||||||
|
|
||||||
val offset = 2 * (y * width + x)
|
val offset = 2L * (y * width + x)
|
||||||
//val lsb = unsafe.getByte(layerPtr + offset)
|
val lsb = ptr[offset]
|
||||||
val lsb = directByteBuffer[offset]
|
//val lsb = directByteBuffer[offset]
|
||||||
//val msb = unsafe.getByte(layerPtr + offset + 1)
|
val msb = ptr[offset + 1]
|
||||||
val msb = directByteBuffer[offset + 1]
|
//val msb = directByteBuffer[offset + 1]
|
||||||
|
|
||||||
|
|
||||||
//return data[y * width + x]
|
|
||||||
return lsb.toUint() + msb.toUint().shl(8)
|
return lsb.toUint() + msb.toUint().shl(8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,7 +82,7 @@ open class BlockLayer(val width: Int, val height: Int) : Disposable {
|
|||||||
fun bytesIterator(): Iterator<Byte> {
|
fun bytesIterator(): Iterator<Byte> {
|
||||||
return object : Iterator<Byte> {
|
return object : Iterator<Byte> {
|
||||||
|
|
||||||
private var iteratorCount = 0
|
private var iteratorCount = 0L
|
||||||
|
|
||||||
override fun hasNext(): Boolean {
|
override fun hasNext(): Boolean {
|
||||||
return iteratorCount < width * height
|
return iteratorCount < width * height
|
||||||
@@ -100,18 +91,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 ptr[iteratorCount]
|
||||||
return directByteBuffer[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 = ptr[offset]
|
||||||
//val msb = unsafe.getByte(layerPtr + offset + 1)
|
val msb = ptr[offset + 1]
|
||||||
val lsb = directByteBuffer[offset]
|
//val lsb = directByteBuffer[offset]
|
||||||
val msb = directByteBuffer[offset + 1]
|
//val msb = directByteBuffer[offset + 1]
|
||||||
|
|
||||||
return lsb.toUint() + msb.toUint().shl(8)
|
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()
|
val msb = tile.ushr(8).and(0xff).toByte()
|
||||||
|
|
||||||
|
|
||||||
directByteBuffer.put(offset, lsb)
|
ptr[offset] = lsb
|
||||||
directByteBuffer.put(offset + 1, msb)
|
ptr[offset + 1] = msb
|
||||||
//unsafe.putByte(layerPtr + offset, lsb)
|
//directByteBuffer.put(offset, lsb)
|
||||||
//unsafe.putByte(layerPtr + offset + 1, msb)
|
//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)
|
fun isInBound(x: Int, y: Int) = (x >= 0 && y >= 0 && x < width && y < height)
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
if (!unsafeArrayDestroyed) {
|
ptr.destroy()
|
||||||
//unsafe.freeMemory(layerPtr)
|
//directByteBuffer.clear()
|
||||||
directByteBuffer.clear()
|
printdbg(this, "BlockLayer successfully freed")
|
||||||
unsafeArrayDestroyed = true
|
|
||||||
printdbg(this, "BlockLayer successfully freed")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun getPtr() = ptr.ptr
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Transient val BYTES_PER_BLOCK = 2
|
@Transient val BYTES_PER_BLOCK = 2L
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -211,6 +211,12 @@ object LightmapRenderer {
|
|||||||
catch (e: UninitializedPropertyAccessException) {
|
catch (e: UninitializedPropertyAccessException) {
|
||||||
return // quit prematurely
|
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
|
if (world.worldIndex == -1) return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user