From d1738866ab1101ea847d2fa1505e323d75c2b10a Mon Sep 17 00:00:00 2001 From: Linnea Gräf Date: Wed, 12 Jun 2024 19:49:10 +0200 Subject: Add regex cache --- src/main/java/moe/nea/caelo/Caelo.kt | 5 +++ src/main/java/moe/nea/caelo/config/OptiCache.kt | 16 ++++--- .../moe/nea/caelo/event/ResourceReloadEvent.kt | 6 +++ .../caelo/mixin/CacheNbtTagValueRegexMatch.java | 16 +++++++ .../nea/caelo/optifine/OptifineCustomItemCache.kt | 1 + .../moe/nea/caelo/optifine/OptifineRegexCache.kt | 50 ++++++++++++++++++++++ 6 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 src/main/java/moe/nea/caelo/event/ResourceReloadEvent.kt create mode 100644 src/main/java/moe/nea/caelo/mixin/CacheNbtTagValueRegexMatch.java create mode 100644 src/main/java/moe/nea/caelo/optifine/OptifineRegexCache.kt (limited to 'src') diff --git a/src/main/java/moe/nea/caelo/Caelo.kt b/src/main/java/moe/nea/caelo/Caelo.kt index 8f1f537..79de170 100644 --- a/src/main/java/moe/nea/caelo/Caelo.kt +++ b/src/main/java/moe/nea/caelo/Caelo.kt @@ -1,12 +1,14 @@ package moe.nea.caelo import moe.nea.caelo.event.NeaTickEvent +import moe.nea.caelo.event.ResourceReloadEvent import moe.nea.caelo.init.MixinPlugin import moe.nea.caelo.optifine.OptifineCustomItemCache import moe.nea.caelo.util.InterModUtil import moe.nea.caelo.util.MC import net.minecraft.client.Minecraft import net.minecraft.client.gui.GuiScreen +import net.minecraft.client.resources.IReloadableResourceManager import net.minecraftforge.client.ClientCommandHandler import net.minecraftforge.common.MinecraftForge import net.minecraftforge.fml.common.Mod @@ -42,6 +44,9 @@ class Caelo { MinecraftForge.EVENT_BUS.register(OptifineCustomItemCache) } MinecraftForge.EVENT_BUS.register(this) + (Minecraft.getMinecraft().resourceManager as IReloadableResourceManager).registerReloadListener { + MinecraftForge.EVENT_BUS.post(ResourceReloadEvent()) + } ClientCommandHandler.instance.registerCommand(CaeloCommand) CaeloCommand.subcommand("mixins") { args -> MC.display("Injected mixins:") diff --git a/src/main/java/moe/nea/caelo/config/OptiCache.kt b/src/main/java/moe/nea/caelo/config/OptiCache.kt index 365ce2d..e18680a 100644 --- a/src/main/java/moe/nea/caelo/config/OptiCache.kt +++ b/src/main/java/moe/nea/caelo/config/OptiCache.kt @@ -5,9 +5,15 @@ import io.github.notenoughupdates.moulconfig.annotations.ConfigEditorBoolean import io.github.notenoughupdates.moulconfig.annotations.ConfigOption class OptiCache { - @ConfigEditorBoolean - @ConfigOption(name = "Enable CIT cache", desc = "Cache CIT property lookups") - @Expose - @JvmField - var citCache = true + @ConfigEditorBoolean + @ConfigOption(name = "Enable CIT cache", desc = "Cache CIT property lookups") + @Expose + @JvmField + var citCache = true + + @ConfigEditorBoolean + @ConfigOption(name = "Enable RegExp cache", desc = "Cache RegExp compilation") + @Expose + @JvmField + var regexCache = true } diff --git a/src/main/java/moe/nea/caelo/event/ResourceReloadEvent.kt b/src/main/java/moe/nea/caelo/event/ResourceReloadEvent.kt new file mode 100644 index 0000000..7afbc13 --- /dev/null +++ b/src/main/java/moe/nea/caelo/event/ResourceReloadEvent.kt @@ -0,0 +1,6 @@ +package moe.nea.caelo.event + +import net.minecraftforge.fml.common.eventhandler.Event + +class ResourceReloadEvent : Event() { +} \ No newline at end of file diff --git a/src/main/java/moe/nea/caelo/mixin/CacheNbtTagValueRegexMatch.java b/src/main/java/moe/nea/caelo/mixin/CacheNbtTagValueRegexMatch.java new file mode 100644 index 0000000..dc26781 --- /dev/null +++ b/src/main/java/moe/nea/caelo/mixin/CacheNbtTagValueRegexMatch.java @@ -0,0 +1,16 @@ +package moe.nea.caelo.mixin; + +import moe.nea.caelo.optifine.OptifineRegexCache; +import net.optifine.config.NbtTagValue; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(NbtTagValue.class) +public class CacheNbtTagValueRegexMatch { + @Inject(method = "matchesRegex", at = @At("HEAD"), cancellable = true) + private void onMatchesRegex(String str, String regex, CallbackInfoReturnable cir) { + OptifineRegexCache.INSTANCE.matchesRegex(str, regex, cir); + } +} diff --git a/src/main/java/moe/nea/caelo/optifine/OptifineCustomItemCache.kt b/src/main/java/moe/nea/caelo/optifine/OptifineCustomItemCache.kt index 244eff3..f343958 100644 --- a/src/main/java/moe/nea/caelo/optifine/OptifineCustomItemCache.kt +++ b/src/main/java/moe/nea/caelo/optifine/OptifineCustomItemCache.kt @@ -24,6 +24,7 @@ object OptifineCustomItemCache { MC.display("- Insertions: §b${cache.insertions}") MC.display("- Evictions: §b${cache.removals}") MC.display("- Cache Size: §b${cache.size}") + OptifineRegexCache.printStats() } } diff --git a/src/main/java/moe/nea/caelo/optifine/OptifineRegexCache.kt b/src/main/java/moe/nea/caelo/optifine/OptifineRegexCache.kt new file mode 100644 index 0000000..daded38 --- /dev/null +++ b/src/main/java/moe/nea/caelo/optifine/OptifineRegexCache.kt @@ -0,0 +1,50 @@ +package moe.nea.caelo.optifine + +import moe.nea.caelo.config.CConfig +import moe.nea.caelo.event.ResourceReloadEvent +import moe.nea.caelo.util.MC +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import org.apache.logging.log4j.LogManager +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable +import java.util.regex.Pattern + +object OptifineRegexCache { + val cache: MutableMap = mutableMapOf() + val illegalRegexes = mutableSetOf() + val logger = LogManager.getLogger() + val neverRegex = Pattern.compile("$.") + + @SubscribeEvent + fun onResourcePackReload(resourceReload: ResourceReloadEvent) { + cache.clear() + } + + private fun compilePattern(regex: String): Pattern { + return try { + Pattern.compile(regex) + } catch (ex: Exception) { + logger.error("Invalid regex $regex in optifine resource pack", ex) + illegalRegexes.add(regex) + neverRegex + } + } + + fun matchesRegex(str: String, regex: String, cir: CallbackInfoReturnable) { + if (!CConfig.config.optiCache.regexCache) return + val pattern = cache.computeIfAbsent(regex, ::compilePattern) + cir.returnValue = pattern.matcher(str).matches() + } + + fun printStats() { + MC.display("Regex Stats:") + MC.display("- Cache Size: §a${cache.size}") + if (illegalRegexes.isNotEmpty()) { + MC.display("- Illegal Regexes:") + for (illegalRegex in illegalRegexes) { + MC.display(" - §c${illegalRegex}") + } + } + } + + +} \ No newline at end of file -- cgit