aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/features/texturepack
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-09-24 11:40:15 +0200
committerLinnea Gräf <nea@nea.moe>2024-09-24 11:40:15 +0200
commit420f2a61e1cc64d68bf03825e8fd70cf49ac6a01 (patch)
tree540f2beaf99bda96af3c145cbfe81faebba76bee /src/main/kotlin/features/texturepack
parent64099bd2628490b06392766c6d1b9425f26788a3 (diff)
downloadfirmament-420f2a61e1cc64d68bf03825e8fd70cf49ac6a01.tar.gz
firmament-420f2a61e1cc64d68bf03825e8fd70cf49ac6a01.tar.bz2
firmament-420f2a61e1cc64d68bf03825e8fd70cf49ac6a01.zip
Use weak caches for custom textures
Diffstat (limited to 'src/main/kotlin/features/texturepack')
-rw-r--r--src/main/kotlin/features/texturepack/AndPredicate.kt1
-rw-r--r--src/main/kotlin/features/texturepack/CustomGlobalArmorOverrides.kt28
-rw-r--r--src/main/kotlin/features/texturepack/CustomGlobalTextures.kt33
-rw-r--r--src/main/kotlin/features/texturepack/CustomSkyBlockTextures.kt57
4 files changed, 68 insertions, 51 deletions
diff --git a/src/main/kotlin/features/texturepack/AndPredicate.kt b/src/main/kotlin/features/texturepack/AndPredicate.kt
index 55a4f32..dc8e852 100644
--- a/src/main/kotlin/features/texturepack/AndPredicate.kt
+++ b/src/main/kotlin/features/texturepack/AndPredicate.kt
@@ -1,4 +1,3 @@
-
package moe.nea.firmament.features.texturepack
import com.google.gson.JsonArray
diff --git a/src/main/kotlin/features/texturepack/CustomGlobalArmorOverrides.kt b/src/main/kotlin/features/texturepack/CustomGlobalArmorOverrides.kt
index 23577ee..7b6e62b 100644
--- a/src/main/kotlin/features/texturepack/CustomGlobalArmorOverrides.kt
+++ b/src/main/kotlin/features/texturepack/CustomGlobalArmorOverrides.kt
@@ -1,12 +1,13 @@
-
@file:UseSerializers(IdentifierSerializer::class)
package moe.nea.firmament.features.texturepack
+import java.util.Optional
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlinx.serialization.UseSerializers
+import kotlin.jvm.optionals.getOrNull
import net.minecraft.item.ArmorMaterial
import net.minecraft.item.ItemStack
import net.minecraft.resource.ResourceManager
@@ -20,8 +21,7 @@ import moe.nea.firmament.events.subscription.SubscriptionOwner
import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.features.texturepack.CustomGlobalTextures.logger
import moe.nea.firmament.util.IdentifierSerializer
-import moe.nea.firmament.util.IdentityCharacteristics
-import moe.nea.firmament.util.computeNullableFunction
+import moe.nea.firmament.util.collections.WeakCache
import moe.nea.firmament.util.skyBlockId
object CustomGlobalArmorOverrides : SubscriptionOwner {
@@ -59,21 +59,21 @@ object CustomGlobalArmorOverrides : SubscriptionOwner {
override val delegateFeature: FirmamentFeature
get() = CustomSkyBlockTextures
- val overrideCache = mutableMapOf<IdentityCharacteristics<ItemStack>, Any>()
+ val overrideCache = WeakCache.memoize<ItemStack, Optional<List<ArmorMaterial.Layer>>>("ArmorOverrides") { stack ->
+ val id = stack.skyBlockId ?: return@memoize Optional.empty()
+ val override = overrides[id.neuItem] ?: return@memoize Optional.empty()
+ for (suboverride in override.overrides) {
+ if (suboverride.predicate.test(stack)) {
+ return@memoize Optional.of(suboverride.bakedLayers)
+ }
+ }
+ return@memoize Optional.of(override.bakedLayers)
+ }
@JvmStatic
fun overrideArmor(stack: ItemStack): List<ArmorMaterial.Layer>? {
if (!CustomSkyBlockTextures.TConfig.enableArmorOverrides) return null
- return overrideCache.computeNullableFunction(IdentityCharacteristics(stack)) {
- val id = stack.skyBlockId ?: return@computeNullableFunction null
- val override = overrides[id.neuItem] ?: return@computeNullableFunction null
- for (suboverride in override.overrides) {
- if (suboverride.predicate.test(stack)) {
- return@computeNullableFunction suboverride.bakedLayers
- }
- }
- return@computeNullableFunction override.bakedLayers
- }
+ return overrideCache.invoke(stack).getOrNull()
}
var overrides: Map<String, ArmorOverride> = mapOf()
diff --git a/src/main/kotlin/features/texturepack/CustomGlobalTextures.kt b/src/main/kotlin/features/texturepack/CustomGlobalTextures.kt
index d64c844..2771699 100644
--- a/src/main/kotlin/features/texturepack/CustomGlobalTextures.kt
+++ b/src/main/kotlin/features/texturepack/CustomGlobalTextures.kt
@@ -1,9 +1,9 @@
-
@file:UseSerializers(IdentifierSerializer::class, CustomModelOverrideParser.FirmamentRootPredicateSerializer::class)
package moe.nea.firmament.features.texturepack
+import java.util.Optional
import java.util.concurrent.CompletableFuture
import org.slf4j.LoggerFactory
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable
@@ -28,9 +28,9 @@ import moe.nea.firmament.events.ScreenChangeEvent
import moe.nea.firmament.events.subscription.SubscriptionOwner
import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.util.IdentifierSerializer
-import moe.nea.firmament.util.IdentityCharacteristics
import moe.nea.firmament.util.MC
-import moe.nea.firmament.util.computeNullableFunction
+import moe.nea.firmament.util.collections.WeakCache
+import moe.nea.firmament.util.intoOptional
import moe.nea.firmament.util.json.SingletonSerializableList
import moe.nea.firmament.util.runNull
@@ -140,7 +140,17 @@ object CustomGlobalTextures : SinglePreparationResourceReloader<CustomGlobalText
.filterTo(mutableSetOf()) { it.screenFilter.title.matches(newTitle) }
}
- val overrideCache = mutableMapOf<IdentityCharacteristics<ItemStack>, Any>()
+ val overrideCache = WeakCache.memoize<ItemStack, ItemModels, Optional<BakedModel>>("CustomGlobalTextureModelOverrides") { stack, models ->
+ matchingOverrides
+ .firstNotNullOfOrNull {
+ it.overrides
+ .asSequence()
+ .filter { it.predicate.test(stack) }
+ .map { models.modelManager.getModel(ModelIdentifier(it.model, "inventory")) }
+ .firstOrNull()
+ }
+ .intoOptional()
+ }
@JvmStatic
fun replaceGlobalModel(
@@ -148,19 +158,8 @@ object CustomGlobalTextures : SinglePreparationResourceReloader<CustomGlobalText
stack: ItemStack,
cir: CallbackInfoReturnable<BakedModel>
) {
- val value = overrideCache.computeNullableFunction(IdentityCharacteristics(stack)) {
- for (guiClassOverride in matchingOverrides) {
- for (override in guiClassOverride.overrides) {
- if (override.predicate.test(stack)) {
- return@computeNullableFunction models.modelManager.getModel(
- ModelIdentifier(override.model, "inventory"))
- }
- }
- }
- null
- }
- if (value != null)
- cir.returnValue = value
+ overrideCache.invoke(stack, models)
+ .ifPresent(cir::setReturnValue)
}
diff --git a/src/main/kotlin/features/texturepack/CustomSkyBlockTextures.kt b/src/main/kotlin/features/texturepack/CustomSkyBlockTextures.kt
index 692f73b..3b7cb96 100644
--- a/src/main/kotlin/features/texturepack/CustomSkyBlockTextures.kt
+++ b/src/main/kotlin/features/texturepack/CustomSkyBlockTextures.kt
@@ -2,7 +2,9 @@ package moe.nea.firmament.features.texturepack
import com.mojang.authlib.minecraft.MinecraftProfileTexture
import com.mojang.authlib.properties.Property
+import java.util.Optional
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable
+import kotlin.jvm.optionals.getOrNull
import net.minecraft.block.SkullBlock
import net.minecraft.client.MinecraftClient
import net.minecraft.client.render.RenderLayer
@@ -12,10 +14,11 @@ import net.minecraft.util.Identifier
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.BakeExtraModelsEvent
import moe.nea.firmament.events.CustomItemModelEvent
+import moe.nea.firmament.events.FinalizeResourceManagerEvent
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.features.FirmamentFeature
import moe.nea.firmament.gui.config.ManagedConfig
-import moe.nea.firmament.util.IdentityCharacteristics
+import moe.nea.firmament.util.collections.WeakCache
import moe.nea.firmament.util.item.decodeProfileTextureProperty
import moe.nea.firmament.util.skyBlockId
@@ -26,7 +29,8 @@ object CustomSkyBlockTextures : FirmamentFeature {
object TConfig : ManagedConfig(identifier) {
val enabled by toggle("enabled") { true }
val skullsEnabled by toggle("skulls-enabled") { true }
- val cacheDuration by integer("cache-duration", 0, 20) { 1 }
+ val cacheForever by toggle("cache-forever") { true }
+ val cacheDuration by integer("cache-duration", 0, 100) { 1 }
val enableModelOverrides by toggle("model-overrides") { true }
val enableArmorOverrides by toggle("armor-overrides") { true }
val enableBlockOverrides by toggle("block-overrides") { true }
@@ -36,14 +40,31 @@ object CustomSkyBlockTextures : FirmamentFeature {
override val config: ManagedConfig
get() = TConfig
+ val allItemCaches by lazy {
+ listOf(
+ CustomItemModelEvent.cache.cache,
+ skullTextureCache.cache,
+ CustomGlobalTextures.overrideCache.cache,
+ CustomGlobalArmorOverrides.overrideCache.cache
+ )
+ }
+
+ fun clearAllCaches() {
+ allItemCaches.forEach(WeakCache<*, *, *>::clear)
+ }
+
@Subscribe
fun onTick(it: TickEvent) {
+ if (TConfig.cacheForever) return
if (TConfig.cacheDuration < 1 || it.tickCount % TConfig.cacheDuration == 0) {
- // TODO: unify all of those caches somehow
- CustomItemModelEvent.clearCache()
- skullTextureCache.clear()
- CustomGlobalTextures.overrideCache.clear()
- CustomGlobalArmorOverrides.overrideCache.clear()
+ clearAllCaches()
+ }
+ }
+
+ @Subscribe
+ fun onStart(event: FinalizeResourceManagerEvent) {
+ event.registerOnApply("Clear firmament CIT caches") {
+ clearAllCaches()
}
}
@@ -74,8 +95,14 @@ object CustomSkyBlockTextures : FirmamentFeature {
it.overrideModel = ModelIdentifier.ofInventoryVariant(Identifier.of("firmskyblock", id.identifier.path))
}
- private val skullTextureCache = mutableMapOf<IdentityCharacteristics<ProfileComponent>, Any>()
- private val sentinelPresentInvalid = Object()
+ private val skullTextureCache =
+ WeakCache.memoize<ProfileComponent, Optional<Identifier>>("SkullTextureCache") { component ->
+ val id = getSkullTexture(component) ?: return@memoize Optional.empty()
+ if (!MinecraftClient.getInstance().resourceManager.getResource(id).isPresent) {
+ return@memoize Optional.empty()
+ }
+ return@memoize Optional.of(id)
+ }
private val mcUrlRegex = "https?://textures.minecraft.net/texture/([a-fA-F0-9]+)".toRegex()
@@ -100,16 +127,8 @@ object CustomSkyBlockTextures : FirmamentFeature {
if (type != SkullBlock.Type.PLAYER) return
if (!TConfig.skullsEnabled) return
if (component == null) return
- val ic = IdentityCharacteristics(component)
- val n = skullTextureCache.getOrPut(ic) {
- val id = getSkullTexture(component) ?: return@getOrPut sentinelPresentInvalid
- if (!MinecraftClient.getInstance().resourceManager.getResource(id).isPresent) {
- return@getOrPut sentinelPresentInvalid
- }
- return@getOrPut id
- }
- if (n === sentinelPresentInvalid) return
- cir.returnValue = RenderLayer.getEntityTranslucent(n as Identifier)
+ val n = skullTextureCache.invoke(component).getOrNull() ?: return
+ cir.returnValue = RenderLayer.getEntityTranslucent(n)
}
}