Forgelin/src/main/kotlin/net/shadowfacts/forgelin/KotlinAdapter.kt

67 lines
2.3 KiB
Kotlin
Raw Normal View History

2016-08-06 14:28:05 +00:00
package net.shadowfacts.forgelin
import net.minecraftforge.fml.common.FMLModContainer
import net.minecraftforge.fml.common.ILanguageAdapter
import net.minecraftforge.fml.common.ModContainer
import net.minecraftforge.fml.relauncher.Side
import org.apache.logging.log4j.LogManager
import java.lang.reflect.Field
import java.lang.reflect.Method
/**
2016-11-14 15:53:45 +00:00
* Forge {@link ILanguageAdapter} for Kotlin
* Usage: Set the {@code modLanguageAdapter} field in your {@code @Mod} annotation to {@code net.shadowfacts.forgelin.KotlinAdapter}
* @author shadowfacts
2016-08-06 14:28:05 +00:00
*/
class KotlinAdapter : ILanguageAdapter {
2016-08-06 14:28:05 +00:00
2016-11-14 15:53:45 +00:00
private val log = LogManager.getLogger("KotlinAdapter")
2016-08-06 14:28:05 +00:00
override fun supportsStatics(): Boolean {
return false
}
override fun setProxy(target: Field, proxyTarget: Class<*>, proxy: Any) {
2016-11-14 15:53:45 +00:00
log.debug("Setting proxy: ${target.declaringClass.simpleName}.${target.name} -> $proxy")
if (proxyTarget.fields.any { x -> x.name == "INSTANCE" }) {
2016-08-06 14:28:05 +00:00
// Singleton
try {
2016-11-14 15:53:45 +00:00
log.debug("Setting proxy on INSTANCE; singleton target")
2016-08-06 20:33:12 +00:00
val obj = proxyTarget.getField("INSTANCE").get(null)
2016-08-06 14:28:05 +00:00
target.set(obj, proxy)
2016-11-14 15:53:45 +00:00
} catch (e: Exception) {
throw KotlinAdapterException(e)
2016-08-06 14:28:05 +00:00
}
} else {
target.set(proxyTarget, proxy)
}
}
2016-11-14 15:53:45 +00:00
override fun getNewInstance(container: FMLModContainer, objectClass: Class<*>, classLoader: ClassLoader, factoryMarkedAnnotation: Method?): Any {
log.debug("FML has asked for ${objectClass.simpleName} to be constructed")
2016-08-06 14:28:05 +00:00
try {
// Try looking for an object type
2016-08-06 20:33:12 +00:00
val f = objectClass.getField("INSTANCE")
val obj = f.get(null) ?: throw NullPointerException()
2016-11-14 15:53:45 +00:00
log.debug("Found an object INSTANCE reference in ${objectClass.simpleName}, using that. ${obj}")
2016-08-06 14:28:05 +00:00
return obj
2016-11-14 15:53:45 +00:00
} catch (e: Exception) {
2016-08-06 14:28:05 +00:00
// Try looking for a class type
2016-11-14 15:53:45 +00:00
log.debug("Failed to get object reference, trying class construction")
2016-08-06 14:28:05 +00:00
try {
val obj = objectClass.newInstance() ?: throw NullPointerException()
2016-11-14 15:53:45 +00:00
log.debug("Constructed an object from a class type ($objectClass), using that. $obj")
2016-08-06 14:28:05 +00:00
return obj
2016-11-14 15:53:45 +00:00
} catch (e: Exception) {
throw KotlinAdapterException(e)
2016-08-06 14:28:05 +00:00
}
}
}
override fun setInternalProxies(mod: ModContainer?, side: Side?, loader: ClassLoader?) {
2016-11-14 15:53:45 +00:00
// Nothing to do; FML's got this covered for Kotlin
2016-08-06 14:28:05 +00:00
}
2016-11-14 15:53:45 +00:00
private class KotlinAdapterException(e: Exception) : RuntimeException("Kotlin adapter error - do not report to Forge!", e)
2016-08-06 14:28:05 +00:00
}