From 59b2d849986d248db35bf3cf521be151281c5025 Mon Sep 17 00:00:00 2001 From: Relentless Date: Wed, 8 Feb 2023 01:36:49 +0100 Subject: [PATCH] Fix accessing runtime when not initialized (#32) Co-authored-by: Relentless --- .../almostreliable/unified/AlmostUnified.java | 4 +- .../unified/AlmostUnifiedFallbackRuntime.java | 81 ++++++++++++++ .../unified/AlmostUnifiedLookupImpl.java | 46 ++++---- .../unified/AlmostUnifiedRuntime.java | 88 ++------------- .../unified/AlmostUnifiedRuntimeImpl.java | 102 ++++++++++++++++++ .../unified/compat/AlmostJEI.java | 14 ++- .../unified/compat/AlmostREI.java | 16 ++- .../unified/compat/HideHelper.java | 11 +- gradle.properties | 2 +- 9 files changed, 248 insertions(+), 116 deletions(-) create mode 100644 Common/src/main/java/com/almostreliable/unified/AlmostUnifiedFallbackRuntime.java create mode 100644 Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntimeImpl.java diff --git a/Common/src/main/java/com/almostreliable/unified/AlmostUnified.java b/Common/src/main/java/com/almostreliable/unified/AlmostUnified.java index 36387bc..cab8431 100644 --- a/Common/src/main/java/com/almostreliable/unified/AlmostUnified.java +++ b/Common/src/main/java/com/almostreliable/unified/AlmostUnified.java @@ -29,7 +29,7 @@ public final class AlmostUnified { public static AlmostUnifiedRuntime getRuntime() { if (RUNTIME == null) { - throw new IllegalStateException("AlmostUnifiedRuntime not initialized"); + return AlmostUnifiedFallbackRuntime.getInstance(); } return RUNTIME; } @@ -39,7 +39,7 @@ public final class AlmostUnified { throw new IllegalStateException("Internal error. TagManager was not updated correctly"); } - RUNTIME = AlmostUnifiedRuntime.create(TAG_MANGER); + RUNTIME = AlmostUnifiedRuntimeImpl.create(TAG_MANGER); } public static void updateTagManager(TagManager tm) { diff --git a/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedFallbackRuntime.java b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedFallbackRuntime.java new file mode 100644 index 0000000..0e4e30e --- /dev/null +++ b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedFallbackRuntime.java @@ -0,0 +1,81 @@ +package com.almostreliable.unified; + +import com.almostreliable.unified.api.StoneStrataHandler; +import com.almostreliable.unified.config.Config; +import com.almostreliable.unified.config.UnifyConfig; +import com.almostreliable.unified.utils.ReplacementMap; +import com.almostreliable.unified.utils.TagMap; +import com.almostreliable.unified.utils.UnifyTag; +import com.google.gson.JsonElement; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; + +import javax.annotation.Nullable; +import java.util.*; + +// TODO: Implement sync so it's not just a fallback +public class AlmostUnifiedFallbackRuntime implements AlmostUnifiedRuntime { + + @Nullable private static AlmostUnifiedFallbackRuntime INSTANCE; + @Nullable private UnifyConfig config; + @Nullable private ReplacementMap replacementMap; + @Nullable private TagMap filteredTagMap; + + public static AlmostUnifiedFallbackRuntime getInstance() { + if (INSTANCE == null) { + INSTANCE = new AlmostUnifiedFallbackRuntime(); + INSTANCE.reload(); + } + + return INSTANCE; + } + + public void reload() { + config = null; + replacementMap = null; + filteredTagMap = null; + build(); + } + + private UnifyConfig getConfig() { + if (config == null) { + config = Config.load(UnifyConfig.NAME, new UnifyConfig.Serializer()); + } + + return config; + } + + public void build() { + var config = getConfig(); + List> unifyTags = config.bakeTags(); + filteredTagMap = TagMap.create(unifyTags).filtered($ -> true, config::includeItem); + StoneStrataHandler stoneStrataHandler = getStoneStrataHandler(config); + replacementMap = new ReplacementMap(Objects.requireNonNull(filteredTagMap), stoneStrataHandler, config); + } + + private static StoneStrataHandler getStoneStrataHandler(UnifyConfig config) { + Set> stoneStrataTags = AlmostUnifiedPlatform.INSTANCE.getStoneStrataTags(config.getStoneStrata()); + TagMap stoneStrataTagMap = TagMap.create(stoneStrataTags); + return StoneStrataHandler.create(config.getStoneStrata(), stoneStrataTags, stoneStrataTagMap); + } + + @Override + public void run(Map recipes, boolean skipClientTracking) { + // no-op + } + + @Override + public Optional getFilteredTagMap() { + return Optional.ofNullable(filteredTagMap); + } + + @Override + public Optional getReplacementMap() { + return Optional.ofNullable(replacementMap); + } + + @Override + public Optional getUnifyConfig() { + return Optional.ofNullable(config); + } +} diff --git a/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedLookupImpl.java b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedLookupImpl.java index 69cac6d..ae427d8 100644 --- a/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedLookupImpl.java +++ b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedLookupImpl.java @@ -26,30 +26,36 @@ public class AlmostUnifiedLookupImpl implements AlmostUnifiedLookup { @Override public Item getReplacementForItem(ItemLike itemLike) { ResourceLocation id = BuiltInRegistries.ITEM.getKey(itemLike.asItem()); - ResourceLocation result = AlmostUnified.getRuntime().getReplacementMap().getReplacementForItem(id); - return BuiltInRegistries.ITEM.getOptional(result).orElse(null); + return AlmostUnified + .getRuntime() + .getReplacementMap() + .map(rm -> rm.getReplacementForItem(id)) + .flatMap(BuiltInRegistries.ITEM::getOptional) + .orElse(null); } @Nullable @Override public Item getPreferredItemForTag(TagKey tag) { UnifyTag asUnifyTag = UnifyTag.item(tag.location()); - ResourceLocation result = AlmostUnified + return AlmostUnified .getRuntime() .getReplacementMap() - .getPreferredItemForTag(asUnifyTag, $ -> true); - return BuiltInRegistries.ITEM.getOptional(result).orElse(null); + .map(rm -> rm.getPreferredItemForTag(asUnifyTag, $ -> true)) + .flatMap(BuiltInRegistries.ITEM::getOptional) + .orElse(null); } @Nullable @Override public TagKey getPreferredTagForItem(ItemLike itemLike) { ResourceLocation id = BuiltInRegistries.ITEM.getKey(itemLike.asItem()); - UnifyTag unifyTag = AlmostUnified.getRuntime().getReplacementMap().getPreferredTagForItem(id); - if (unifyTag == null) { - return null; - } - return TagKey.create(Registries.ITEM, unifyTag.location()); + return AlmostUnified + .getRuntime() + .getReplacementMap() + .map(rm -> rm.getPreferredTagForItem(id)) + .map(ut -> TagKey.create(Registries.ITEM, ut.location())) + .orElse(null); } @Override @@ -58,10 +64,12 @@ public class AlmostUnifiedLookupImpl implements AlmostUnifiedLookup { return AlmostUnified .getRuntime() .getFilteredTagMap() - .getItems(asUnifyTag) - .stream() - .flatMap(rl -> BuiltInRegistries.ITEM.getOptional(rl).stream()) - .collect(Collectors.toSet()); + .map(tagMap -> tagMap + .getItems(asUnifyTag) + .stream() + .flatMap(rl -> BuiltInRegistries.ITEM.getOptional(rl).stream()) + .collect(Collectors.toSet())) + .orElseGet(Set::of); } @Override @@ -69,9 +77,11 @@ public class AlmostUnifiedLookupImpl implements AlmostUnifiedLookup { return AlmostUnified .getRuntime() .getFilteredTagMap() - .getTags() - .stream() - .map(ut -> TagKey.create(Registries.ITEM, ut.location())) - .collect(Collectors.toSet()); + .map(tagMap -> tagMap + .getTags() + .stream() + .map(ut -> TagKey.create(Registries.ITEM, ut.location())) + .collect(Collectors.toSet())) + .orElseGet(Set::of); } } diff --git a/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntime.java b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntime.java index 9260a42..6adfc94 100644 --- a/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntime.java +++ b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntime.java @@ -1,97 +1,21 @@ package com.almostreliable.unified; -import com.almostreliable.unified.api.StoneStrataHandler; -import com.almostreliable.unified.config.Config; -import com.almostreliable.unified.config.DebugConfig; -import com.almostreliable.unified.config.DuplicationConfig; import com.almostreliable.unified.config.UnifyConfig; -import com.almostreliable.unified.recipe.RecipeDumper; -import com.almostreliable.unified.recipe.RecipeTransformer; -import com.almostreliable.unified.recipe.unifier.RecipeHandlerFactory; -import com.almostreliable.unified.utils.FileUtils; import com.almostreliable.unified.utils.ReplacementMap; import com.almostreliable.unified.utils.TagMap; -import com.almostreliable.unified.utils.UnifyTag; import com.google.gson.JsonElement; import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagManager; -import net.minecraft.world.item.Item; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; import java.util.Map; -import java.util.Objects; +import java.util.Optional; -public final class AlmostUnifiedRuntime { - private final RecipeHandlerFactory recipeHandlerFactory; - private final TagMap filteredTagMap; - private final DuplicationConfig dupConfig; - private final UnifyConfig unifyConfig; - private final DebugConfig debugConfig; - private final ReplacementMap replacementMap; +public interface AlmostUnifiedRuntime { - private AlmostUnifiedRuntime(RecipeHandlerFactory recipeHandlerFactory, TagMap tagMap, DuplicationConfig dupConfig, UnifyConfig unifyConfig, DebugConfig debugConfig) { - this.recipeHandlerFactory = recipeHandlerFactory; - this.dupConfig = dupConfig; - this.unifyConfig = unifyConfig; - this.debugConfig = debugConfig; - List> allowedTags = unifyConfig.bakeTags(); - this.filteredTagMap = tagMap.filtered(allowedTags::contains, unifyConfig::includeItem); - StoneStrataHandler stoneStrataHandler = StoneStrataHandler.create(unifyConfig.getStoneStrata(), - AlmostUnifiedPlatform.INSTANCE.getStoneStrataTags(unifyConfig.getStoneStrata()), - tagMap); - this.replacementMap = new ReplacementMap(filteredTagMap, stoneStrataHandler, unifyConfig); - } + void run(Map recipes, boolean skipClientTracking); - public static AlmostUnifiedRuntime create(TagManager tagManager) { - Objects.requireNonNull(tagManager); + Optional getFilteredTagMap(); - createGitIgnoreIfNotExists(); - DuplicationConfig dupConfig = Config.load(DuplicationConfig.NAME, new DuplicationConfig.Serializer()); - UnifyConfig unifyConfig = Config.load(UnifyConfig.NAME, new UnifyConfig.Serializer()); - DebugConfig debugConfig = Config.load(DebugConfig.NAME, new DebugConfig.Serializer()); + Optional getReplacementMap(); - RecipeHandlerFactory factory = new RecipeHandlerFactory(); - AlmostUnifiedPlatform.INSTANCE.bindRecipeHandlers(factory); - - TagMap tagMap = TagMap.create(tagManager); - return new AlmostUnifiedRuntime(factory, tagMap, dupConfig, unifyConfig, debugConfig); - } - - private static void createGitIgnoreIfNotExists() { - Path path = AlmostUnifiedPlatform.INSTANCE.getConfigPath(); - if (!(Files.exists(path) && Files.isDirectory(path))) { - FileUtils.write(AlmostUnifiedPlatform.INSTANCE.getConfigPath(), - ".gitignore", - sb -> sb.append(DebugConfig.NAME).append(".json").append("\n")); - } - } - - public void run(Map recipes, boolean skipClientTracking) { - debugConfig.logRecipes(recipes, "recipes_before_unification.txt"); - debugConfig.logUnifyTagDump(filteredTagMap); - - long startTime = System.currentTimeMillis(); - RecipeTransformer.Result result = new RecipeTransformer(recipeHandlerFactory, - replacementMap, - unifyConfig, - dupConfig).transformRecipes(recipes, skipClientTracking); - RecipeDumper dumper = new RecipeDumper(result, startTime, System.currentTimeMillis()); - dumper.dump(debugConfig.dumpOverview, debugConfig.dumpUnification, debugConfig.dumpDuplicates); - - debugConfig.logRecipes(recipes, "recipes_after_unification.txt"); - } - - public TagMap getFilteredTagMap() { - return filteredTagMap; - } - - public ReplacementMap getReplacementMap() { - return replacementMap; - } - - public UnifyConfig getUnifyConfig() { - return unifyConfig; - } + Optional getUnifyConfig(); } diff --git a/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntimeImpl.java b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntimeImpl.java new file mode 100644 index 0000000..82d82a6 --- /dev/null +++ b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntimeImpl.java @@ -0,0 +1,102 @@ +package com.almostreliable.unified; + +import com.almostreliable.unified.api.StoneStrataHandler; +import com.almostreliable.unified.config.Config; +import com.almostreliable.unified.config.DebugConfig; +import com.almostreliable.unified.config.DuplicationConfig; +import com.almostreliable.unified.config.UnifyConfig; +import com.almostreliable.unified.recipe.RecipeDumper; +import com.almostreliable.unified.recipe.RecipeTransformer; +import com.almostreliable.unified.recipe.unifier.RecipeHandlerFactory; +import com.almostreliable.unified.utils.FileUtils; +import com.almostreliable.unified.utils.ReplacementMap; +import com.almostreliable.unified.utils.TagMap; +import com.almostreliable.unified.utils.UnifyTag; +import com.google.gson.JsonElement; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagManager; +import net.minecraft.world.item.Item; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +public final class AlmostUnifiedRuntimeImpl implements AlmostUnifiedRuntime { + private final RecipeHandlerFactory recipeHandlerFactory; + private final TagMap filteredTagMap; + private final DuplicationConfig dupConfig; + private final UnifyConfig unifyConfig; + private final DebugConfig debugConfig; + private final ReplacementMap replacementMap; + + private AlmostUnifiedRuntimeImpl(RecipeHandlerFactory recipeHandlerFactory, TagMap tagMap, DuplicationConfig dupConfig, UnifyConfig unifyConfig, DebugConfig debugConfig) { + this.recipeHandlerFactory = recipeHandlerFactory; + this.dupConfig = dupConfig; + this.unifyConfig = unifyConfig; + this.debugConfig = debugConfig; + List> allowedTags = unifyConfig.bakeTags(); + this.filteredTagMap = tagMap.filtered(allowedTags::contains, unifyConfig::includeItem); + StoneStrataHandler stoneStrataHandler = StoneStrataHandler.create(unifyConfig.getStoneStrata(), + AlmostUnifiedPlatform.INSTANCE.getStoneStrataTags(unifyConfig.getStoneStrata()), + tagMap); + this.replacementMap = new ReplacementMap(filteredTagMap, stoneStrataHandler, unifyConfig); + } + + public static AlmostUnifiedRuntimeImpl create(TagManager tagManager) { + Objects.requireNonNull(tagManager); + + createGitIgnoreIfNotExists(); + DuplicationConfig dupConfig = Config.load(DuplicationConfig.NAME, new DuplicationConfig.Serializer()); + UnifyConfig unifyConfig = Config.load(UnifyConfig.NAME, new UnifyConfig.Serializer()); + DebugConfig debugConfig = Config.load(DebugConfig.NAME, new DebugConfig.Serializer()); + + RecipeHandlerFactory factory = new RecipeHandlerFactory(); + AlmostUnifiedPlatform.INSTANCE.bindRecipeHandlers(factory); + + TagMap tagMap = TagMap.create(tagManager); + return new AlmostUnifiedRuntimeImpl(factory, tagMap, dupConfig, unifyConfig, debugConfig); + } + + private static void createGitIgnoreIfNotExists() { + Path path = AlmostUnifiedPlatform.INSTANCE.getConfigPath(); + if (!(Files.exists(path) && Files.isDirectory(path))) { + FileUtils.write(AlmostUnifiedPlatform.INSTANCE.getConfigPath(), + ".gitignore", + sb -> sb.append(DebugConfig.NAME).append(".json").append("\n")); + } + } + + @Override + public void run(Map recipes, boolean skipClientTracking) { + debugConfig.logRecipes(recipes, "recipes_before_unification.txt"); + debugConfig.logUnifyTagDump(filteredTagMap); + + long startTime = System.currentTimeMillis(); + RecipeTransformer.Result result = new RecipeTransformer(recipeHandlerFactory, + replacementMap, + unifyConfig, + dupConfig).transformRecipes(recipes, skipClientTracking); + RecipeDumper dumper = new RecipeDumper(result, startTime, System.currentTimeMillis()); + dumper.dump(debugConfig.dumpOverview, debugConfig.dumpUnification, debugConfig.dumpDuplicates); + + debugConfig.logRecipes(recipes, "recipes_after_unification.txt"); + } + + @Override + public Optional getFilteredTagMap() { + return Optional.of(filteredTagMap); + } + + @Override + public Optional getReplacementMap() { + return Optional.of(replacementMap); + } + + @Override + public Optional getUnifyConfig() { + return Optional.of(unifyConfig); + } +} diff --git a/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java b/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java index 99303e1..f241ed1 100644 --- a/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java +++ b/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java @@ -1,7 +1,8 @@ package com.almostreliable.unified.compat; +import com.almostreliable.unified.AlmostUnified; +import com.almostreliable.unified.AlmostUnifiedFallbackRuntime; import com.almostreliable.unified.api.ModConstants; -import com.almostreliable.unified.config.Config; import com.almostreliable.unified.config.UnifyConfig; import com.almostreliable.unified.recipe.CRTLookup; import com.almostreliable.unified.utils.Utils; @@ -29,10 +30,15 @@ public class AlmostJEI implements IModPlugin { @Override public void onRuntimeAvailable(IJeiRuntime jei) { - UnifyConfig config = Config.load(UnifyConfig.NAME, new UnifyConfig.Serializer()); - if (config.reiOrJeiDisabled()) return; + AlmostUnifiedFallbackRuntime.getInstance().reload(); - Collection items = HideHelper.createHidingList(config); + Boolean jeiDisabled = AlmostUnified.getRuntime() + .getUnifyConfig() + .map(UnifyConfig::reiOrJeiDisabled) + .orElse(false); + if (jeiDisabled) return; + + Collection items = HideHelper.createHidingList(AlmostUnified.getRuntime()); if (!items.isEmpty()) { jei.getIngredientManager().removeIngredientsAtRuntime(VanillaTypes.ITEM_STACK, items); } diff --git a/Common/src/main/java/com/almostreliable/unified/compat/AlmostREI.java b/Common/src/main/java/com/almostreliable/unified/compat/AlmostREI.java index 0174f4f..0c4c5a1 100644 --- a/Common/src/main/java/com/almostreliable/unified/compat/AlmostREI.java +++ b/Common/src/main/java/com/almostreliable/unified/compat/AlmostREI.java @@ -1,8 +1,9 @@ package com.almostreliable.unified.compat; +import com.almostreliable.unified.AlmostUnified; +import com.almostreliable.unified.AlmostUnifiedFallbackRuntime; import com.almostreliable.unified.ClientTagUpdateEvent; import com.almostreliable.unified.api.ModConstants; -import com.almostreliable.unified.config.Config; import com.almostreliable.unified.config.UnifyConfig; import com.almostreliable.unified.recipe.CRTLookup; import com.almostreliable.unified.recipe.ClientRecipeTracker.ClientRecipeLink; @@ -46,9 +47,16 @@ public class AlmostREI implements REIClientPlugin { @Override public void registerBasicEntryFiltering(BasicFilteringRule rule) { filterUpdate = rule.hide(() -> { - UnifyConfig config = Config.load(UnifyConfig.NAME, new UnifyConfig.Serializer()); - if (config.reiOrJeiDisabled()) return List.of(); - return EntryIngredients.ofItemStacks(HideHelper.createHidingList(config)); + AlmostUnifiedFallbackRuntime.getInstance().reload(); + + var reiDisabled = AlmostUnified + .getRuntime() + .getUnifyConfig() + .map(UnifyConfig::reiOrJeiDisabled) + .orElse(false); + if (reiDisabled) return List.of(); + + return EntryIngredients.ofItemStacks(HideHelper.createHidingList(AlmostUnified.getRuntime())); }); } diff --git a/Common/src/main/java/com/almostreliable/unified/compat/HideHelper.java b/Common/src/main/java/com/almostreliable/unified/compat/HideHelper.java index 23c1ba1..c1af431 100644 --- a/Common/src/main/java/com/almostreliable/unified/compat/HideHelper.java +++ b/Common/src/main/java/com/almostreliable/unified/compat/HideHelper.java @@ -2,6 +2,7 @@ package com.almostreliable.unified.compat; import com.almostreliable.unified.AlmostUnified; import com.almostreliable.unified.AlmostUnifiedPlatform; +import com.almostreliable.unified.AlmostUnifiedRuntime; import com.almostreliable.unified.api.StoneStrataHandler; import com.almostreliable.unified.config.UnifyConfig; import com.almostreliable.unified.utils.ReplacementMap; @@ -17,11 +18,11 @@ import java.util.stream.Collectors; public class HideHelper { - public static Collection createHidingList(UnifyConfig config) { - List> unifyTags = config.bakeTags(); - TagMap filteredTagMap = TagMap.create(unifyTags).filtered($ -> true, config::includeItem); - StoneStrataHandler stoneStrataHandler = getStoneStrataHandler(config); - ReplacementMap repMap = new ReplacementMap(filteredTagMap, stoneStrataHandler, config); + public static Collection createHidingList(AlmostUnifiedRuntime runtime) { + ReplacementMap repMap = runtime.getReplacementMap().orElse(null); + TagMap filteredTagMap = runtime.getFilteredTagMap().orElse(null); + + if (repMap == null || filteredTagMap == null) return new ArrayList<>(); return filteredTagMap.getTags().stream().map(unifyTag -> { Collection itemsByTag = filteredTagMap.getItems(unifyTag); diff --git a/gradle.properties b/gradle.properties index a6ee2f2..97f5b29 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ group = com.almostreliable.mods license = GNU Lesser General Public License v3.0 enabledPlatforms = fabric,forge enableAccessWidener = false -sharedRunDir = true +sharedRunDir = false extraModsDirectory = extra-mods junitVersion = 5.9.0