Add a Snowy.annotatedButtons abstract value, and make Snowy.Companion.annotatedButtons an anonymous function

Signed-off-by: Username404 <w.iron.zombie@gmail.com>
This commit is contained in:
Username404 2022-01-16 13:03:52 +01:00
parent 0e4772873a
commit 76b17d0c97
Signed by: Username404-59
GPG Key ID: 7AB361FBB257A5D1
4 changed files with 24 additions and 30 deletions

View File

@ -13,17 +13,19 @@ abstract class Snowy {
protected fun Class<*>.isValidForButtonCollection(): Boolean = protected fun Class<*>.isValidForButtonCollection(): Boolean =
!Modifier.isAbstract(modifiers) && declaredAnnotations.any { it is ButtonInfo && !it.ignored } !Modifier.isAbstract(modifiers) && declaredAnnotations.any { it is ButtonInfo && !it.ignored }
private val displayInitMessage: Boolean by Configuration private val displayInitMessage: Boolean by Configuration
abstract val annotatedButtons: Set<Class<out ButtonImpl>>
companion object { companion object {
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
object MissingComponent: TranslatableComponent(null) { override fun getString(): String = "MISSING_COMPONENT" } object MissingComponent: TranslatableComponent(null) { override fun getString(): String = "MISSING_COMPONENT" }
@Suppress("JVM_STATIC_ON_CONST_OR_JVM_FIELD") // See KT-39868 @Suppress("JVM_STATIC_ON_CONST_OR_JVM_FIELD") // See KT-39868
@JvmStatic @JvmStatic
protected const val FeaturePackage: String = "fr.username404.snowygui.gui.feature" protected const val FeaturePackage: String = "fr.username404.snowygui.gui.feature"
lateinit var annotatedButtons: Set<Class<out ButtonImpl>> lateinit var annotatedButtons: () -> Set<Class<out ButtonImpl>>
fun onEvent(e: Any, lambda: argsLambda) = EventSnowy[e.toString()].add(lambda) fun onEvent(e: Any, lambda: argsLambda) = EventSnowy[e.toString()].add(lambda)
@JvmField @JvmField
val logs: Logger = LogManager.getLogger() val logs: Logger = LogManager.getLogger()
} }
init { Companion.annotatedButtons = ::annotatedButtons::get }
private fun eventsInit() { private fun eventsInit() {
onEvent("EndTick") { onEvent("EndTick") {
for (Key in AddKeyMaps.list.keys) { for (Key in AddKeyMaps.list.keys) {

View File

@ -38,7 +38,7 @@ sealed class ButtonImpl: ColoredElement(0.0, 0.0, 73, 8, opacity = 0.60F) {
} }
@JvmStatic @JvmStatic
fun initButtons() = addButtons( fun initButtons() = addButtons(
*Snowy.annotatedButtons.mapNotNull { *Snowy.annotatedButtons().mapNotNull {
try { try {
it.getConstructor().newInstance() it.getConstructor().newInstance()
} catch (_: NoSuchMethodException) { } catch (_: NoSuchMethodException) {

View File

@ -23,21 +23,16 @@ class FabricInit: Snowy(), ClientModInitializer {
} }
) )
} }
init { override val annotatedButtons = FabricLoader.getInstance().allMods.map {
val modsPaths = FabricLoader.getInstance().allMods.map { it.getPath(FeaturePackage.replace('.', '/'))
it.getPath(FeaturePackage.replace('.', '/')) }.filter { it.exists() && it.isDirectory() }.flatMap { buttonsDirectory ->
}.filter { it.exists() && it.isDirectory() } mutableSetOf<Class<out ButtonImpl>>().apply {
annotatedButtons = modsPaths.flatMap { buttonsDirectory -> buttonsDirectory.listDirectoryEntries("*.class").forEach { file ->
val classSet = mutableSetOf<Class<out ButtonImpl>>() @Suppress("DEPRECATION") net.fabricmc.loader.launch.common.
buttonsDirectory.run { FabricLauncherBase.getClass(file.pathString.drop(1).replace('/', '.').removeSuffix(".class")).let { foundClass ->
listDirectoryEntries("*.class").forEach { file -> if (foundClass.isValidForButtonCollection()) add(foundClass.asSubclass(ButtonImpl::class.java))
@Suppress("DEPRECATION") net.fabricmc.loader.launch.common.
FabricLauncherBase.getClass(file.pathString.drop(1).replace('/', '.').removeSuffix(".class")).let { foundClass ->
if (foundClass.isValidForButtonCollection()) classSet.add(foundClass.asSubclass(ButtonImpl::class.java))
}
} }
} }
classSet }
}.toSet() }.toSet()
}
} }

View File

@ -14,7 +14,6 @@ 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.stream.Collectors
@Mod("snowygui") @Mod("snowygui")
@Suppress("UNUSED_PARAMETER") @Suppress("UNUSED_PARAMETER")
@ -25,19 +24,17 @@ class ForgeInit: Snowy() {
ExtensionPoint.CONFIGGUIFACTORY ExtensionPoint.CONFIGGUIFACTORY
) { BiFunction { _, parent -> configScreenParent = parent; SnowyConfigScreen } } ) { BiFunction { _, parent -> configScreenParent = parent; SnowyConfigScreen } }
} }
init { override val annotatedButtons = ModList.get() // Forge-specific reflection
annotatedButtons = ModList.get() // Forge-specific reflection .allScanData
.allScanData .flatMap { obj: ModFileScanData -> obj.classes }
.stream() .filter { data: ModFileScanData.ClassData? ->
.map { obj: ModFileScanData -> obj.classes } (data!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(data) as Type).className.let { classname ->
.flatMap { obj: Set<ModFileScanData.ClassData?> -> obj.stream() } classname.startsWith(FeaturePackage) && Class.forName(classname).isValidForButtonCollection()
.filter { data: ModFileScanData.ClassData? ->
(data!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(data) as Type).className.let { classname ->
classname.startsWith(FeaturePackage) && Class.forName(classname).isValidForButtonCollection()
}
} }
.map { Class.forName((it!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(it) as Type).className).asSubclass(ButtonImpl::class.java)} }
.collect(Collectors.toSet()) .map { Class.forName((it!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(it) as Type).className).asSubclass(ButtonImpl::class.java)}
.toSet()
init {
with(MOD_BUS) { with(MOD_BUS) {
addListener(this@ForgeInit::initSetup) addListener(this@ForgeInit::initSetup)
addListener(this@ForgeInit::configSetup) addListener(this@ForgeInit::configSetup)