aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle60
-rw-r--r--changelog.txt26
-rw-r--r--index.html8
-rw-r--r--src/example/kotlin/thedarkcolour/kotlinforforge/ExampleMod.kt80
-rw-r--r--src/example/kotlin/thedarkcolour/kotlinforforge/package.md7
-rw-r--r--src/example/kotlin/thedarkcolour/kotlinforforge/proxy/Proxies.kt20
-rw-r--r--src/example/kotlin/thedarkcolour/kotlinforforge/proxy/package.md12
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt60
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt14
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt38
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt62
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModLoadingContext.kt16
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBus.kt46
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/package.md2
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt169
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/forge/package.md11
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/Kotlin.kt85
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/package.md6
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/package.md2
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/webgenerator/WebGenerator.kt68
-rw-r--r--src/main/resources/META-INF/mods.toml6
-rw-r--r--src/main/resources/pack.mcmeta5
-rw-r--r--thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.pom101
-rw-r--r--thedarkcolour/kotlinforforge/1.0.0/web.html8
-rw-r--r--thedarkcolour/kotlinforforge/1.0.1/kotlinforforge-1.0.1.pom101
-rw-r--r--thedarkcolour/kotlinforforge/1.0.1/web.html8
-rw-r--r--thedarkcolour/kotlinforforge/1.1.0/kotlinforforge-1.1.0.pom101
-rw-r--r--thedarkcolour/kotlinforforge/1.1.0/web.html8
-rw-r--r--thedarkcolour/kotlinforforge/1.2.0/kotlinforforge-1.2.0.pom115
-rw-r--r--thedarkcolour/kotlinforforge/1.2.0/web.html8
-rw-r--r--thedarkcolour/kotlinforforge/1.2.1/kotlinforforge-1.2.1.pom115
-rw-r--r--thedarkcolour/kotlinforforge/1.2.1/web.html8
-rw-r--r--thedarkcolour/kotlinforforge/1.2.2/kotlinforforge-1.2.2-sources.jarbin0 -> 15773 bytes
-rw-r--r--thedarkcolour/kotlinforforge/1.2.2/kotlinforforge-1.2.2-sources.jar.md51
-rw-r--r--thedarkcolour/kotlinforforge/1.2.2/kotlinforforge-1.2.2-sources.jar.sha11
-rw-r--r--thedarkcolour/kotlinforforge/1.2.2/kotlinforforge-1.2.2.jarbin0 -> 77158 bytes
-rw-r--r--thedarkcolour/kotlinforforge/1.2.2/kotlinforforge-1.2.2.jar.md51
-rw-r--r--thedarkcolour/kotlinforforge/1.2.2/kotlinforforge-1.2.2.jar.sha11
-rw-r--r--thedarkcolour/kotlinforforge/1.2.2/kotlinforforge-1.2.2.pom60
-rw-r--r--thedarkcolour/kotlinforforge/1.2.2/kotlinforforge-1.2.2.pom.md51
-rw-r--r--thedarkcolour/kotlinforforge/1.2.2/kotlinforforge-1.2.2.pom.sha11
-rw-r--r--thedarkcolour/kotlinforforge/1.2.2/web.html20
-rw-r--r--thedarkcolour/kotlinforforge/web.html8
-rw-r--r--thedarkcolour/style.css240
-rw-r--r--thedarkcolour/web.html7
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
diff --git a/index.html b/index.html
index be78025..44bd61a 100644
--- a/index.html
+++ b/index.html
@@ -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