Итак, я работаю над концепцией, которая предполагает автоматическую запись в ByteBuffer
содержимого класса, расширяющего Bufferizable
abstract class Bufferizable {
abstract val fieldOrder: Array<String>
open fun size(): Int = TODO()
var initialized = false
open infix fun to(address: Long) {
if (initialized) {
addFunctions.forEach { }
} else {
addFunctions = Array(fieldOrder.size) { null }
members = Array(fieldOrder.size) { null }
fieldOrder.forEachIndexed { i, field ->
val member = this::class.declaredMemberProperties.find { it.name == field }!!
addFunctions[i] = when (member.returnType) {
Mat4::class.defaultType.javaType -> WithAddress::addMat4
...
else -> throw Error()
} as BufferizableAddFunctionType
members[i] = member.get(this) // error
}
initialized = true
}
}
infix fun from(address: Long): Unit = TODO()
var addFunctions = arrayOf<BufferizableAddFunctionType?>()
var members = arrayOf<Any?>()
}
typealias BufferizableAddFunctionType = (Any) -> Unit
object WithAddress {
var address = NULL
var offset = 0
fun addMat4(mat4: Mat4) {
for (i in 0..3)
for (j in 0..3) {
memPutFloat(address + offset, mat4[i, j])
offset += Float.BYTES
}
}
...
}
Идея состоит в том, чтобы объявить, например, следующее
object uboVS : Bufferizable() {
var projectionMatrix = Mat4()
var modelMatrix = Mat4()
...
override val fieldOrder = arrayOf("projectionMatrix", "modelMatrix", "viewMatrix")
}
И затем всякий раз, когда uboVS to address
будет вызван в первый раз, он будет инициализирован, а затем его содержимое будет записано по собственному адресу в указанном порядке.
Но единственная проблема, с которой я застрял, - это сбор членов для передачи в качестве аргумента i-й addFunction
потому что компилятор жалуется здесь:
members[i] = member.get(this)
Ошибка: (328, 37) Котлин: Запроектированный тип 'KProperty1' запрещает использование 'public abstract fun get (получатель: T): R определен в kotlin.reflect.KProperty1'
Как я могу решить?