Little refactor
This commit is contained in:
parent
fb1184288c
commit
d2da5a71e2
|
@ -3,7 +3,6 @@ package net.shadowfacts.forgelin
|
||||||
import net.minecraftforge.eventbus.EventBusErrorMessage
|
import net.minecraftforge.eventbus.EventBusErrorMessage
|
||||||
import net.minecraftforge.eventbus.api.Event
|
import net.minecraftforge.eventbus.api.Event
|
||||||
import net.minecraftforge.eventbus.api.IEventBus
|
import net.minecraftforge.eventbus.api.IEventBus
|
||||||
import net.minecraftforge.eventbus.api.IEventExceptionHandler
|
|
||||||
import net.minecraftforge.eventbus.api.IEventListener
|
import net.minecraftforge.eventbus.api.IEventListener
|
||||||
import net.minecraftforge.fml.*
|
import net.minecraftforge.fml.*
|
||||||
import net.minecraftforge.fml.Logging.LOADING
|
import net.minecraftforge.fml.Logging.LOADING
|
||||||
|
@ -15,19 +14,19 @@ import java.util.*
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
class FMLKotlinModContainer(
|
class FMLKotlinModContainer(
|
||||||
private val info: IModInfo,
|
info: IModInfo,
|
||||||
private val className: String,
|
private val className: String,
|
||||||
private val modClassLoader: ClassLoader,
|
modClassLoader: ClassLoader,
|
||||||
private val scanResults: ModFileScanData
|
private val scanResults: ModFileScanData
|
||||||
) : ModContainer(info) {
|
) : ModContainer(info) {
|
||||||
private val log = LogManager.getLogger()
|
private val logger = LogManager.getLogger()
|
||||||
|
|
||||||
val eventBus: IEventBus
|
val eventBus: IEventBus
|
||||||
private var mod: Any? = null
|
private var mod: Any? = null
|
||||||
private val modClass: Class<*>
|
private val modClass: Class<*>
|
||||||
|
|
||||||
init {
|
init {
|
||||||
log.debug(LOADING, "Creating FMLModContainer instance for {} with classLoader {} & {}", className, modClassLoader, javaClass.classLoader)
|
logger.debug(LOADING, "Creating FMLModContainer instance for {} with classLoader {} & {}", className, modClassLoader, javaClass.classLoader)
|
||||||
triggerMap[ModLoadingStage.CONSTRUCT] = dummy().andThen(::beforeEvent).andThen(::constructMod).andThen(::afterEvent)
|
triggerMap[ModLoadingStage.CONSTRUCT] = dummy().andThen(::beforeEvent).andThen(::constructMod).andThen(::afterEvent)
|
||||||
triggerMap[ModLoadingStage.CREATE_REGISTRIES] = dummy().andThen(::beforeEvent).andThen(::fireEvent).andThen(::afterEvent)
|
triggerMap[ModLoadingStage.CREATE_REGISTRIES] = dummy().andThen(::beforeEvent).andThen(::fireEvent).andThen(::afterEvent)
|
||||||
triggerMap[ModLoadingStage.LOAD_REGISTRIES] = dummy().andThen(::beforeEvent).andThen(::fireEvent).andThen(::afterEvent)
|
triggerMap[ModLoadingStage.LOAD_REGISTRIES] = dummy().andThen(::beforeEvent).andThen(::fireEvent).andThen(::afterEvent)
|
||||||
|
@ -43,20 +42,34 @@ class FMLKotlinModContainer(
|
||||||
// Here, we won't init the class, meaning static {} blocks (init {} in kotlin) won't get triggered
|
// Here, we won't init the class, meaning static {} blocks (init {} in kotlin) won't get triggered
|
||||||
// but we will still have to do it later, on CONSTRUCT phase.
|
// but we will still have to do it later, on CONSTRUCT phase.
|
||||||
modClass = Class.forName(className, false, modClassLoader)
|
modClass = Class.forName(className, false, modClassLoader)
|
||||||
log.debug(LOADING, "Loaded modclass {} with {}", modClass.name, modClass.classLoader)
|
logger.debug(LOADING, "Loaded modclass {} with {}", modClass.name, modClass.classLoader)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log.error(LOADING, "Failed to load class {}", className, e)
|
logger.error(LOADING, "Failed to load class {}", className, e)
|
||||||
throw ModLoadingException(info, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmodclass", e)
|
throw ModLoadingException(info, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmodclass", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun dummy(): Consumer<LifecycleEventProvider.LifecycleEvent> = Consumer {}
|
private fun constructMod(event: LifecycleEventProvider.LifecycleEvent) {
|
||||||
|
try {
|
||||||
|
logger.debug(LOADING, "Loading mod instance {} of type {}", getModId(), modClass.name)
|
||||||
|
// Now we can load the class, so that static {} block gets called
|
||||||
|
Class.forName(className)
|
||||||
|
// Then we check whether it's a kotlin object and return it, or if not we create a new instance of kotlin class.
|
||||||
|
this.mod = modClass.kotlin.objectInstance ?: modClass.newInstance()
|
||||||
|
logger.debug(LOADING, "Loaded mod instance {} of type {}", getModId(), modClass.name)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
logger.error(LOADING, "Failed to create mod instance. ModID: {}, class {}", getModId(), modClass.name, e)
|
||||||
|
throw ModLoadingException(modInfo, event.fromStage(), "fml.modloading.failedtoloadmod", e, modClass)
|
||||||
|
}
|
||||||
|
|
||||||
private fun onEventFailed(iEventBus: IEventBus, event: Event, iEventListeners: Array<IEventListener>, i: Int, throwable: Throwable) {
|
logger.debug(LOADING, "Injecting Automatic event subscribers for {}", getModId())
|
||||||
log.error(EventBusErrorMessage(event, i, iEventListeners, throwable))
|
ForgelinAutomaticEventSubscriber.inject(this, this.scanResults, this.modClass.classLoader)
|
||||||
|
logger.debug(LOADING, "Completed Automatic event subscribers for {}", getModId())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun dummy(): Consumer<LifecycleEventProvider.LifecycleEvent> = Consumer {}
|
||||||
|
|
||||||
private fun beforeEvent(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) {
|
private fun beforeEvent(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) {
|
||||||
FMLKotlinModLoadingContext.get().activeContainer = this
|
FMLKotlinModLoadingContext.get().activeContainer = this
|
||||||
ModThreadContext.get().activeContainer = this
|
ModThreadContext.get().activeContainer = this
|
||||||
|
@ -64,12 +77,12 @@ class FMLKotlinModContainer(
|
||||||
|
|
||||||
private fun fireEvent(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) {
|
private fun fireEvent(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) {
|
||||||
val event = lifecycleEvent.getOrBuildEvent(this)
|
val event = lifecycleEvent.getOrBuildEvent(this)
|
||||||
log.debug(LOADING, "Firing event for modid {} : {}", this.getModId(), event)
|
logger.debug(LOADING, "Firing event for modid {} : {}", this.getModId(), event)
|
||||||
try {
|
try {
|
||||||
eventBus.post(event)
|
eventBus.post(event)
|
||||||
log.debug(LOADING, "Fired event for modid {} : {}", this.getModId(), event)
|
logger.debug(LOADING, "Fired event for modid {} : {}", this.getModId(), event)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
log.error(LOADING, "Caught exception during event {} dispatch for modid {}", event, this.getModId(), e)
|
logger.error(LOADING, "Caught exception during event {} dispatch for modid {}", event, this.getModId(), e)
|
||||||
throw ModLoadingException(modInfo, lifecycleEvent.fromStage(), "fml.modloading.errorduringevent", e)
|
throw ModLoadingException(modInfo, lifecycleEvent.fromStage(), "fml.modloading.errorduringevent", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,29 +92,14 @@ class FMLKotlinModContainer(
|
||||||
ModThreadContext.get().activeContainer = null
|
ModThreadContext.get().activeContainer = null
|
||||||
FMLKotlinModLoadingContext.get().activeContainer = null
|
FMLKotlinModLoadingContext.get().activeContainer = null
|
||||||
if (currentState == ModLoadingStage.ERROR) {
|
if (currentState == ModLoadingStage.ERROR) {
|
||||||
log.error(LOADING, "An error occurred while dispatching event {} to {}", lifecycleEvent.fromStage(), getModId())
|
logger.error(LOADING, "An error occurred while dispatching event {} to {}", lifecycleEvent.fromStage(), getModId())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun constructMod(event: LifecycleEventProvider.LifecycleEvent) {
|
private fun onEventFailed(iEventBus: IEventBus, event: Event, iEventListeners: Array<IEventListener>, i: Int, throwable: Throwable) {
|
||||||
try {
|
logger.error(EventBusErrorMessage(event, i, iEventListeners, throwable))
|
||||||
log.debug(LOADING, "Loading mod instance {} of type {}", getModId(), modClass.name)
|
|
||||||
// Now we can load the class, so that static {} block gets called
|
|
||||||
Class.forName(className)
|
|
||||||
// Then we check whether it's a kotlin object and return it, or if not we create a new instance of kotlin class.
|
|
||||||
this.mod = modClass.kotlin.objectInstance ?: modClass.newInstance()
|
|
||||||
log.debug(LOADING, "Loaded mod instance {} of type {}", getModId(), modClass.name)
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
log.error(LOADING, "Failed to create mod instance. ModID: {}, class {}", getModId(), modClass.name, e)
|
|
||||||
throw ModLoadingException(modInfo, event.fromStage(), "fml.modloading.failedtoloadmod", e, modClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug(LOADING, "Injecting Automatic event subscribers for {}", getModId())
|
|
||||||
ForgelinAutomaticEventSubscriber.inject(this, this.scanResults, this.modClass.classLoader)
|
|
||||||
log.debug(LOADING, "Completed Automatic event subscribers for {}", getModId())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun matches(mod: Any): Boolean = mod === this.mod
|
override fun matches(mod: Any): Boolean = mod === this.mod
|
||||||
|
|
||||||
override fun getMod(): Any? = mod
|
override fun getMod(): Any? = mod
|
||||||
}
|
}
|
|
@ -10,23 +10,16 @@ import java.util.function.Consumer
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
import java.util.stream.Collectors
|
import java.util.stream.Collectors
|
||||||
|
|
||||||
/**
|
|
||||||
* Forge {@link ILanguageAdapter} for Kotlin
|
|
||||||
* Usage: Set the {@code modLanguageAdapter} field in your {@code @Mod} annotation to {@code net.shadowfacts.forgelin.FMLKotlinModLanguageProvider}
|
|
||||||
* @author shadowfacts
|
|
||||||
*/
|
|
||||||
class FMLKotlinModLanguageProvider : IModLanguageProvider {
|
class FMLKotlinModLanguageProvider : IModLanguageProvider {
|
||||||
private val log = LogManager.getLogger()
|
private val logger = LogManager.getLogger()
|
||||||
|
|
||||||
override fun name(): String {
|
override fun name(): String = "kotlinfml"
|
||||||
return "kotlinfml"
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getFileVisitor(): Consumer<ModFileScanData> {
|
override fun getFileVisitor(): Consumer<ModFileScanData> {
|
||||||
return Consumer { scanResult ->
|
return Consumer { scanResult ->
|
||||||
val modTargetMap = scanResult.annotations.stream()
|
val modTargetMap = scanResult.annotations.stream()
|
||||||
.filter { ad -> ad.annotationType == FMLJavaModLanguageProvider.MODANNOTATION }
|
.filter { ad -> ad.annotationType == FMLJavaModLanguageProvider.MODANNOTATION }
|
||||||
.peek { ad -> log.debug(SCAN, "Found @Mod class {} with id {}", ad.classType.className, ad.annotationData["value"]) }
|
.peek { ad -> logger.debug(SCAN, "Found @Mod class {} with id {}", ad.classType.className, ad.annotationData["value"]) }
|
||||||
.map { ad -> FMLKotlinModTarget(ad.classType.className, ad.annotationData["value"] as String) }
|
.map { ad -> FMLKotlinModTarget(ad.classType.className, ad.annotationData["value"] as String) }
|
||||||
.collect(Collectors.toMap(java.util.function.Function<FMLKotlinModTarget, String> { it.modId }, java.util.function.Function.identity<FMLKotlinModTarget>()))
|
.collect(Collectors.toMap(java.util.function.Function<FMLKotlinModTarget, String> { it.modId }, java.util.function.Function.identity<FMLKotlinModTarget>()))
|
||||||
scanResult.addLanguageLoader(modTargetMap)
|
scanResult.addLanguageLoader(modTargetMap)
|
||||||
|
|
|
@ -5,10 +5,9 @@ import net.minecraftforge.forgespi.language.IModInfo
|
||||||
import net.minecraftforge.forgespi.language.IModLanguageProvider
|
import net.minecraftforge.forgespi.language.IModLanguageProvider
|
||||||
import net.minecraftforge.forgespi.language.ModFileScanData
|
import net.minecraftforge.forgespi.language.ModFileScanData
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
import java.lang.reflect.InvocationTargetException
|
|
||||||
|
|
||||||
class FMLKotlinModTarget(private val className: String, val modId: String) : IModLanguageProvider.IModLanguageLoader {
|
class FMLKotlinModTarget(private val className: String, val modId: String) : IModLanguageProvider.IModLanguageLoader {
|
||||||
private val log = LogManager.getLogger()
|
private val logger = LogManager.getLogger()
|
||||||
|
|
||||||
override fun <T> loadMod(info: IModInfo, modClassLoader: ClassLoader, modFileScanResults: ModFileScanData): T {
|
override fun <T> loadMod(info: IModInfo, modClassLoader: ClassLoader, modFileScanResults: ModFileScanData): T {
|
||||||
// This language class is loaded in the system level classloader - before the game even starts
|
// This language class is loaded in the system level classloader - before the game even starts
|
||||||
|
@ -16,11 +15,11 @@ class FMLKotlinModTarget(private val className: String, val modId: String) : IMo
|
||||||
// in the classloader of the game - the context classloader is appropriate here.
|
// in the classloader of the game - the context classloader is appropriate here.
|
||||||
try {
|
try {
|
||||||
val fmlContainer = Class.forName("net.shadowfacts.forgelin.FMLKotlinModContainer", true, Thread.currentThread().contextClassLoader)
|
val fmlContainer = Class.forName("net.shadowfacts.forgelin.FMLKotlinModContainer", true, Thread.currentThread().contextClassLoader)
|
||||||
log.debug(LOADING, "Loading FMLKotlinModContainer from classloader {} - got {}", Thread.currentThread().contextClassLoader, fmlContainer.classLoader)
|
logger.debug(LOADING, "Loading FMLKotlinModContainer from classloader {} - got {}", Thread.currentThread().contextClassLoader, fmlContainer.classLoader)
|
||||||
val constructor = fmlContainer.getConstructor(IModInfo::class.java, String::class.java, ClassLoader::class.java, ModFileScanData::class.java)
|
val constructor = fmlContainer.getConstructor(IModInfo::class.java, String::class.java, ClassLoader::class.java, ModFileScanData::class.java)
|
||||||
return constructor.newInstance(info, className, modClassLoader, modFileScanResults) as T
|
return constructor.newInstance(info, className, modClassLoader, modFileScanResults) as T
|
||||||
} catch (e: ReflectiveOperationException) {
|
} catch (e: ReflectiveOperationException) {
|
||||||
log.fatal(LOADING, "Unable to load FMLKotlinModContainer, wut?", e)
|
logger.fatal(LOADING, "Unable to load FMLKotlinModContainer, wut?", e)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue