From f50641a67956111107eff933227ea5dfd6cdea69 Mon Sep 17 00:00:00 2001 From: Integer Limit <103940576+IntegerLimit@users.noreply.github.com> Date: Thu, 9 Jan 2025 15:46:40 +0800 Subject: [PATCH] Allow Caching Crafting Recipe Outputs --- .../nomiceu/nomilabs/config/LabsConfig.java | 16 ++++++ .../com/nomiceu/nomilabs/core/LabsCore.java | 5 +- .../nomiceu/nomilabs/event/CommonProxy.java | 5 ++ .../mixinhelper/CraftingOutputCache.java | 37 +++++++++++++ .../mixin/earlygroovy/CraftingMixin.java | 53 +++++++++++++++++++ .../resources/assets/nomilabs/lang/en_us.lang | 1 + .../mixins.nomilabs.earlygroovy.json | 12 +++++ 7 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/nomiceu/nomilabs/groovy/mixinhelper/CraftingOutputCache.java create mode 100644 src/main/java/com/nomiceu/nomilabs/mixin/earlygroovy/CraftingMixin.java create mode 100644 src/main/resources/mixins.nomilabs.earlygroovy.json diff --git a/src/main/java/com/nomiceu/nomilabs/config/LabsConfig.java b/src/main/java/com/nomiceu/nomilabs/config/LabsConfig.java index 44da34ac..eafd0522 100644 --- a/src/main/java/com/nomiceu/nomilabs/config/LabsConfig.java +++ b/src/main/java/com/nomiceu/nomilabs/config/LabsConfig.java @@ -185,6 +185,22 @@ public enum GTRecipeSearchMode { FAST_DISCARDED_TREE, DISCARDED_TREE, } + + @Config.Comment({ "Mode to Use for Crafting Output Cache.", + "DISABLED keeps the default behaviour of searching through all Crafting Recipes.", + "DISCARDED or SAVED caches outputs of recipes. This cache is used when removing/replacing by output, with an ItemStack.", + "This causes two changes in behaviour: Output Removing/Replacing no longer removes GroovyScript added recipes, and Output Removing/Replacing only matches based on item and meta, ignoring NBT.", + "If the NBT tag is desired to be matched, a non-ItemStack IIngredient should be used for output searching.", + "DISCARDED discards the cache after script loading, saving memory during gameplay. SAVED keeps the cache during gameplay, removing the need to rebuild the cache for reloading.", + "[default: DISABLED]" }) + @Config.LangKey("config.nomilabs.groovy.crafting_output_cache") + public CraftingOutputCacheMode craftingOutputCacheMode = CraftingOutputCacheMode.DISABLED; + + public enum CraftingOutputCacheMode { + DISABLED, + DISCARDED, + SAVED + } } public static class TheOneProbeSettings { diff --git a/src/main/java/com/nomiceu/nomilabs/core/LabsCore.java b/src/main/java/com/nomiceu/nomilabs/core/LabsCore.java index c7c86081..a7afc3c9 100644 --- a/src/main/java/com/nomiceu/nomilabs/core/LabsCore.java +++ b/src/main/java/com/nomiceu/nomilabs/core/LabsCore.java @@ -49,8 +49,9 @@ public String getAccessTransformerClass() { @Override public List getMixinConfigs() { return ImmutableList.of( - "mixins.nomilabs.json", - "mixins." + LabsValues.LABS_MODID + "." + devIdentifier + ".json"); + "mixins." + LabsValues.LABS_MODID + ".json", + "mixins." + LabsValues.LABS_MODID + "." + devIdentifier + ".json", + "mixins." + LabsValues.LABS_MODID + ".earlygroovy.json"); } @Override diff --git a/src/main/java/com/nomiceu/nomilabs/event/CommonProxy.java b/src/main/java/com/nomiceu/nomilabs/event/CommonProxy.java index 34b7da9c..787be780 100644 --- a/src/main/java/com/nomiceu/nomilabs/event/CommonProxy.java +++ b/src/main/java/com/nomiceu/nomilabs/event/CommonProxy.java @@ -39,6 +39,7 @@ import com.nomiceu.nomilabs.groovy.GroovyScriptHandManager; import com.nomiceu.nomilabs.groovy.NBTClearingRecipe; import com.nomiceu.nomilabs.groovy.NCActiveCoolerHelper; +import com.nomiceu.nomilabs.groovy.mixinhelper.CraftingOutputCache; import com.nomiceu.nomilabs.integration.architecturecraft.LabsShapes; import com.nomiceu.nomilabs.integration.betterp2p.LabsBetterMemoryCardModes; import com.nomiceu.nomilabs.integration.jei.LabsJEIPlugin; @@ -226,5 +227,9 @@ public static void afterScriptLoad(ScriptRunEvent.Post event) { if (Loader.isModLoaded(LabsValues.NUCLEARCRAFT_MODID)) { NCActiveCoolerHelper.afterScriptLoad(); } + + if (LabsConfig.groovyScriptSettings.craftingOutputCacheMode == + LabsConfig.GroovyScriptSettings.CraftingOutputCacheMode.DISCARDED) + CraftingOutputCache.cache = null; } } diff --git a/src/main/java/com/nomiceu/nomilabs/groovy/mixinhelper/CraftingOutputCache.java b/src/main/java/com/nomiceu/nomilabs/groovy/mixinhelper/CraftingOutputCache.java new file mode 100644 index 00000000..af39dce8 --- /dev/null +++ b/src/main/java/com/nomiceu/nomilabs/groovy/mixinhelper/CraftingOutputCache.java @@ -0,0 +1,37 @@ +package com.nomiceu.nomilabs.groovy.mixinhelper; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.registry.ForgeRegistries; + +import com.nomiceu.nomilabs.NomiLabs; +import com.nomiceu.nomilabs.util.ItemMeta; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; + +public class CraftingOutputCache { + + public static Map> cache = null; + + public static void buildCache() { + if (cache != null) return; + + cache = new Object2ObjectOpenHashMap<>(); + + long time = System.currentTimeMillis(); + for (IRecipe recipe : ForgeRegistries.RECIPES) { + ItemStack output = recipe.getRecipeOutput(); + if (output.isEmpty()) continue; + + cache.computeIfAbsent(new ItemMeta(output), k -> new ArrayList<>()) + .add(recipe.getRegistryName()); + } + time = System.currentTimeMillis() - time; + NomiLabs.LOGGER.info("[GrS] Building Crafting Output Cache took {}ms.", time); + } +} diff --git a/src/main/java/com/nomiceu/nomilabs/mixin/earlygroovy/CraftingMixin.java b/src/main/java/com/nomiceu/nomilabs/mixin/earlygroovy/CraftingMixin.java new file mode 100644 index 00000000..e1a00528 --- /dev/null +++ b/src/main/java/com/nomiceu/nomilabs/mixin/earlygroovy/CraftingMixin.java @@ -0,0 +1,53 @@ +package com.nomiceu.nomilabs.mixin.earlygroovy; + +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.registry.ForgeRegistries; + +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.CallbackInfo; + +import com.cleanroommc.groovyscript.api.GroovyLog; +import com.cleanroommc.groovyscript.api.IIngredient; +import com.cleanroommc.groovyscript.compat.vanilla.Crafting; +import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper; +import com.cleanroommc.groovyscript.registry.ReloadableRegistryManager; +import com.nomiceu.nomilabs.config.LabsConfig; +import com.nomiceu.nomilabs.groovy.mixinhelper.CraftingOutputCache; +import com.nomiceu.nomilabs.util.ItemMeta; + +@Mixin(value = Crafting.class, remap = false) +public class CraftingMixin { + + @Inject(method = "removeByOutput(Lcom/cleanroommc/groovyscript/api/IIngredient;Z)V", + at = @At(value = "HEAD"), + cancellable = true) + private void useOutputCache(IIngredient output, boolean log, CallbackInfo ci) { + if (LabsConfig.groovyScriptSettings.craftingOutputCacheMode == + LabsConfig.GroovyScriptSettings.CraftingOutputCacheMode.DISABLED) + return; + + // noinspection ConstantValue + if (IngredientHelper.isEmpty(output) || !((Object) output instanceof ItemStack stack)) return; + + ci.cancel(); + CraftingOutputCache.buildCache(); + var itemMeta = new ItemMeta(stack); + + if (!CraftingOutputCache.cache.containsKey(itemMeta)) { + if (log) { + GroovyLog.msg("Error removing Minecraft Crafting recipe") + .add("No recipes found for {}", output) + .error() + .post(); + } + return; + } + + for (ResourceLocation rl : CraftingOutputCache.cache.get(itemMeta)) { + ReloadableRegistryManager.removeRegistryEntry(ForgeRegistries.RECIPES, rl); + } + } +} diff --git a/src/main/resources/assets/nomilabs/lang/en_us.lang b/src/main/resources/assets/nomilabs/lang/en_us.lang index 83c94efc..3f06b064 100644 --- a/src/main/resources/assets/nomilabs/lang/en_us.lang +++ b/src/main/resources/assets/nomilabs/lang/en_us.lang @@ -79,6 +79,7 @@ config.nomilabs.groovy=GroovyScript Extensions and Script Helper Settings config.nomilabs.groovy.tooltip=GroovyScript Extensions and Script Helper Settings config.nomilabs.groovy.hand=Enable GroovyScript Hand Command Additions config.nomilabs.groovy.recipe_search_mode=GregTech Recipe Output Search Mode +config.nomilabs.groovy.crafting_output_cache=Crafting Output Cache Mode config.nomilabs.top=The One Probe Settings config.nomilabs.top.tooltip=The One Probe Settings diff --git a/src/main/resources/mixins.nomilabs.earlygroovy.json b/src/main/resources/mixins.nomilabs.earlygroovy.json new file mode 100644 index 00000000..f97f2235 --- /dev/null +++ b/src/main/resources/mixins.nomilabs.earlygroovy.json @@ -0,0 +1,12 @@ +{ + "package": "com.nomiceu.nomilabs.mixin.earlygroovy", + "refmap": "mixins.nomilabs.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "CraftingMixin" + ], + "client": [], + "server": [] +}