Prepare clean up

This commit is contained in:
LLytho 2022-06-17 17:56:32 +02:00
parent 977273241a
commit e699714835
6 changed files with 113 additions and 64 deletions

View file

@ -1,24 +1,19 @@
package com.almostreliable.unified;
import com.almostreliable.unified.api.RecipeTransformContext;
import com.almostreliable.unified.api.RecipeTransformer;
import com.almostreliable.unified.api.RecipeTransformerFactory;
import com.almostreliable.unified.api.RecipeTransformerRegistry;
import com.almostreliable.unified.api.ReplacementLookupHelper;
import com.almostreliable.unified.transformer.GenericRecipeTransformer;
import com.almostreliable.unified.transformer.GenericRecipeTransformerFactory;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.Tag;
import net.minecraft.tags.TagManager;
import org.apache.commons.lang3.time.StopWatch;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -26,7 +21,6 @@ import java.util.Map;
public class AlmostUnifiedRuntime {
protected final ModConfig config;
protected final RecipeTransformer defaultTransformer = new GenericRecipeTransformer();
protected final RecipeTransformerFactory defaultFactory = new GenericRecipeTransformerFactory();
@Nullable protected TagManager tagManager;
@ -36,11 +30,11 @@ public class AlmostUnifiedRuntime {
public void run(Map<ResourceLocation, JsonElement> recipes) {
config.load();
ReplacementLookupHelper helper = createHelper(config.getAllowedTags(), config.getModPriorities());
transformRecipes(recipes, helper);
RecipeTransformContext helper = createContext(config.getAllowedTags(), config.getModPriorities());
// transformRecipes(recipes, helper);
}
public void transformRecipes(Map<ResourceLocation, JsonElement> recipes, ReplacementLookupHelper helper) {
public void transformRecipes(Map<ResourceLocation, JsonElement> recipes, RecipeTransformContext helper) {
int transformedRecipes = 0;
int transformedPropertiesInRecipes = 0;
long start = System.nanoTime();
@ -62,7 +56,7 @@ public class AlmostUnifiedRuntime {
timeElapsed / 1000_000D);
}
public int transformRecipe(JsonObject json, ReplacementLookupHelper helper) {
public int transformRecipe(JsonObject json, RecipeTransformContext helper) {
ResourceLocation recipeType = getRecipeType(json);
if (recipeType == null) {
return 0;
@ -106,42 +100,29 @@ public class AlmostUnifiedRuntime {
this.tagManager = tagManager;
}
protected ReplacementLookupHelper createHelper(List<ResourceLocation> allowedTags, List<String> modPriorities) {
protected RecipeTransformContext createContext(List<ResourceLocation> allowedTags, List<String> modPriorities) {
if (tagManager == null) {
throw new IllegalStateException("Internal error. TagManager was not updated correctly");
}
var tags = tagManager
.getResult()
.stream()
.filter(result -> result.key().equals(Registry.ITEM_REGISTRY))
.findFirst()
.map(TagManager.LoadResult::tags)
.orElseThrow(() -> new IllegalStateException("No item tag result found"));
Map<ResourceLocation, ResourceLocation> itemTagMap = new HashMap<>();
Multimap<ResourceLocation, ResourceLocation> tagToEntry = HashMultimap.create();
TagMap tagMap = TagMap.create(tagManager);
Map<ResourceLocation, ResourceLocation> itemToTagMapping = new HashMap<>(allowedTags.size());
for (ResourceLocation allowedTag : allowedTags) {
Tag<? extends Holder<?>> holderTag = tags.get(allowedTag);
if (holderTag == null) {
continue;
}
for (Holder<?> holder : holderTag.getValues()) {
ResourceLocation itemId = holder.unwrapKey().map(ResourceKey::location).orElse(null);
if (itemTagMap.containsKey(itemId)) {
for (ResourceLocation tag : allowedTags) {
Collection<ResourceLocation> items = tagMap.getItems(tag);
for (ResourceLocation item : items) {
if (itemToTagMapping.containsKey(item)) {
AlmostUnified.LOG.warn("Item '{}' already has a tag '{}' for recipe replacement. Skipping this tag",
itemId,
allowedTag);
item,
tag);
continue;
}
itemTagMap.put(itemId, allowedTag);
tagToEntry.put(allowedTag, itemId);
itemToTagMapping.put(item, tag);
}
}
return new LookupByModPriority(itemTagMap, tagToEntry, modPriorities);
return new RecipeTransformContextImpl(tagMap, itemToTagMapping, modPriorities);
}
}

View file

@ -1,6 +1,6 @@
package com.almostreliable.unified;
import com.almostreliable.unified.api.ReplacementLookupHelper;
import com.almostreliable.unified.api.RecipeTransformContext;
import com.google.common.collect.Multimap;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
@ -8,20 +8,21 @@ import net.minecraft.resources.ResourceLocation;
import javax.annotation.Nullable;
import java.util.*;
public class LookupByModPriority implements ReplacementLookupHelper {
private final Collection<String> modPriorities;
private final Map<ResourceLocation, ResourceLocation> itemToTag;
private final Multimap<ResourceLocation, ResourceLocation> tagToItem;
public class RecipeTransformContextImpl implements RecipeTransformContext {
private final Collection<String> modPriorities;
private final TagMap tagMap;
private final Map<ResourceLocation, ResourceLocation> itemToTagMapping;
/**
* Cache for replacements. Key is the item to replace, value is the replacement.
*/
private final Map<ResourceLocation, ResourceLocation> replacementCache = new HashMap<>();
private final Set<ResourceLocation> invalidCache = new HashSet<>();
public LookupByModPriority(Map<ResourceLocation, ResourceLocation> itemToTag, Multimap<ResourceLocation, ResourceLocation> tagToItem, Collection<String> modPriorities) {
this.itemToTag = itemToTag;
this.tagToItem = tagToItem;
public RecipeTransformContextImpl(TagMap tagMap, Map<ResourceLocation, ResourceLocation> itemToTagMapping, List<String> modPriorities) {
this.tagMap = tagMap;
this.itemToTagMapping = itemToTagMapping;
this.modPriorities = modPriorities;
}
@ -38,12 +39,12 @@ public class LookupByModPriority implements ReplacementLookupHelper {
return replacement.toString();
}
ResourceLocation tagRL = itemToTag.get(asLocation);
if (!Registry.ITEM.containsKey(asLocation) || tagRL == null) {
ResourceLocation tag = itemToTagMapping.get(asLocation);
if (!Registry.ITEM.containsKey(asLocation) || tag == null) {
return null;
}
ResourceLocation modReplacement = computeReplacement(asLocation, tagToItem.get(tagRL));
ResourceLocation modReplacement = computeReplacement(asLocation, tag, tagMap.getItems(tag));
if(modReplacement == null || modReplacement.equals(asLocation)) {
invalidCache.add(asLocation);
return null;
@ -55,15 +56,26 @@ public class LookupByModPriority implements ReplacementLookupHelper {
}
@Nullable
private ResourceLocation computeReplacement(ResourceLocation toReplace, Collection<ResourceLocation> items) {
public ResourceLocation computeReplacement(ResourceLocation toReplace, ResourceLocation tag, Collection<ResourceLocation> items) {
for (String mod : modPriorities) {
for (ResourceLocation item : items) {
if (item.getNamespace().equals(mod) && Registry.ITEM.containsKey(item)) {
return item;
}
List<ResourceLocation> sameModItems = tagMap
.getItems(tag)
.stream()
.filter(item -> item.getNamespace().equals(mod) && Registry.ITEM.containsKey(item))
.toList();
if(sameModItems.size() == 1) {
return sameModItems.get(0);
}
if(sameModItems.size() > 1) {
return findFittingItem(toReplace, tag, sameModItems);
}
}
return null;
}
public ResourceLocation findFittingItem(ResourceLocation toReplace, ResourceLocation tag, List<ResourceLocation> sameModItems) {
return null;
}
}

View file

@ -0,0 +1,58 @@
package com.almostreliable.unified;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.Tag;
import net.minecraft.tags.TagManager;
import java.util.*;
public class TagMap {
private final Map<ResourceLocation, Set<ResourceLocation>> tagsToItems = new HashMap<>();
private final Map<ResourceLocation, Set<ResourceLocation>> itemsToTags = new HashMap<>();
protected TagMap() {}
public static TagMap create(TagManager tagManager) {
Objects.requireNonNull(tagManager, "Requires a non-null tag manager");
var tags = tagManager
.getResult()
.stream()
.filter(result -> result.key().equals(Registry.ITEM_REGISTRY))
.findFirst()
.map(TagManager.LoadResult::tags)
.orElseThrow(() -> new IllegalStateException("No item tag result found"));
TagMap tagMap = new TagMap();
for (var entry : tags.entrySet()) {
ResourceLocation tag = entry.getKey();
Tag<? extends Holder<?>> holderTag = entry.getValue();
for (Holder<?> holder : holderTag.getValues()) {
ResourceLocation itemId = holder.unwrapKey().map(ResourceKey::location).orElse(null);
if (itemId != null) {
tagMap.put(tag, itemId);
}
}
}
return tagMap;
}
protected void put(ResourceLocation tag, ResourceLocation item) {
tagsToItems.computeIfAbsent(tag, k -> new HashSet<>()).add(item);
itemsToTags.computeIfAbsent(item, k -> new HashSet<>()).add(tag);
}
public Collection<ResourceLocation> getItems(ResourceLocation tag) {
return Collections.unmodifiableSet(tagsToItems.getOrDefault(tag, Collections.emptySet()));
}
public Collection<ResourceLocation> getTags(ResourceLocation items) {
return Collections.unmodifiableSet(itemsToTags.getOrDefault(items, Collections.emptySet()));
}
}

View file

@ -2,7 +2,7 @@ package com.almostreliable.unified.api;
import javax.annotation.Nullable;
public interface ReplacementLookupHelper {
public interface RecipeTransformContext {
@Nullable
String findReplacement(String id);

View file

@ -7,5 +7,5 @@ import javax.annotation.Nullable;
@FunctionalInterface
public interface RecipeTransformer {
@Nullable
JsonElement transformRecipe(JsonElement json, ReplacementLookupHelper helper);
JsonElement transformRecipe(JsonElement json, RecipeTransformContext context);
}

View file

@ -1,7 +1,7 @@
package com.almostreliable.unified.transformer;
import com.almostreliable.unified.api.RecipeTransformer;
import com.almostreliable.unified.api.ReplacementLookupHelper;
import com.almostreliable.unified.api.RecipeTransformContext;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@ -9,28 +9,26 @@ import com.google.gson.JsonObject;
import javax.annotation.Nullable;
public class GenericRecipeTransformer implements RecipeTransformer {
protected void replaceItems(JsonElement element, ReplacementLookupHelper lookup) {
protected void replaceItems(JsonElement element, RecipeTransformContext context) {
if (element instanceof JsonObject asObject) {
if (asObject.has("item")) {
String newItem = lookup.findReplacement(asObject.get("item").getAsString());
String newItem = context.findReplacement(asObject.get("item").getAsString());
if (newItem != null) {
asObject.addProperty("item", newItem);
}
}
} else if (element instanceof JsonArray asArray) {
for (JsonElement innerElement : asArray) {
replaceItems(innerElement, lookup);
replaceItems(innerElement, context);
}
}
}
@Nullable
@Override
public JsonElement transformRecipe(JsonElement json, ReplacementLookupHelper helper) {
public JsonElement transformRecipe(JsonElement json, RecipeTransformContext context) {
// TODO refactor
replaceItems(json, helper);
replaceItems(json, context);
return json;
}
}