diff options
21 files changed, 173 insertions, 191 deletions
@@ -23,3 +23,4 @@ run # Files from Forge MDK forge*changelog.txt +gradle @@ -3,7 +3,7 @@ Makes Kotlin forge-friendly by doing the following: - Provides the Kotlin libraries. - Provides `KotlinLanguageProvider` to allow usage of object declarations as @Mod targets. - Provides `AutoKotlinEventBusSubscriber` to allow usage of object declarations as @Mod.EventBusSubscriber targets. -- Provides `KtDeferredRegister` as an alternative to `DeferredRegister` that returns non-null values +- Provides useful top-level utility functions and constants To implement in your project, add the following to your build.gradle: ```groovy @@ -15,6 +15,7 @@ repositories { } dependencies { + // Uses the latest version of KotlinForForge implementation 'thedarkcolour:kotlinforforge:1+' } ``` @@ -22,23 +23,9 @@ Then, add the following to your mods.toml file: ```toml modLoader="kotlinforforge" loaderVersion="[1,)" - -[[dependencies.YOUR_MODID]] - modId="kotlinforforge" - mandatory=true - versionRange="[1,)" - ordering="NONE" - side="BOTH" ``` -Currently, this mod supports object declarations with @Mod and @EventBusSubscriber annotations. - -It is recommended that you use -```net.minecraftforge.registries.DeferredRegister``` -instead of -```net.minecraftforge.registries.ObjectHolder``` - -You must use +Use ```thedarkcolour.kotlinforforge.KotlinModLoadingContext``` instead of ```net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext``` diff --git a/build.gradle b/build.gradle index 09aac4c..26760ab 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { } } plugins { - id "org.jetbrains.kotlin.jvm" version "1.3.50" + id "org.jetbrains.kotlin.jvm" version "1.3.61" id "com.github.johnrengelman.shadow" version "4.0.4" } @@ -31,7 +31,7 @@ tasks.build.dependsOn kotlinSourcesJar tasks.build.dependsOn shadowJar minecraft { - mappings channel: 'snapshot', version: '20191019-1.14.3' + mappings channel: 'snapshot', version: '20191213-1.14.3' runs { client { @@ -91,7 +91,8 @@ repositories { } dependencies { - minecraft 'net.minecraftforge:forge:1.14.4-28.1.74' + minecraft 'net.minecraftforge:forge:1.14.4-28.1.106' + compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib", version: kotlin_version compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk7", version: kotlin_version compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk8", version: kotlin_version @@ -99,6 +100,9 @@ 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 { @@ -141,6 +145,7 @@ def reobfArtifact = artifacts.add('default', reobfFile) { type 'jar' builtBy 'reobfJar' } + publishing { publications { mavenJava(MavenPublication) { @@ -152,4 +157,11 @@ publishing { url "file:///${project.projectDir}/mcmodsrepo" } } +} + +compileKotlin { + kotlinOptions { + freeCompilerArgs = ["-Xinline-classes"] + jvmTarget = '1.8' + } }
\ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 9031548..0a82c28 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,6 +2,6 @@ # This is required to provide enough memory for the Minecraft decompilation process. org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false -kotlin_version=1.3.50 +kotlin_version=1.3.61 coroutines_version = 1.3.2 annotations_version = 18.0.0
\ 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 0189ea7..9f81c93 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt @@ -1,7 +1,6 @@ package thedarkcolour.kotlinforforge import net.minecraftforge.api.distmarker.Dist -import net.minecraftforge.common.MinecraftForge import net.minecraftforge.fml.Logging import net.minecraftforge.fml.ModContainer import net.minecraftforge.fml.common.Mod @@ -10,16 +9,16 @@ import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation import net.minecraftforge.forgespi.language.ModFileScanData import org.objectweb.asm.Type import thedarkcolour.kotlinforforge.KotlinForForge.logger +import thedarkcolour.kotlinforforge.forge.FORGE_BUS +import thedarkcolour.kotlinforforge.forge.MOD_BUS import java.util.* import java.util.stream.Collectors /** - * Handles [net.minecraftforge.fml.common.Mod.EventBusSubscriber] + * Handles [net.minecraftforge.fml.common.Mod.EventBusSubscriber] annotations for object declarations. */ -@Suppress("unused") object AutoKotlinEventBusSubscriber { - @PublishedApi - internal val EVENT_BUS_SUBSCRIBER: Type = Type.getType(Mod.EventBusSubscriber::class.java) + private val EVENT_BUS_SUBSCRIBER: Type = Type.getType(Mod.EventBusSubscriber::class.java) /** * Registers Kotlin objects and companion objects that are annotated with [Mod.EventBusSubscriber] @@ -29,16 +28,15 @@ object AutoKotlinEventBusSubscriber { * Example Usage: * * @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) - * public object ExampleSubscriber { - * @SubscribeEvent - * public fun onItemRegistry(event: RegistryEvent.Register<Item>) { - * println("Look! We're in items!") - * } + * object ExampleSubscriber { + * @SubscribeEvent + * public fun onItemRegistry(event: RegistryEvent.Register<Item>) { + * println("Look! We're in items!") + * } * } */ - @Suppress("UNCHECKED_CAST", "unused") 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) + 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 @@ -54,15 +52,15 @@ object AutoKotlinEventBusSubscriber { val ktObject = Class.forName(annotationData.classType.className, true, classLoader).kotlin.objectInstance if (ktObject != null && mod.modId == modid && sides.contains(FMLEnvironment.dist)) { try { - logger.debug(Logging.LOADING, "Auto-subscribing kotlin object {} to {}", annotationData.classType.className, busTarget) + 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 - KotlinModLoadingContext.get().getEventBus().register(ktObject) + MOD_BUS.register(ktObject) } else { - MinecraftForge.EVENT_BUS.register(ktObject) + FORGE_BUS.register(ktObject) } } catch (e: Throwable) { - logger.fatal(Logging.LOADING, "Failed to load mod class {} for @EventBusSubscriber annotation", annotationData.classType, e) + logger.fatal(Logging.LOADING, "Failed to load mod class ${annotationData.classType} for @EventBusSubscriber annotation", e) throw RuntimeException(e) } } diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt index 337f82a..4b07205 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt @@ -4,11 +4,10 @@ import net.minecraftforge.fml.common.Mod import net.minecraftforge.registries.DeferredRegister import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger +import thedarkcolour.kotlinforforge.forge.MOD_BUS /** - * Set 'modLoader' in mods.toml to "kotlinforforge" and loaderVersion to "1". - * - * It is recommended that you use [DeferredRegister] instead of ObjectHolders. + * Set 'modLoader' in mods.toml to "kotlinforforge" and loaderVersion to "[1,)". */ @Mod("kotlinforforge") object KotlinForForge { diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt index c549580..378b999 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt @@ -16,25 +16,22 @@ class KotlinLanguageProvider : FMLJavaModLanguageProvider() { override fun getFileVisitor(): Consumer<ModFileScanData> { return Consumer { scanResult -> val target = scanResult.annotations.stream() - .filter {data -> data.annotationType == MODANNOTATION } - .peek { data -> KotlinForForge.logger.debug(Logging.SCAN, "Found @Mod class {} with id {}", data.classType.className, data.annotationData["value"]) } + .filter { data -> data.annotationType == MODANNOTATION } + .peek { data -> KotlinForForge.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<KotlinModTarget, String, KotlinModTarget>(Function { target: KotlinModTarget -> return@Function target.modId }, Function {return@Function it}, BinaryOperator { a, _ -> a })) + .collect(Collectors.toMap({ target: KotlinModTarget -> target.modId }, { it }, { a, _ -> a })) scanResult.addLanguageLoader(target) } } override fun <R : ILifecycleEvent<R>?> consumeLifecycleEvent(consumeEvent: Supplier<R>?) {} - override fun name(): String { - return "kotlinforforge" - } + override fun name(): String = "kotlinforforge" class KotlinModTarget constructor(private val className: String, val modId: String) : IModLanguageProvider.IModLanguageLoader { - @Suppress("UNCHECKED_CAST") override fun <T> loadMod(info: IModInfo, modClassLoader: ClassLoader, modFileScanResults: ModFileScanData): T { val ktContainer = Class.forName("thedarkcolour.kotlinforforge.KotlinModContainer", true, Thread.currentThread().contextClassLoader) - KotlinForForge.logger.debug(Logging.LOADING, "Loading KotlinModContainer from classloader {} - got {}", Thread.currentThread().contextClassLoader, ktContainer.classLoader) + KotlinForForge.logger.debug(Logging.LOADING, "Loading KotlinModContainer from classloader ${Thread.currentThread().contextClassLoader} - got ${ktContainer.classLoader}}") val constructor = ktContainer.getConstructor(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 28722cd..3446a7a 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt @@ -13,35 +13,38 @@ import java.util.* import java.util.function.Consumer import java.util.function.Supplier -@Suppress("UNUSED_PARAMETER") +/** + * Functions as [net.minecraftforge.fml.javafmlmod.FMLModContainer] for Kotlin + * + * + */ class KotlinModContainer(info: IModInfo, className: String, loader: ClassLoader, private val scanData: ModFileScanData) : ModContainer(info) { - private lateinit var modInstance: Any private val modClass: Class<*> - val eventBus: IEventBus - - // Use a separate logger because KotlinForForge.logger isn't initialized yet + /** Use a separate logger because KotlinForForge.logger isn't initialized yet */ private val logger = LogManager.getLogger() + private lateinit var modInstance: Any + val eventBus: IEventBus init { logger.debug(Logging.LOADING, "Creating KotlinModContainer instance for {} with classLoader {} & {}", className, loader, javaClass.classLoader) - triggerMap[ModLoadingStage.CONSTRUCT] = dummy().andThen { beforeEvent(it) }.andThen { constructMod(it) }.andThen{ afterEvent(it) } - triggerMap[ModLoadingStage.CREATE_REGISTRIES] = dummy().andThen { beforeEvent(it) }.andThen { fireEvent(it) }.andThen{ afterEvent(it) } - triggerMap[ModLoadingStage.LOAD_REGISTRIES] = dummy().andThen { beforeEvent(it) }.andThen { fireEvent(it) }.andThen{ afterEvent(it) } - triggerMap[ModLoadingStage.COMMON_SETUP] = dummy().andThen { beforeEvent(it) }.andThen { preinitMod(it) }.andThen{ fireEvent(it) }.andThen { this.afterEvent(it) } - triggerMap[ModLoadingStage.SIDED_SETUP] = dummy().andThen { beforeEvent(it)}.andThen { fireEvent(it) }.andThen { afterEvent(it) } - triggerMap[ModLoadingStage.ENQUEUE_IMC] = dummy().andThen { beforeEvent(it)}.andThen { initMod(it) }.andThen{ fireEvent(it) }.andThen{ this.afterEvent(it) } - triggerMap[ModLoadingStage.PROCESS_IMC] = dummy().andThen { beforeEvent(it) }.andThen { fireEvent(it) }.andThen{ afterEvent(it) } - triggerMap[ModLoadingStage.COMPLETE] = dummy().andThen { beforeEvent(it) }.andThen { completeLoading(it) }.andThen{ fireEvent(it) }.andThen { this.afterEvent(it) } - triggerMap[ModLoadingStage.GATHERDATA] = dummy().andThen { beforeEvent(it) }.andThen { fireEvent(it) }.andThen{ afterEvent(it) } - eventBus = BusBuilder.builder().setExceptionHandler{ bus, event, listeners, index, throwable -> onEventFailed(bus, event, listeners, index, throwable) }.setTrackPhases(false).build() - configHandler = Optional.of(Consumer {event -> eventBus.post(event)}) + triggerMap[ModLoadingStage.CONSTRUCT] = dummy().andThen(::beforeEvent).andThen(::constructMod).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.COMMON_SETUP] = dummy().andThen(::beforeEvent).andThen(::preInitMod).andThen(::fireEvent).andThen(::afterEvent) + triggerMap[ModLoadingStage.SIDED_SETUP] = dummy().andThen(::beforeEvent).andThen(::fireEvent).andThen (::afterEvent) + triggerMap[ModLoadingStage.ENQUEUE_IMC] = dummy().andThen(::beforeEvent).andThen(::initMod).andThen(::fireEvent).andThen(::afterEvent) + triggerMap[ModLoadingStage.PROCESS_IMC] = dummy().andThen(::beforeEvent).andThen(::fireEvent).andThen(::afterEvent) + triggerMap[ModLoadingStage.COMPLETE] = dummy().andThen(::beforeEvent).andThen(::completeLoading).andThen(::fireEvent).andThen(::afterEvent) + triggerMap[ModLoadingStage.GATHERDATA] = dummy().andThen(::beforeEvent).andThen(::fireEvent).andThen(::afterEvent) + eventBus = BusBuilder.builder().setExceptionHandler(::onEventFailed).setTrackPhases(false).build() + configHandler = Optional.of(Consumer { event -> eventBus.post(event) }) val ctx = KotlinModLoadingContext(this) - contextExtension = Supplier { return@Supplier ctx} + contextExtension = Supplier { ctx } try { modClass = Class.forName(className, true, loader) - logger.debug(Logging.LOADING, "Loaded kotlin modclass {} with {}", modClass.name, modClass.classLoader) + logger.debug(Logging.LOADING, "Loaded kotlin modclass ${modClass.name} with ${modClass.classLoader}") } catch (e: Throwable) { - logger.error(Logging.LOADING, "Failed to load kotlin class {}", className, e) + logger.error(Logging.LOADING, "Failed to load kotlin class $className", e) throw ModLoadingException(info, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmodclass", e) } } @@ -49,58 +52,57 @@ class KotlinModContainer(info: IModInfo, className: String, loader: ClassLoader, private fun completeLoading(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) {} private fun initMod(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) {} private fun dummy(): Consumer<LifecycleEventProvider.LifecycleEvent> = Consumer {} - private fun onEventFailed(iEventBus: IEventBus, event: Event, iEventListeners: Array<IEventListener>, i: Int, throwable: Throwable) = logger.error(EventBusErrorMessage(event, i, iEventListeners, throwable)) private fun beforeEvent(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) {} + private fun onEventFailed(iEventBus: IEventBus, event: Event, iEventListeners: Array<IEventListener>, i: Int, throwable: Throwable) { + logger.error(EventBusErrorMessage(event, i, iEventListeners, throwable)) + } + private fun fireEvent(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) { val event = lifecycleEvent.getOrBuildEvent(this) - logger.debug(Logging.LOADING, "Firing event for modid {} : {}", getModId(), event) - // Now actually fires the event + logger.debug(Logging.LOADING, "Firing event for modid ${getModId()} : $event") + try { eventBus.post(event) - logger.debug(Logging.LOADING, "Fired event for modid {} : {}", getModId(), event) + logger.debug(Logging.LOADING, "Fired event for modid ${getModId()} : $event") } catch (e: Throwable) { - logger.error(Logging.LOADING,"An error occurred while dispatching event {} to {}", lifecycleEvent.fromStage(), modId) + logger.error(Logging.LOADING,"An error occurred while dispatching event ${lifecycleEvent.fromStage()} to $modId") throw ModLoadingException(modInfo, lifecycleEvent.fromStage(), "fml.modloading.errorduringevent", e) } } private fun afterEvent(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) { if (currentState == ModLoadingStage.ERROR) { - logger.error(Logging.LOADING, "An error occurred while dispatching event {} to {}", lifecycleEvent.fromStage(), modId) + logger.error(Logging.LOADING, "An error occurred while dispatching event ${lifecycleEvent.fromStage()} to $modId") } } - private fun preinitMod(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) {} + private fun preInitMod(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) {} private fun constructMod(lifecycleEvent: LifecycleEventProvider.LifecycleEvent) { try { - logger.debug(Logging.LOADING, "Loading mod instance {} of type {}", getModId(), modClass.name) + logger.debug(Logging.LOADING, "Loading mod instance ${getModId()} of type ${modClass.name}") modInstance = modClass.kotlin.objectInstance ?: modClass.newInstance() - logger.debug(Logging.LOADING, "Loaded mod instance {} of type {}", getModId(), modClass.name) + logger.debug(Logging.LOADING, "Loaded mod instance ${getModId()} of type ${modClass.name}") } catch (e: Throwable) { - logger.error(Logging.LOADING, "Failed to create mod instance. ModID: {}, class {}", getModId(), modClass.name, e) + logger.error(Logging.LOADING, "Failed to create mod instance. ModID: ${getModId()}, class ${modClass.name}", e) throw ModLoadingException(modInfo, lifecycleEvent.fromStage(), "fml.modloading.failedtoloadmod", e, modClass) } try { - logger.debug(Logging.LOADING, "Injecting Automatic event subscribers for {}", getModId()) + logger.debug(Logging.LOADING, "Injecting Automatic Kotlin event subscribers for ${getModId()}") // Inject into object EventBusSubscribers AutoKotlinEventBusSubscriber.inject(this, scanData, modClass.classLoader) - logger.debug(Logging.LOADING, "Completed Automatic event subscribers for {}", getModId()) + logger.debug(Logging.LOADING, "Completed Automatic Kotlin event subscribers for ${getModId()}") } catch (e: Throwable) { - logger.error(Logging.LOADING, "Failed to register automatic subscribers. ModID: {}, class {}", getModId(), modClass.name, e) + logger.error(Logging.LOADING, "Failed to register Automatic Kotlin subscribers. ModID: ${getModId()}, class ${modClass.name}", e) throw ModLoadingException(modInfo, lifecycleEvent.fromStage(), "fml.modloading.failedtoloadmod", e, modClass) } } - override fun getMod(): Any { - return modInstance - } + override fun getMod(): Any = modInstance - override fun matches(mod: Any?): Boolean { - return mod == modInstance - } + override fun matches(mod: Any?): Boolean = mod == modInstance }
\ No newline at end of file diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModLoadingContext.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModLoadingContext.kt index c3a047e..1c50aae 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModLoadingContext.kt +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModLoadingContext.kt @@ -3,7 +3,10 @@ package thedarkcolour.kotlinforforge import net.minecraftforge.eventbus.api.IEventBus import net.minecraftforge.fml.ModLoadingContext -class KotlinModLoadingContext internal constructor(private val container: KotlinModContainer) { +/** + * Functions as [net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext] for Kotlin + */ +class KotlinModLoadingContext constructor(private val container: KotlinModContainer) { fun getEventBus(): IEventBus { return container.eventBus } diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/forge/EventBus.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/forge/EventBus.kt deleted file mode 100644 index 8fb2552..0000000 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/forge/EventBus.kt +++ /dev/null @@ -1,16 +0,0 @@ -package thedarkcolour.kotlinforforge.forge - -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.eventbus.api.IEventBus - -/** - * The forge event bus. - * Many events that occur during the game are fired on this bus. - * - * Examples: - * @see net.minecraftforge.event.entity.player.PlayerEvent - * @see net.minecraftforge.event.entity.living.LivingEvent - * @see net.minecraftforge.event.world.BlockEvent - */ -val FORGE_BUS: IEventBus - inline get() = MinecraftForge.EVENT_BUS
\ No newline at end of file diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt new file mode 100644 index 0000000..297afe4 --- /dev/null +++ b/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt @@ -0,0 +1,81 @@ +package thedarkcolour.kotlinforforge.forge + +import net.minecraftforge.api.distmarker.Dist +import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.eventbus.api.IEventBus +import net.minecraftforge.fml.loading.FMLEnvironment +import thedarkcolour.kotlinforforge.KotlinModLoadingContext + +/** @since 1.0.0 + * The forge EventBus. + * Many events that occur during the game are fired on this bus. + * + * Examples: + * @see net.minecraftforge.event.entity.player.PlayerEvent + * @see net.minecraftforge.event.entity.living.LivingEvent + * @see net.minecraftforge.event.world.BlockEvent + */ +val FORGE_BUS: IEventBus + inline get() = MinecraftForge.EVENT_BUS + +/** @since 1.0.0 + * The mod-specific EventBus. + * Setup events are typically fired on this bus. + * + * Examples: + * @see net.minecraftforge.fml.event.lifecycle.InterModProcessEvent + * @see net.minecraftforge.event.AttachCapabilitiesEvent + * @see net.minecraftforge.event.RegistryEvent + */ +val MOD_BUS: IEventBus + inline get() = KotlinModLoadingContext.get().getEventBus() + +/** @since 1.0.0 + * Mod context for Kotlin mods. + * + * Used in place of [net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext] + */ +val MOD_CONTEXT: KotlinModLoadingContext + inline get() = KotlinModLoadingContext.get() + +/** @since 1.0.0 + * The current [Dist] of this environment. + */ +val DIST: Dist = FMLEnvironment.dist + +/** @since 1.0.0 + * An alternative to [net.minecraftforge.fml.DistExecutor.callWhenOn] + * that uses Kotlin functions instead of Java functional interfaces. + */ +fun <T> callWhenOn(dist: Dist, toRun: () -> () -> T): T? { + if (DIST == dist) { + try { + return toRun()() + } catch (e: Exception) { + throw RuntimeException(e) + } + } + + return null +} + +/** @since 1.0.0 + * An alternative to [net.minecraftforge.fml.DistExecutor.callWhenOn] + * that uses Kotlin functions instead of Java functional interfaces. + */ +fun runWhenOn(dist: Dist, toRun: () -> () -> Unit) { + if (DIST == dist) { + toRun()() + } +} + +/** @since 1.0.0 + * An alternative to [net.minecraftforge.fml.DistExecutor.runForDist] + * that uses Kotlin functions instead of Java functional interfaces. + */ +fun <T> runForDist(clientTarget: () -> () -> T, serverTarget: () -> () -> T): T { + return when (DIST) { + Dist.CLIENT -> clientTarget()() + Dist.DEDICATED_SERVER -> serverTarget()() + } +}
\ No newline at end of file diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/registry/KtDeferredRegister.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/registry/KtDeferredRegister.kt deleted file mode 100644 index dedfb27..0000000 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/registry/KtDeferredRegister.kt +++ /dev/null @@ -1,34 +0,0 @@ -package thedarkcolour.kotlinforforge.registry - -import net.minecraft.util.ResourceLocation -import net.minecraftforge.event.RegistryEvent -import net.minecraftforge.eventbus.api.IEventBus -import net.minecraftforge.registries.IForgeRegistry -import net.minecraftforge.registries.IForgeRegistryEntry -import java.util.* -import java.util.function.Supplier -import kotlin.collections.LinkedHashMap - -/** - * @see [net.minecraftforge.registries.DeferredRegister] for example use - */ -class KtDeferredRegister<T : IForgeRegistryEntry<T>>(private val registry: IForgeRegistry<T>, private val modid: String) { - private val entries: MutableMap<KtRegistryObject<T>, Supplier<out T>> = LinkedHashMap() - val entriesView: Set<KtRegistryObject<T>> = Collections.unmodifiableSet(entries.keys) - - fun register(name: String, supplier: Supplier<out T>): KtRegistryObject<T> { - val key = ResourceLocation(modid, name) - val obj = KtRegistryObject(key, registry) - require(entries.putIfAbsent(obj, Supplier { supplier.get().setRegistryName(key) }) == null) { "Duplicate registration $name" } - return obj - } - - fun register(bus: IEventBus) = bus.addListener(::addEntries) - - private fun addEntries(event: RegistryEvent.Register<T>) { - for (entry in entries.entries) { - registry.register(entry.value.get()) - entry.key.refresh(registry) - } - } -}
\ No newline at end of file diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/registry/KtRegistryObject.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/registry/KtRegistryObject.kt deleted file mode 100644 index fe20cc4..0000000 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/registry/KtRegistryObject.kt +++ /dev/null @@ -1,47 +0,0 @@ -package thedarkcolour.kotlinforforge.registry - -import net.minecraft.util.ResourceLocation -import net.minecraftforge.registries.IForgeRegistry -import net.minecraftforge.registries.IForgeRegistryEntry -import net.minecraftforge.registries.ObjectHolderRegistry -import net.minecraftforge.registries.RegistryManager -import java.util.function.Supplier - -/** - * An alternative to DeferredRegistry that enforces non-nullability. - */ -open class KtRegistryObject<T : IForgeRegistryEntry<T>>(val name: ResourceLocation, registry: IForgeRegistry<T>) : Supplier<T> { - private lateinit var value: T - - constructor(name: String, registry: IForgeRegistry<T>) : this(ResourceLocation(name), registry) - - @Suppress("UNCHECKED_CAST") - constructor(name: String, registryType: Supplier<Class<out T>>) : this(ResourceLocation(name), RegistryManager.ACTIVE.getRegistry(registryType.get()) as IForgeRegistry<T>) - - init { - ObjectHolderRegistry.addHandler { predicate -> - if (predicate.test(registry.registryName)) { - value = registry.getValue(name)!! - } - } - } - - override fun get(): T = value - - fun refresh(registry: IForgeRegistry<out T>) { - value = registry.getValue(name)!! - } - - override fun equals(other: Any?): Boolean { - return when (other) { - other === this -> true - other?.javaClass != javaClass -> false - (other as KtRegistryObject<*>).name != name -> false - else -> true - } - } - - override fun hashCode(): Int { - return name.hashCode() - } -}
\ No newline at end of file diff --git a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar Binary files differindex 0517b84..8c61a66 100644 --- a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar +++ b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar diff --git a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar.md5 b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar.md5 index 8f2d6d1..b440f7b 100644 --- a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar.md5 +++ b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar.md5 @@ -1 +1 @@ -37eeafb7c445190d5ac4953caef46c79
\ No newline at end of file +cda2255791958f5288c24161b2826b1d
\ No newline at end of file diff --git a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar.sha1 b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar.sha1 index b9af7fb..01e1999 100644 --- a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar.sha1 +++ b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0-sources.jar.sha1 @@ -1 +1 @@ -2ec3afb2b00b0a36c940a2fa40b2526f2bb0a486
\ No newline at end of file +2207a49e93eb065bc7f0442fdf6160d9f4e94c4d
\ No newline at end of file diff --git a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar Binary files differindex e91ad77..331ba80 100644 --- a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar +++ b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar diff --git a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar.md5 b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar.md5 index 3efca06..e69de29 100644 --- a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar.md5 +++ b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar.md5 @@ -1 +0,0 @@ -527d1882df65e5b0a0c776a63da950e8
\ No newline at end of file diff --git a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar.sha1 b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar.sha1 index 3d6cb16..b6ea805 100644 --- a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar.sha1 +++ b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.jar.sha1 @@ -1 +1 @@ -7c9f7c81ae35513f7cded652a35b4a4166bc44f8
\ No newline at end of file +F91033F841208DBDCFF5EB46C8A4B1CCDFC49E66
\ No newline at end of file diff --git a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.pom b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.pom index 529c114..0b963aa 100644 --- a/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.pom +++ b/thedarkcolour/kotlinforforge/1.0.0/kotlinforforge-1.0.0.pom @@ -9,25 +9,25 @@ <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> - <version>1.3.50</version> + <version>1.3.61</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-jdk7</artifactId> - <version>1.3.50</version> + <version>1.3.61</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-jdk8</artifactId> - <version>1.3.50</version> + <version>1.3.61</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-reflect</artifactId> - <version>1.3.50</version> + <version>1.3.61</version> <scope>compile</scope> </dependency> <dependency> diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/webgenerator/WebGenerator.kt b/webgenerator/WebGenerator.kt index 29150f0..29150f0 100644 --- a/src/main/kotlin/thedarkcolour/kotlinforforge/webgenerator/WebGenerator.kt +++ b/webgenerator/WebGenerator.kt |