aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/moe/nea/caelo/optifine/OptifineCustomItemCache.kt
blob: 0bd6d78daccfcca35a81ec527000141bcae4c765 (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
package moe.nea.caelo.optifine

import moe.nea.caelo.CaeloCommand
import moe.nea.caelo.event.NeaTickEvent
import moe.nea.caelo.util.Histogram
import moe.nea.caelo.util.MC
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.optifine.CustomItemProperties
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable

object OptifineCustomItemCache {

    init {
        CaeloCommand.subcommand("opticache") { args ->
            val cache = cacheSizeHistory.lastOrNull() ?: CacheStats()
            MC.display("OptiCache stats:")
            MC.display("- History: §3${cacheSizeHistory.size}")
            MC.display("- Misses: §c${cache.cacheMisses}")
            MC.display("- Hits: §a${cache.cacheHits}")
            MC.display("- Entries: §b${cache.uniquePropertyBearingStacks}")
        }
    }

    class CacheKey(val itemStack: ItemStack, val type: Int) {
        override fun equals(other: Any?): Boolean {
            if (other !is CacheKey) return false
            return itemStack === other.itemStack && type == other.type
        }

        override fun hashCode(): Int {
            return System.identityHashCode(itemStack) + type * 31
        }
    }

    data class CacheStats(
        var cacheHits: Int = 0,
        var cacheMisses: Int = 0,
        var uniquePropertyBearingStacks: Int = 0,
    )

    private val map = mutableMapOf<CacheKey, CustomItemProperties?>()
    private val cacheSizeHistory = Histogram<CacheStats>(1000)
    private var cacheStats = CacheStats()

    @SubscribeEvent
    fun onTick(event: NeaTickEvent) {
        cacheSizeHistory.append(cacheStats)
        cacheStats = CacheStats()
        map.clear()
    }

    @JvmStatic
    fun retrieveCacheHit(
        itemStack: ItemStack,
        type: Int,
        cir: CallbackInfoReturnable<CustomItemProperties?>
    ) {
        val key = CacheKey(itemStack, type)
        if (!map.containsKey(key)) {
            cacheStats.cacheMisses++
            return
        }
        cacheStats.cacheHits++
        cir.returnValue = map[key]
    }

    @JvmStatic
    fun storeCustomItemProperties(itemStack: ItemStack, type: Int, cip: CustomItemProperties) {
        map[CacheKey(itemStack, type)] = cip
        cacheStats.uniquePropertyBearingStacks++
    }

    @JvmStatic
    fun storeNoCustomItemProperties(itemStack: ItemStack, type: Int) {
        map[CacheKey(itemStack, type)] = null
    }
}