I want to add to a MutableList<(some-type)->Uint>
at run-time depending on the type. I mostly got it, but I can't figure out how to get the instance info into the KFunction
I have.
This code is a bit contrived, but it's a stripped down example of what I'm trying to do. I'm trying to get rid of a bunch of boiler plate code by wiring up dispatch at runtime.
This code compiles, but blows up at runtime when using the lists with the error : java.lang.IllegalArgumentException: Callable expects 2 arguments, but 1 were provided.
from the doSomeWork()
when dispatching.
This error makes me think the instance isn't associated w/ the KFunction
I'm adding to the list... but I don't know how to associate it. I have the instance handy, I just don't know how to attach it. Or maybe it's something else entirely.
The code :
package reflectwork
import kotlin.reflect.KFunction
import kotlin.reflect.full.functions
import kotlin.reflect.full.hasAnnotation
import kotlin.reflect.full.memberProperties
interface Marker
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class WireMeUp
class Dispacher {
val strList = mutableListOf<(String)->Unit>()
val intList = mutableListOf<(Int)->Unit>()
val floatList = mutableListOf<(Float)->Unit>()
fun doSomeWork() {
strList.forEach { it("Some work") }
intList.forEach { it(57) }
floatList.forEach { it(3.14f) }
}
}
class Client : Marker {
@WireMeUp fun doStringWork(str:String) { println(str) }
@WireMeUp fun doIntWork(i:Int) { println(i) }
@WireMeUp fun doFloatWork(f:Float) { println(f) }
}
fun wire(app:Marker, dis:Dispacher) {
app::class.functions.forEach { func ->
if( func.hasAnnotation<WireMeUp>() ) {
require( func.parameters.size == 2 )
val parmType = func.parameters[1].type
dis::class.memberProperties.forEach{ prop ->
if( prop.returnType.arguments.size == 1 ) {
val argType = prop.returnType.arguments[0].type
// I have no idea how to compare a [type] to a ([type]) -> Unit
// so just do it via strings. better way?
if( "($parmType)->kotlin.Unit" == argType.toString().replace(" ","")) {
println("found match, setting type = $parmType")
// get the list. No idea how cast to the correct type
// which in theory I know at this point.
val lst = prop.call(dis) as MutableList<KFunction<*>>
// this works, but blows up at runtime in doSomeWork()
// with the error :
// java.lang.IllegalArgumentException: Callable expects 2 arguments, but 1 were provided.
// I think because "func" has not instance? Not sure how to attach an instance... which I have
lst.add( func )
}
}
}
}
}
}
fun main() {
val dispatch = Dispacher()
val cli = Client()
wire(cli,dispatch)
dispatch.doSomeWork()
}
Any advice?
Thanks in advance.
Aucun commentaire:
Enregistrer un commentaire