package jalse.entities.methods;
import java.lang.invoke.MethodHandle;
import java.util.Objects;
import jalse.entities.Entity;
import jalse.entities.functions.DefaultFunction;
/**
* This is used for mapping {@code default} methods.<br>
* <br>
* It is worth noting that this class has been designed with performance in mind. Default method
* invocation on a dynamic proxy is quite problematic and slow (for now).
*
* @author Elliot Ford
*
* @see DefaultFunction
*/
public class DefaultMethod implements EntityMethod {
private final MethodHandle handle;
private final int argCount;
/**
* Creates a new default method.
*
* @param handle
* Method handle to invoke.
* @param argCount
* Method parameter count.
*/
public DefaultMethod(final MethodHandle handle, final int argCount) {
this.handle = Objects.requireNonNull(handle);
if (argCount < 0) {
throw new IllegalArgumentException();
}
this.argCount = argCount;
}
/**
* Gets the method argument count.
*
* @return Argument count.
*/
public int getArgCount() {
return argCount;
}
/**
* Gets the method handle to invoke.
*
* @return Method handle.
*/
public MethodHandle getHandle() {
return handle;
}
@Override
public Object invoke(final Object proxy, final Entity e, final Object[] args) throws Throwable {
/*
* Generally the maximum accepted parameter count for a method is 7.
*/
switch (argCount) {
case 0:
return handle.invoke(proxy);
case 1:
return handle.invoke(proxy, args[0]);
case 2:
return handle.invoke(proxy, args[0], args[1]);
case 3:
return handle.invoke(proxy, args[0], args[1], args[2]);
case 4:
return handle.invoke(proxy, args[0], args[1], args[2], args[3]);
case 5:
return handle.invoke(proxy, args[0], args[1], args[2], args[3], args[4]);
case 6:
return handle.invoke(proxy, args[0], args[1], args[2], args[3], args[4], args[5]);
case 7:
return handle.invoke(proxy, args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
default:
/*
* This has a huge performance hit!
*/
return handle.bindTo(proxy).invokeWithArguments(args);
}
}
}