mardi 1 mai 2018

How to collect members via reflection to pass as argument later

So, I'm working on a concept that involvs writing automatically to a ByteBuffer the content of a class extending 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
            }
    }
    ...
}

The idea is to declare, for example, the following

object uboVS : Bufferizable() {

    var projectionMatrix = Mat4()
    var modelMatrix = Mat4()
    ...

    override val fieldOrder = arrayOf("projectionMatrix", "modelMatrix", "viewMatrix")
}

And then whenever uboVS to address will be called for the first time, it will be initialized and then its content written at the native address, following the order specified.

But the only problem I'm stuck at, is collecting the members to pass later on as argument to the i-th addFunction

because the compiler complains here:

members[i] = member.get(this)

Error:(328, 37) Kotlin: Out-projected type 'KProperty1' prohibits the use of 'public abstract fun get(receiver: T): R defined in kotlin.reflect.KProperty1'

How can I solve?





Aucun commentaire:

Enregistrer un commentaire