62 lines
1.7 KiB
Kotlin
62 lines
1.7 KiB
Kotlin
package ru.dbotthepony.kstarbound.util
|
|
|
|
import it.unimi.dsi.fastutil.objects.ObjectSpliterators
|
|
import java.util.Arrays
|
|
import java.util.stream.Stream
|
|
import java.util.stream.StreamSupport
|
|
import kotlin.reflect.KClass
|
|
|
|
class TwoDimensionalArray<T : Any>(clazz: KClass<T>, private val width: Int, private val height: Int) {
|
|
data class Entry<out T>(
|
|
val x: Int,
|
|
val y: Int,
|
|
val value: T,
|
|
)
|
|
|
|
private val memory: Array<T?> = java.lang.reflect.Array.newInstance(clazz.java, width * height) as Array<T?>
|
|
|
|
fun isOutside(x: Int, y: Int): Boolean {
|
|
return (x !in 0 until width) || (y !in 0 until height)
|
|
}
|
|
|
|
operator fun get(x: Int, y: Int): T? {
|
|
if (x !in 0 until width) {
|
|
throw IndexOutOfBoundsException("X $x is out of bounds between 0 and $width")
|
|
}
|
|
|
|
if (y !in 0 until height) {
|
|
throw IndexOutOfBoundsException("Y $y is out of bounds between 0 and $height")
|
|
}
|
|
|
|
return memory[x + y * width]
|
|
}
|
|
|
|
operator fun set(x: Int, y: Int, value: T?): T? {
|
|
if (x !in 0 until width) {
|
|
throw IndexOutOfBoundsException("X $x is out of bounds between 0 and $width")
|
|
}
|
|
|
|
if (y !in 0 until height) {
|
|
throw IndexOutOfBoundsException("Y $y is out of bounds between 0 and $height")
|
|
}
|
|
|
|
val old = memory[x + y * width]
|
|
memory[x + y * width] = value
|
|
return old
|
|
}
|
|
|
|
fun stream(): Stream<out T?> {
|
|
return Arrays.stream(memory)
|
|
}
|
|
|
|
fun indexedStream(): Stream<out Entry<T?>> {
|
|
return StreamSupport.stream(IndexedArraySpliterator(memory), false).map {
|
|
val x = it.index % width
|
|
val y = (it.index - x) / width
|
|
Entry(x, y, it.value)
|
|
}
|
|
}
|
|
}
|
|
|
|
inline fun <reified T : Any> TwoDimensionalArray(width: Int, height: Int) = TwoDimensionalArray(T::class, width, height)
|