aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/utils/ConfigUtils.kt
blob: 239f250a06ee9bb778f883fc24f76451487ad6f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package at.hannibal2.skyhanni.utils

import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.config.ConfigGuiManager
import at.hannibal2.skyhanni.config.HasLegacyId
import at.hannibal2.skyhanni.events.LorenzEvent
import at.hannibal2.skyhanni.test.command.ErrorManager
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonPrimitive
import io.github.notenoughupdates.moulconfig.gui.GuiScreenElementWrapper
import io.github.notenoughupdates.moulconfig.gui.MoulConfigEditor
import io.github.notenoughupdates.moulconfig.processor.ProcessedOption
import kotlin.reflect.KMutableProperty0
import kotlin.reflect.jvm.javaField

object ConfigUtils {

    /**
     * Migrates an Int ArrayList to an Enum ArrayList.
     * The new enum class should implement HasLegacyId and have a getter for LegacyId
     *
     * @param element The JsonElement to migrate
     * @param enumClass The enum class to migrate to
     * @return The migrated JsonElement
     */
    fun <T> migrateIntArrayListToEnumArrayList(element: JsonElement, enumClass: Class<T>): JsonElement
        where T : Enum<T>, T : HasLegacyId {
        require(element is JsonArray) { "Expected a JsonArray but got ${element.javaClass.simpleName}" }

        // An array of enum constants that are to be migrated
        val migratedArray = element.mapNotNull { jsonElement ->
            val index = jsonElement.asInt
            getEnumConstantFromLegacyId(index, enumClass)?.name
        }.map { JsonPrimitive(it) }

        // Return a JsonArray of the migrated enum constants
        return JsonArray().apply {
            migratedArray.forEach { add(it) }
        }
    }

    /**
     * Gets an enum constant from a legacy id
     * @param legacyId The legacy id to get the enum constant from
     * @param enumClass The enum class to get the enum constant from
     * @return The enum constant, or null if not found
     */
    private fun <T> getEnumConstantFromLegacyId(
        legacyId: Int,
        enumClass: Class<T>,
    ): T? where T : Enum<T>, T : HasLegacyId = enumClass.getEnumConstants().firstOrNull { it.legacyId == legacyId }

    /**
     * Migrates an Int to an Enum Constant.
     * The new enum class should implement HasLegacyId and have a getter for LegacyId
     *
     * @param element The JsonElement to migrate
     * @param enumClass The enum class to migrate to
     * @return The migrated JsonElement
     */
    fun <T> migrateIntToEnum(element: JsonElement, enumClass: Class<T>): JsonElement
        where T : Enum<T>, T : HasLegacyId {
        require(element is JsonPrimitive) { "Expected a JsonPrimitive but got ${element.javaClass.simpleName}" }
        return JsonPrimitive(getEnumConstantFromLegacyId(element.asInt, enumClass)?.name)
    }

    fun KMutableProperty0<*>.tryFindEditor(editor: MoulConfigEditor<*>): ProcessedOption? {
        return editor.processedConfig.getOptionFromField(this.javaField ?: return null)
    }

    fun KMutableProperty0<*>.jumpToEditor() {
        if (tryJumpToEditor(ConfigGuiManager.getEditorInstance())) return

        // TODO create utils function "crashIfInDevEnv"
        if (LorenzEvent.isInGuardedEventHandler) {
            throw Error("can not jump to editor $name")
        }
        ErrorManager.logErrorStateWithData(
            "Can not open the config",
            "error while trying to jump to an editor element",
            "this.name" to this.name,
            "this.toString()" to this.toString(),
            "this" to this,
        )
    }

    private fun KMutableProperty0<*>.tryJumpToEditor(editor: MoulConfigEditor<*>): Boolean {
        val option = tryFindEditor(editor) ?: return false
        editor.search("")
        if (!editor.goToOption(option)) return false
        SkyHanniMod.screenToOpen = GuiScreenElementWrapper(editor)
        return true
    }
}