diff options
45 files changed, 1111 insertions, 606 deletions
diff --git a/build.gradle b/build.gradle index 5686edf..d9b563e 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,8 @@ buildscript { } dependencies { classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'org.jetbrains.dokka:dokka-gradle-plugin:0.10.1' } } plugins { @@ -17,8 +18,9 @@ plugins { apply plugin: 'net.minecraftforge.gradle' apply plugin: 'kotlin' +apply plugin: 'org.jetbrains.dokka' -version = '1.2.1' +version = "1.2.2" group = 'thedarkcolour.kotlinforforge' archivesBaseName = 'kotlinforforge' @@ -40,7 +42,7 @@ minecraft { } server { - workingDirectory project.file('run') + workingDirectory project.file('run/server') property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP' @@ -62,17 +64,21 @@ minecraft { repositories { mavenCentral() maven { - name = "Yarn Mappings" - url = "https://maven.tterrag.com/" + name = 'Yarn Mappings' + url = 'https://maven.tterrag.com/' + } + maven { + name = 'Kotlin Early Access' + url = 'https://dl.bintray.com/kotlin/kotlin-eap' } maven { - name = "Kotlin Early Access" - url = "https://dl.bintray.com/kotlin/kotlin-eap" + name = 'Dokka' + url = 'https://dl.bintray.com/kotlin/dokka' } } dependencies { - minecraft 'net.minecraftforge:forge:1.15.2-31.1.14' + minecraft 'net.minecraftforge:forge:1.15.2-31.2.5' compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib", version: kotlin_version compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk7", version: kotlin_version @@ -81,30 +87,24 @@ dependencies { compile group: "org.jetbrains", name: "annotations", version: annotations_version compile group: "org.jetbrains.kotlinx", name: "kotlinx-coroutines-core", version: coroutines_version compile group: "org.jetbrains.kotlinx", name: "kotlinx-coroutines-jdk8", version: coroutines_version - - // Used to generate html files - compile group: 'org.jsoup', name: 'jsoup', version: '1.11.3' } shadowJar { classifier = "obf" dependencies { - include(dependency("org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}")) - include(dependency("org.jetbrains.kotlin:kotlin-stdlib-jdk7:${kotlin_version}")) - include(dependency("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}")) - include(dependency("org.jetbrains.kotlin:kotlin-reflect:${kotlin_version}")) - include(dependency("org.jetbrains:annotations:${annotations_version}")) - include(dependency("org.jetbrains.kotlinx:kotlinx-coroutines-core:${coroutines_version}")) - include(dependency("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:${coroutines_version}")) + include dependency("org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}") + include dependency("org.jetbrains.kotlin:kotlin-stdlib-jdk7:${kotlin_version}") + include dependency("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}") + include dependency("org.jetbrains.kotlin:kotlin-reflect:${kotlin_version}") + include dependency("org.jetbrains:annotations:${annotations_version}") + include dependency("org.jetbrains.kotlinx:kotlinx-coroutines-core:${coroutines_version}") + include dependency("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:${coroutines_version}") } } jar { manifest { - attributes([ - "FMLModType": "LANGPROVIDER" - ]) - + attributes(["FMLModType": "LANGPROVIDER"]) attributes([ "Specification-Title": "Mod Language Provider", "Specification-Vendor": "Forge", @@ -119,11 +119,25 @@ jar { compileKotlin { kotlinOptions { - freeCompilerArgs = ["-Xinline-classes"] jvmTarget = '1.8' } // Required to run in dev environment copy { from "$buildDir/classes/kotlin/main" into "$buildDir/classes/java/main" } +} + +kotlinSourcesJar { + from(sourceSets.main.kotlin.srcDirs) +} + +dokka { + outputFormat = 'html' + outputDirectory = "$buildDir/dokka" + + configuration { + reportUndocumented = true + + samples = ["$rootDir/src/test/kotlin/thedarkcolour/kotlinforforge/ExampleMod.kt".toString()] + } }
\ No newline at end of file diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..3f38229 --- /dev/null +++ b/changelog.txt @@ -0,0 +1,26 @@ +Kotlin for Forge 1.2.2 +- Added a sided delegate class that returns a "client value" on the client side and a "server value" on the server side. +- Added a new utility file called "Kotlin.kt" that provides a few utility functions not related to Minecraft Forge. +- Added an example mod. I will make a template GitHub repository for Kotlin for Forge soon. +- Adjusted mod construction to accurately report exceptions in @Mod object initializers +- Restructured Kotlin for Forge code to use Kotlin APIs whenever possible +- Added styling to the maven repo + +Kotlin for Forge 1.2.1 +- Added backwards compatibility to mods that used versions of Kotlin for Forge before 1.2.0 + +Kotlin for Forge 1.2.0 +- Added a Kotlin implementation of the Forge EventBus that has working addListener and addGenericListener functions +- Added an overload of addGenericListener that uses a reified type parameter instead of a class parameter. +- Updated to Kotlin 1.4M1 + +Kotlin for Forge 1.1.0 +- Events now properly fire through KotlinModContainer +- Updated to Kotlin 1.3.70 Updated to coroutines 1.3.4 Updated to Jetbrains annotation 19.0.0 + +Kotlin for Forge 1.0.1 +- Fixed an issue with language extensions +- Fixed an internal crash + +Kotlin for Forge 1.0.0 +- Initial release for 1.14 and 1.15
\ No newline at end of file @@ -2,7 +2,11 @@ <link rel="stylesheet" href="thedarkcolour/style.css"> <head><title>Index of /thedarkcolour/</title></head> <body> -<h1>Index of /thedarkcolour/</h1><hr><pre><a href="index.html">../</a> +<h1>Index of /thedarkcolour/</h1> +<hr> +<pre><a href="index.html">../</a> <a href="thedarkcolour/web.html">thedarkcolour</a> -</pre><hr></body> +</pre> +<hr> +</body> </html> diff --git a/src/example/kotlin/thedarkcolour/kotlinforforge/ExampleMod.kt b/src/example/kotlin/thedarkcolour/kotlinforforge/ExampleMod.kt new file mode 100644 index 0000000..af01493 --- /dev/null +++ b/src/example/kotlin/thedarkcolour/kotlinforforge/ExampleMod.kt @@ -0,0 +1,80 @@ +package thedarkcolour.kotlinforforge + +import net.minecraft.block.Block +import net.minecraftforge.event.RegistryEvent +import net.minecraftforge.eventbus.api.SubscribeEvent +import net.minecraftforge.fml.common.Mod +import net.minecraftforge.fml.event.server.FMLServerStartingEvent +import thedarkcolour.kotlinforforge.forge.MOD_BUS +import thedarkcolour.kotlinforforge.forge.lazySidedDelegate +import thedarkcolour.kotlinforforge.proxy.ClientProxy +import thedarkcolour.kotlinforforge.proxy.IProxy +import thedarkcolour.kotlinforforge.proxy.ServerProxy + +/** + * Example mod for anyone who'd like to see + * how a mod would be made with Kotlin for Forge. + * + * This mod has a modid of "examplemod", listens + * for the ``RegistryEvent.Register<Block>`` and + * for the ``FMLServerStartingEvent``. + * + * It registers event listeners by adding event listeners + * directly to the event buses KFF provides and + * by using the ``@EventBusSubscriber`` annotation. + */ +@Mod(ExampleMod.ID) +object ExampleMod { + /** + * Your mod's ID + */ + const val ID = "examplemod" + + /** + * The sided proxy. Since we use a lazy sided delegate, + * the supplier parameters are invoked only once. + */ + private val proxy by lazySidedDelegate(::ClientProxy, ::ServerProxy) + + /** + * Example of using the KotlinEventBus + * to register a function reference. + * + * Event classes with a generic type + * should be registered using ``addGenericListener`` + * instead of ``addListener``. + */ + init { + MOD_BUS.addGenericListener(::registerBlocks) + + proxy.modConstruction() + } + + /** + * Handle block registry here. + */ + private fun registerBlocks(event: RegistryEvent.Register<Block>) { + // ... + } + + /** + * Example of an object class using the + * ``@Mod.EventBusSubscriber`` annotation + * to automatically subscribe functions + * to the forge event bus. + * + * Even though the ``Bus.FORGE`` event bus + * is default, I think that it's still + * a good practice to specify the bus explicitly. + */ + @Mod.EventBusSubscriber(modid = ExampleMod.ID, bus = Mod.EventBusSubscriber.Bus.FORGE) + object EventHandler { + /** + * Handles things like registering commands. + */ + @SubscribeEvent + fun onServerStarting(event: FMLServerStartingEvent) { + // ... + } + } +}
\ No newline at end of file diff --git a/src/example/kotlin/thedarkcolour/kotlinforforge/package.md b/src/example/kotlin/thedarkcolour/kotlinforforge/package.md new file mode 100644 index 0000000..c9c1caa --- /dev/null +++ b/src/example/kotlin/thedarkcolour/kotlinforforge/package.md @@ -0,0 +1,7 @@ +# thedarkcolour.kotlinforforge +This package contains an example main mod class +for a mod using Kotlin for Forge. + +## ExampleMod +Your main mod class should be an object declaration. +It must be annotated with the @Mod annotation.
\ No newline at end of file diff --git a/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/Proxies.kt b/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/Proxies.kt new file mode 100644 index 0000000..24c51b7 --- /dev/null +++ b/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/Proxies.kt @@ -0,0 +1,20 @@ +package thedarkcolour.kotlinforforge.proxy + +/** + * Common inheritor of both proxies. + */ +interface IProxy { + fun modConstruction() +} + +class ClientProxy : IProxy { + override fun modConstruction() { + // run client code + } +} + +class ServerProxy : IProxy { + override fun modConstruction() { + // run server code + } +}
\ No newline at end of file diff --git a/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/package.md b/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/package.md new file mode 100644 index 0000000..bb57203 --- /dev/null +++ b/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/package.md @@ -0,0 +1,12 @@ +# thedarkcolour.kotlinforforge.proxy +This package has example proxy classes. +Proxies are used to provide common declarations with sided implementations. + +Forge no longer supports the proxy pattern. +The ``@SidedProxy`` annotation was removed in 1.13+. +This example shows a use case for the ``lazySidedDelegate``. +It is recommended to use the ``runWhenOn`` and ``callWhenOn`` functions +instead of proxies whenever possible. + +In this example, a proxy is instantiated lazily in the ``ExampleMod`` class. +Proxies are not the only use for sided delegates.
\ No newline at end of file diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt index 547918f..01a10c0 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt @@ -4,56 +4,60 @@ import net.minecraftforge.api.distmarker.Dist import net.minecraftforge.fml.Logging import net.minecraftforge.fml.ModContainer import net.minecraftforge.fml.common.Mod -import net.minecraftforge.fml.loading.FMLEnvironment import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation import net.minecraftforge.forgespi.language.ModFileScanData import org.objectweb.asm.Type +import thedarkcolour.kotlinforforge.forge.DIST import thedarkcolour.kotlinforforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.forge.MOD_BUS -import java.util.* -import java.util.stream.Collectors +import thedarkcolour.kotlinforforge.kotlin.enumSet /** - * Handles [net.minecraftforge.fml.common.Mod.EventBusSubscriber] annotations for object declarations. + * Automatically registers `object` classes to + * Kotlin for Forge's event buses. + * + * @see MOD_BUS + * @see FORGE_BUS */ -public object AutoKotlinEventBusSubscriber { +object AutoKotlinEventBusSubscriber { private val EVENT_BUS_SUBSCRIBER: Type = Type.getType(Mod.EventBusSubscriber::class.java) + private val DIST_ENUM_HOLDERS = listOf( + ModAnnotation.EnumHolder(null, "CLIENT"), + ModAnnotation.EnumHolder(null, "DEDICATED_SERVER") + ) /** - * Registers Kotlin objects and companion objects that are annotated with [Mod.EventBusSubscriber] - * This allows you to declare an object that subscribes to the event bus - * without making all the [net.minecraftforge.eventbus.api.SubscribeEvent] annotated with [JvmStatic] + * Allows the Mod.EventBusSubscriber annotation + * to target member functions of an `object` class. * - * Example Usage: + * You **must** be using an `object` class, or the + * EventBusSubscriber annotation will ignore it. * - * @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) - * object ExampleSubscriber { - * @SubscribeEvent - * public fun onItemRegistry(event: RegistryEvent.Register<Item>) { - * println("Look! We're in items!") - * } - * } + * Personally, I am against using [Mod.EventBusSubscriber] + * because it makes + * + * @sample thedarkcolour.kotlinforforge.ExampleMod */ - public fun inject(mod: ModContainer, scanData: ModFileScanData, classLoader: ClassLoader) { + fun inject(mod: ModContainer, scanData: ModFileScanData, classLoader: ClassLoader) { LOGGER.debug(Logging.LOADING, "Attempting to inject @EventBusSubscriber kotlin objects in to the event bus for ${mod.modId}") - val data: ArrayList<ModFileScanData.AnnotationData> = scanData.annotations.stream() - .filter { annotationData -> - EVENT_BUS_SUBSCRIBER == annotationData.annotationType - } - .collect(Collectors.toList()) as ArrayList<ModFileScanData.AnnotationData> + + val data = scanData.annotations.filter { annotationData -> + EVENT_BUS_SUBSCRIBER == annotationData.annotationType + } + data.forEach { annotationData -> - val sidesValue: List<ModAnnotation.EnumHolder> = annotationData.annotationData.getOrDefault("value", listOf(ModAnnotation.EnumHolder(null, "CLIENT"), ModAnnotation.EnumHolder(null, "DEDICATED_SERVER"))) as List<ModAnnotation.EnumHolder> - val sides: EnumSet<Dist> = sidesValue.stream().map { eh -> Dist.valueOf(eh.value) } - .collect(Collectors.toCollection { EnumSet.noneOf(Dist::class.java) }) + val sidesValue = annotationData.annotationData.getOrDefault("value", DIST_ENUM_HOLDERS) as List<ModAnnotation.EnumHolder> + val sides = enumSet<Dist>().plus(sidesValue.map { eh -> Dist.valueOf(eh.value) }) val modid = annotationData.annotationData.getOrDefault("modid", mod.modId) - val busTargetHolder: ModAnnotation.EnumHolder = annotationData.annotationData.getOrDefault("bus", ModAnnotation.EnumHolder(null, "FORGE")) as ModAnnotation.EnumHolder + val busTargetHolder = annotationData.annotationData.getOrDefault("bus", ModAnnotation.EnumHolder(null, "FORGE")) as ModAnnotation.EnumHolder val busTarget = Mod.EventBusSubscriber.Bus.valueOf(busTargetHolder.value) val ktObject = Class.forName(annotationData.classType.className, true, classLoader).kotlin.objectInstance - if (ktObject != null && mod.modId == modid && sides.contains(FMLEnvironment.dist)) { + + if (ktObject != null && mod.modId == modid && DIST in sides) { try { LOGGER.debug(Logging.LOADING, "Auto-subscribing kotlin object ${annotationData.classType.className} to $busTarget") + if (busTarget == Mod.EventBusSubscriber.Bus.MOD) { - // Gets the correct mod loading context MOD_BUS.register(ktObject) } else { FORGE_BUS.register(ktObject) diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt index 51840d9..6a60e4b 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt @@ -1,11 +1,7 @@ package thedarkcolour.kotlinforforge -import net.minecraft.block.Block -import net.minecraft.block.material.Material -import net.minecraftforge.event.RegistryEvent import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext -import thedarkcolour.kotlinforforge.forge.MOD_BUS /** * Set 'modLoader' in mods.toml to "kotlinforforge" and loaderVersion to "[1,)". @@ -13,12 +9,4 @@ import thedarkcolour.kotlinforforge.forge.MOD_BUS * Make sure to use [KotlinModLoadingContext] instead of [FMLJavaModLoadingContext]. */ @Mod("kotlinforforge") -object KotlinForForge { - init { - MOD_BUS.addGenericListener(::registerBlocks) - } - - private fun registerBlocks(event: RegistryEvent.Register<Block>) { - event.registry.register(Block(Block.Properties.create(Material.ROCK)).setRegistryName("bruh")) - } -}
\ No newline at end of file +object KotlinForForge
\ No newline at end of file diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt index d393cbd..a06c9a3 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt @@ -2,35 +2,39 @@ package thedarkcolour.kotlinforforge import net.minecraftforge.fml.Logging import net.minecraftforge.fml.javafmlmod.FMLJavaModLanguageProvider -import net.minecraftforge.forgespi.language.ILifecycleEvent import net.minecraftforge.forgespi.language.IModInfo import net.minecraftforge.forgespi.language.IModLanguageProvider import net.minecraftforge.forgespi.language.ModFileScanData import java.util.function.Consumer -import java.util.function.Supplier -import java.util.stream.Collectors -public class KotlinLanguageProvider : FMLJavaModLanguageProvider() { +/** + * Reuse a bit of code from FMLJavaModLanguageProvider + */ +class KotlinLanguageProvider : FMLJavaModLanguageProvider() { + override fun name() = "kotlinforforge" + override fun getFileVisitor(): Consumer<ModFileScanData> { - return Consumer { scanResult -> - val target = scanResult.annotations.stream() - .filter { data -> data.annotationType == MODANNOTATION } - .peek { data -> LOGGER.debug(Logging.SCAN, "Found @Mod class ${data.classType.className} with id ${data.annotationData["value"]}") } - .map { data -> KotlinModTarget(data.classType.className, data.annotationData["value"] as String) } - .collect(Collectors.toMap({ target: KotlinModTarget -> target.modId }, { it }, { a, _ -> a })) - scanResult.addLanguageLoader(target) + return Consumer { scanData -> + val id2TargetMap = scanData.annotations.filter { data -> + data.annotationType == MODANNOTATION + }.map { data -> + val modid = data.annotationData["value"] as String + val modClass = data.classType.className + LOGGER.debug(Logging.SCAN, "Found @Mod class $modClass with mod id $modid") + modid to KotlinModTarget(modClass) + }.toMap() + + scanData.addLanguageLoader(id2TargetMap) } } - override fun <R : ILifecycleEvent<R>?> consumeLifecycleEvent(consumeEvent: Supplier<R>?) {} - - override fun name(): String = "kotlinforforge" - - public class KotlinModTarget constructor(private val className: String, val modId: String) : IModLanguageProvider.IModLanguageLoader { + class KotlinModTarget constructor(private val className: String) : IModLanguageProvider.IModLanguageLoader { override fun <T> loadMod(info: IModInfo, modClassLoader: ClassLoader, modFileScanResults: ModFileScanData): T { val ktContainer = Class.forName("thedarkcolour.kotlinforforge.KotlinModContainer", true, Thread.currentThread().contextClassLoader) + val constructor = ktContainer.declaredConstructors[0] + LOGGER.debug(Logging.LOADING, "Loading KotlinModContainer from classloader ${Thread.currentThread().contextClassLoader} - got ${ktContainer.classLoader}}") - val constructor = ktContainer.declaredConstructors[0]//(IModInfo::class.java, String::class.java, ClassLoader::class.java, ModFileScanData::class.java)!! + return constructor.newInstance(info, className, modClassLoader, modFileScanResults) as T } } diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt index 9802d90..e86f66a 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt @@ -5,13 +5,19 @@ import net.minecraftforge.eventbus.api.BusBuilder import net.minecraftforge.eventbus.api.Event import net.minecraftforge.eventbus.api.IEventBus import net.minecraftforge.eventbus.api.IEventListener -import net.minecraftforge.fml.* +import net.minecraftforge.fml.LifecycleEventProvider.LifecycleEvent +import net.minecraftforge.fml.Logging +import net.minecraftforge.fml.ModContainer +import net.minecraftforge.fml.ModLoadingException +import net.minecraftforge.fml.ModLoadingStage import net.minecraftforge.fml.config.ModConfig import net.minecraftforge.forgespi.language.IModInfo import net.minecraftforge.forgespi.language.ModFileScanData import thedarkcolour.kotlinforforge.eventbus.KotlinEventBus +import thedarkcolour.kotlinforforge.kotlin.supply import java.util.function.Consumer -import java.util.function.Supplier + +typealias LifeCycleEventListener = (LifecycleEvent) -> Unit /** * Functions as [net.minecraftforge.fml.javafmlmod.FMLModContainer] for Kotlin @@ -22,27 +28,34 @@ class KotlinModContainer(private val info: IModInfo, private val className: Stri init { LOGGER.debug(Logging.LOADING, "Creating KotlinModContainer instance for {} with classLoader {} & {}", className, classLoader, javaClass.classLoader) - triggerMap[ModLoadingStage.CONSTRUCT] = dummy().andThen(::constructMod).andThen(::afterEvent) - triggerMap[ModLoadingStage.CREATE_REGISTRIES] = dummy().andThen(::fireEvent).andThen(::afterEvent) - triggerMap[ModLoadingStage.LOAD_REGISTRIES] = dummy().andThen(::fireEvent).andThen(::afterEvent) - triggerMap[ModLoadingStage.COMMON_SETUP] = dummy().andThen(::fireEvent).andThen(::afterEvent) - triggerMap[ModLoadingStage.SIDED_SETUP] = dummy().andThen(::fireEvent).andThen(::afterEvent) - triggerMap[ModLoadingStage.ENQUEUE_IMC] = dummy().andThen(::fireEvent).andThen(::afterEvent) - triggerMap[ModLoadingStage.PROCESS_IMC] = dummy().andThen(::fireEvent).andThen(::afterEvent) - triggerMap[ModLoadingStage.COMPLETE] = dummy().andThen(::fireEvent).andThen(::afterEvent) - triggerMap[ModLoadingStage.GATHERDATA] = dummy().andThen(::fireEvent).andThen(::afterEvent) + triggerMap[ModLoadingStage.CONSTRUCT] = createTrigger(::constructMod, ::afterEvent) + triggerMap[ModLoadingStage.CREATE_REGISTRIES] = createTrigger(::fireEvent, ::afterEvent) + triggerMap[ModLoadingStage.LOAD_REGISTRIES] = createTrigger(::fireEvent, ::afterEvent) + triggerMap[ModLoadingStage.COMMON_SETUP] = createTrigger(::fireEvent, ::afterEvent) + triggerMap[ModLoadingStage.SIDED_SETUP] = createTrigger(::fireEvent, ::afterEvent) + triggerMap[ModLoadingStage.ENQUEUE_IMC] = createTrigger(::fireEvent, ::afterEvent) + triggerMap[ModLoadingStage.PROCESS_IMC] = createTrigger(::fireEvent, ::afterEvent) + triggerMap[ModLoadingStage.COMPLETE] = createTrigger(::fireEvent, ::afterEvent) + triggerMap[ModLoadingStage.GATHERDATA] = createTrigger(::fireEvent, ::afterEvent) eventBus = KotlinEventBus(BusBuilder.builder().setExceptionHandler(::onEventFailed).setTrackPhases(false)) - val ctx = KotlinModLoadingContext(this) - contextExtension = Supplier { ctx } + contextExtension = supply(KotlinModLoadingContext(this)) } - private fun dummy(): Consumer<LifecycleEventProvider.LifecycleEvent> = Consumer {} + private inline fun |
