All Downloads are FREE. Search and download functionalities are using the official Maven repository.

orbit.client.addressable.MethodInvoker.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0a19
Show newest version
/*
 Copyright (C) 2015 - 2019 Electronic Arts Inc.  All rights reserved.
 This file is part of the Orbit Project .
 See license in LICENSE.
 */

package orbit.client.addressable

import kotlinx.coroutines.coroutineScope
import orbit.client.util.DeferredWrappers
import orbit.shared.addressable.AddressableInvocationArguments
import java.lang.reflect.Method
import kotlin.coroutines.Continuation
import kotlin.reflect.jvm.kotlinFunction

internal object MethodInvoker {
    suspend fun invoke(
        instance: Any,
        methodName: String,
        args: AddressableInvocationArguments
    ): Any? = coroutineScope {
        val argTypes = args.map { it.second }.toTypedArray()

        val method = matchMethod(instance::class.java, methodName, argTypes) ?: matchMethod(
            instance::class.java,
            methodName,
            argTypes.plus(Continuation::class.java)
        ) ?: throw NoSuchMethodException("${methodName}(${argTypes.joinToString(", ")})")

        val argValues = args.map { it.first }.toTypedArray()

        method.isAccessible = true

        if (method.kotlinFunction?.isSuspend == true) {
            DeferredWrappers.wrapSuspend(method, instance, argValues)

        } else {
            DeferredWrappers.wrapCall(method.invoke(instance, *argValues)).await()
        }
    }

    fun matchMethod(clazz: Class<*>, name: String, args: Array>): Method? =
        clazz.methods.firstOrNull { m -> m.name == name && m.parameterTypes.contentEquals(args) }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy