Finally fix reflection on forge by using forge's scan data

This commit is contained in:
Username404-59 2021-05-16 12:45:48 +02:00
parent 8c6219627b
commit c39670c764
Signed by: Username404-59
GPG Key ID: 7AB361FBB257A5D1
3 changed files with 25 additions and 8 deletions

View File

@ -2,6 +2,7 @@ package fr.username404.snowygui
import fr.username404.snowygui.EventSnowy.Companion.useKey import fr.username404.snowygui.EventSnowy.Companion.useKey
import fr.username404.snowygui.config.Configuration.obtained import fr.username404.snowygui.config.Configuration.obtained
import fr.username404.snowygui.gui.feature.ButtonInfo
import fr.username404.snowygui.misc.AddKeyMaps import fr.username404.snowygui.misc.AddKeyMaps
import io.github.config4k.getValue import io.github.config4k.getValue
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
@ -15,19 +16,14 @@ import org.reflections8.util.ConfigurationBuilder
abstract class Snowy { abstract class Snowy {
private val displayInitMessage: Boolean by obtained private val displayInitMessage: Boolean by obtained
companion object { companion object {
val reflections = Reflections(ConfigurationBuilder() var annotatedButtons: Set<Class<*>> = Reflections(ConfigurationBuilder()
.setUrls(ClasspathHelper.forClassLoader()) .setUrls(ClasspathHelper.forClassLoader())
.setScanners(SubTypesScanner(false), TypeAnnotationsScanner()) .setScanners(SubTypesScanner(false), TypeAnnotationsScanner())
.useParallelExecutor() .useParallelExecutor()
) ).getTypesAnnotatedWith(ButtonInfo::class.java)
fun onEvent(e: String, lambda: argsLambda) = useKey(e).add(lambda) fun onEvent(e: String, lambda: argsLambda) = useKey(e).add(lambda)
@JvmField @JvmField
val logs: Logger = LogManager.getLogger() val logs: Logger = LogManager.getLogger()
init {
reflections.allTypes.forEach {
if (it.contains("fr.username404")) logs.info(it)
}
}
} }
private fun eventsInit() { private fun eventsInit() {
onEvent("EndTick") { onEvent("EndTick") {

View File

@ -17,7 +17,7 @@ abstract class ButtonImpl: ColoredElement(0.0, 0.0, 73, 8, opacity = 0.60F) {
var done: Boolean = false; private set var done: Boolean = false; private set
fun initialize() { fun initialize() {
done = true done = true
Snowy.reflections.getTypesAnnotatedWith(ButtonInfo::class.java).forEach { // Initializes every button Snowy.annotatedButtons.forEach { // Initializes every button
((try { ((try {
it.getConstructor().newInstance() it.getConstructor().newInstance()
} catch (e: NoSuchMethodException) { } catch (e: NoSuchMethodException) {

View File

@ -2,14 +2,19 @@ package fr.username404.snowygui.forge
import fr.username404.snowygui.Snowy import fr.username404.snowygui.Snowy
import fr.username404.snowygui.config.SnowyConfigScreen import fr.username404.snowygui.config.SnowyConfigScreen
import fr.username404.snowygui.gui.feature.ButtonInfo
import net.minecraftforge.fml.ExtensionPoint import net.minecraftforge.fml.ExtensionPoint
import net.minecraftforge.fml.ModList
import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent
import net.minecraftforge.forgespi.language.ModFileScanData
import org.objectweb.asm.Type
import thedarkcolour.kotlinforforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.forge.FORGE_BUS
import thedarkcolour.kotlinforforge.forge.LOADING_CONTEXT import thedarkcolour.kotlinforforge.forge.LOADING_CONTEXT
import thedarkcolour.kotlinforforge.forge.MOD_BUS import thedarkcolour.kotlinforforge.forge.MOD_BUS
import java.util.function.BiFunction import java.util.function.BiFunction
import java.util.function.Supplier import java.util.function.Supplier
import java.util.stream.Collectors
@Mod("snowygui") @Mod("snowygui")
@Suppress("UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER")
@ -28,6 +33,22 @@ class ForgeInit: Snowy() {
) )
} }
init { init {
annotatedButtons = ModList.get() // Forge-specific reflection
.allScanData
.stream()
.map { obj: ModFileScanData -> obj.classes }
.flatMap { obj: Set<ModFileScanData.ClassData?> -> obj.stream() }
.filter { data: ModFileScanData.ClassData? ->
(data!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(data) as Type).className.let {
if (it.contains("fr.username404") && !it.contains("mixins")) {
Class.forName(it).declaredAnnotations.any { annotation ->
annotation is ButtonInfo
}
} else false
}
}
.map { Class.forName((it!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(it) as Type).className) }
.collect(Collectors.toSet())
with(MOD_BUS) { with(MOD_BUS) {
addListener(this@ForgeInit::initSetup) addListener(this@ForgeInit::initSetup)
addListener(this@ForgeInit::configSetup) addListener(this@ForgeInit::configSetup)