mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 01:04:24 +00:00
Alternative @SidedProxy setter for Scala.
This commit is contained in:
1 parent
49111e9c5c
commit
23b070c7d0
1 file changed
+47
@@ -1,6 +1,8 @@
|
||||
package cpw.mods.fml.common;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public interface ILanguageAdapter {
|
||||
public Object getNewInstance(FMLModContainer container, Class<?> objectClass, ClassLoader classLoader) throws Exception;
|
||||
@@ -24,6 +26,51 @@ public interface ILanguageAdapter {
|
||||
@Override
|
||||
public void setProxy(Field target, Class<?> proxyTarget, Object proxy) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException
|
||||
{
|
||||
try
|
||||
{
|
||||
// Check if the target class is a singleton, if so its
|
||||
// implementation's class name is the actual classname
|
||||
// postfixed with a $.
|
||||
final Class<?> targetSingleton = Class.forName(proxyTarget.getName() + "$", true, proxyTarget.getClassLoader());
|
||||
|
||||
// Get the instance via the MODULE$ field which is
|
||||
// automatically generated by the scala compiler for
|
||||
// singletons.
|
||||
final Object targetInstance = targetSingleton.getField("MODULE$").get(null);
|
||||
|
||||
// Find setter function. We do it this way because we can't
|
||||
// necessarily use proxyTarget.getMethod(proxy.getClass()), as
|
||||
// it might be a subclass and not the exact parameter type.
|
||||
// All fields are private in scala, wrapped by a getter and
|
||||
// setter named <fieldname> and <fieldname>_$eq. To those
|
||||
// familiar with scala.reflect.BeanProperty: these will always
|
||||
// be there, set<Fieldname> and get<Fieldname> will always
|
||||
// only be generated *additionally*.
|
||||
final String setterName = target.getName() + "_$eq";
|
||||
for (Method setter : proxyTarget.getMethods())
|
||||
{
|
||||
Class<?>[] setterParameters = setter.getParameterTypes();
|
||||
if (setterName.equals(setter.getName()) &&
|
||||
// Some more validation.
|
||||
setterParameters.length == 1 &&
|
||||
setterParameters[0].isAssignableFrom(proxy.getClass()))
|
||||
{
|
||||
// Here goes nothing... if this invocation fails we'll
|
||||
// just fall back to the original functionality.
|
||||
setter.invoke(targetInstance, proxy);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
FMLLog.fine("This scala class is not a singleton (scala object), falling back to old proxy setter.");
|
||||
}
|
||||
catch (InvocationTargetException e)
|
||||
{
|
||||
FMLLog.fine("There's a problem with this proxy's setter, falling back to old proxy setter.");
|
||||
}
|
||||
|
||||
Field field = proxyTarget.getField("INSTANCE");
|
||||
Object scalaObject = field.get(null);
|
||||
target.set(scalaObject, proxy);
|
||||
|
||||
Reference in new issue
Block a user