package com.github.czyzby.autumn.context.impl.method; import com.badlogic.gdx.utils.GdxRuntimeException; import com.badlogic.gdx.utils.reflect.Method; import com.github.czyzby.autumn.context.Context; import com.github.czyzby.kiwi.util.common.Strings; import com.github.czyzby.kiwi.util.gdx.collection.GdxArrays; import com.github.czyzby.kiwi.util.gdx.reflection.Reflection; /** Utility for delayed method invocations. * * @author MJ */ public class MethodInvocation { private final Method method; private final Object methodOwner; private final Object[] parameters; /** @param method will be eventually invoked. * @param methodOwner an instance of the object that contains the method. Will be kept, unless the method is static. * @param parameters will be used to invoke the method. */ public MethodInvocation(final Method method, final Object methodOwner, final Object[] parameters) { this.method = method; this.methodOwner = method.isStatic() ? null : methodOwner; this.parameters = parameters; } /** @return stored method that will be invoked. */ public Method getMethod() { return method; } /** @return object that will be used to invoke the stored method. */ public Object getMethodOwner() { return methodOwner; } /** @return direct reference to arguments that will be used to invoke stored method. */ public Object[] getParameters() { return parameters; } /** Invokes the stored method with the chosen arguments. * * @return result of the invoked method. */ public Object invoke() { try { return Reflection.invokeMethod(method, methodOwner, parameters); } catch (final Exception exception) { throw new GdxRuntimeException("Unable to invoke method: " + method.getName() + " of type: " + methodOwner + " with parameters: " + GdxArrays.newArray(parameters), exception); } } /** @param parameterTypes array of types required by method invocation. * @param context used to resolve dependencies. * @return parameters array. */ public static Object[] getParametersFromContext(final Class<?>[] parameterTypes, final Context context) { if (parameterTypes == null || parameterTypes.length == 0) { return Strings.EMPTY_ARRAY; } final Object[] parameters = new Object[parameterTypes.length]; for (int index = 0, length = parameterTypes.length; index < length; index++) { final Class<?> parameterType = parameterTypes[index]; parameters[index] = context.provide(parameterType); } return parameters; } }