[Change] Stricter Generics for RecipeManager
This commit is contained in:
parent
1628ac9a86
commit
9f75cbde1b
4 changed files with 49 additions and 36 deletions
|
@ -1,6 +1,7 @@
|
||||||
package org.betterx.bclib.mixin.common;
|
package org.betterx.bclib.mixin.common;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.Container;
|
||||||
import net.minecraft.world.item.crafting.Recipe;
|
import net.minecraft.world.item.crafting.Recipe;
|
||||||
import net.minecraft.world.item.crafting.RecipeManager;
|
import net.minecraft.world.item.crafting.RecipeManager;
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
|
@ -13,14 +14,14 @@ import java.util.Map;
|
||||||
@Mixin(RecipeManager.class)
|
@Mixin(RecipeManager.class)
|
||||||
public interface RecipeManagerAccessor {
|
public interface RecipeManagerAccessor {
|
||||||
@Accessor("recipes")
|
@Accessor("recipes")
|
||||||
Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> bclib_getRecipes();
|
<C extends Container, T extends Recipe<C>> Map<RecipeType<T>, Map<ResourceLocation, T>> bclib_getRecipes();
|
||||||
|
|
||||||
@Accessor("recipes")
|
@Accessor("recipes")
|
||||||
void bclib_setRecipes(Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes);
|
<C extends Container, T extends Recipe<C>> void bclib_setRecipes(Map<RecipeType<T>, Map<ResourceLocation, T>> recipes);
|
||||||
|
|
||||||
@Accessor("byName")
|
@Accessor("byName")
|
||||||
Map<ResourceLocation, Recipe<?>> bclib_getRecipesByName();
|
<C extends Container, T extends Recipe<C>> Map<ResourceLocation, T> bclib_getRecipesByName();
|
||||||
|
|
||||||
@Accessor("byName")
|
@Accessor("byName")
|
||||||
void bclib_setRecipesByName(Map<ResourceLocation, Recipe<?>> recipes);
|
<C extends Container, T extends Recipe<C>> void bclib_setRecipesByName(Map<ResourceLocation, T> recipes);
|
||||||
}
|
}
|
|
@ -21,9 +21,7 @@ import java.util.Optional;
|
||||||
@Mixin(RecipeManager.class)
|
@Mixin(RecipeManager.class)
|
||||||
public abstract class RecipeManagerMixin {
|
public abstract class RecipeManagerMixin {
|
||||||
@Shadow
|
@Shadow
|
||||||
private <C extends Container, T extends Recipe<C>> Map<ResourceLocation, Recipe<C>> byType(RecipeType<T> type) {
|
protected abstract <C extends Container, T extends Recipe<C>> Map<ResourceLocation, T> byType(RecipeType<T> recipeType);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "getRecipeFor", at = @At(value = "HEAD"), cancellable = true)
|
@Inject(method = "getRecipeFor", at = @At(value = "HEAD"), cancellable = true)
|
||||||
private <C extends Container, T extends Recipe<C>> void bclib_getRecipeFor(
|
private <C extends Container, T extends Recipe<C>> void bclib_getRecipeFor(
|
||||||
|
|
|
@ -12,7 +12,6 @@ import net.minecraft.world.level.ItemLike;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -20,53 +19,65 @@ import java.util.Map.Entry;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class BCLRecipeManager {
|
public class BCLRecipeManager {
|
||||||
private static final Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> RECIPES = Maps.newHashMap();
|
private static final Map<?, ? extends Map<?, ?>> _RECIPES = Maps.newHashMap();
|
||||||
private static final Map<RecipeType<?>, Object> SORTED = Maps.newHashMap();
|
private static final Map<?, ? extends List<?>> _SORTED = Maps.newHashMap();
|
||||||
private static final String MINECRAFT = "minecraft";
|
private static final String MINECRAFT = "minecraft";
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <C extends Container, T extends Recipe<C>> Map<RecipeType<T>, Map<ResourceLocation, T>> RECIPES() {
|
||||||
|
return (Map<RecipeType<T>, Map<ResourceLocation, T>>) _RECIPES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <C extends Container, T extends Recipe<C>> Map<RecipeType<T>, List<T>> SORTED() {
|
||||||
|
return (Map<RecipeType<T>, List<T>>) _SORTED;
|
||||||
|
}
|
||||||
|
|
||||||
public static <C extends Container, T extends Recipe<C>> Optional<T> getSortedRecipe(
|
public static <C extends Container, T extends Recipe<C>> Optional<T> getSortedRecipe(
|
||||||
RecipeType<T> type,
|
RecipeType<T> type,
|
||||||
C inventory,
|
C inventory,
|
||||||
Level level,
|
Level level,
|
||||||
Function<RecipeType<T>, Map<ResourceLocation, Recipe<C>>> getter
|
Function<RecipeType<T>, Map<ResourceLocation, T>> getter
|
||||||
) {
|
) {
|
||||||
List<Recipe<C>> recipes = (List<Recipe<C>>) SORTED.computeIfAbsent(type, t -> {
|
List<T> recipes = BCLRecipeManager.<C, T>SORTED().computeIfAbsent(type, t -> {
|
||||||
Collection<Recipe<C>> values = getter.apply(type).values();
|
Collection<T> values = getter.apply(type).values();
|
||||||
List<Recipe<C>> list = new ArrayList<>(values);
|
List<T> list = new ArrayList<>(values);
|
||||||
list.sort((v1, v2) -> {
|
list.sort((v1, v2) -> {
|
||||||
boolean b1 = v1.getId().getNamespace().equals(MINECRAFT);
|
boolean b1 = v1.getId().getNamespace().equals(MINECRAFT);
|
||||||
boolean b2 = v2.getId().getNamespace().equals(MINECRAFT);
|
boolean b2 = v2.getId().getNamespace().equals(MINECRAFT);
|
||||||
return b1 ^ b2 ? (b1 ? 1 : -1) : v1.getId().compareTo(v2.getId());
|
return b1 ^ b2 ? (b1 ? 1 : -1) : v1.getId().compareTo(v2.getId());
|
||||||
});
|
});
|
||||||
return ImmutableList.copyOf(list);
|
return list;
|
||||||
});
|
});
|
||||||
return (Optional<T>) recipes.stream().filter(recipe -> recipe.matches(inventory, level)).findFirst();
|
return recipes.stream().filter(recipe -> recipe.matches(inventory, level)).findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void addRecipe(RecipeType<?> type, Recipe<?> recipe) {
|
public static <C extends Container, T extends Recipe<C>> void addRecipe(RecipeType<T> type, T recipe) {
|
||||||
Map<ResourceLocation, Recipe<?>> list = RECIPES.computeIfAbsent(type, i -> Maps.newHashMap());
|
Map<ResourceLocation, T> list = BCLRecipeManager.<C, T>RECIPES().computeIfAbsent(type, i -> Maps.newHashMap());
|
||||||
list.put(recipe.getId(), recipe);
|
list.put(recipe.getId(), recipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Recipe<?>> T getRecipe(RecipeType<T> type, ResourceLocation id) {
|
public static <C extends Container, T extends Recipe<C>> T getRecipe(RecipeType<T> type, ResourceLocation id) {
|
||||||
Map<ResourceLocation, Recipe<?>> map = RECIPES.get(type);
|
Map<ResourceLocation, T> map = BCLRecipeManager.<C, T>RECIPES().get(type);
|
||||||
return map != null ? (T) map.get(id) : null;
|
return map != null ? map.get(id) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> getMap(Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes) {
|
public static <C extends Container, T extends Recipe<C>> Map<RecipeType<T>, Map<ResourceLocation, T>> getMap(
|
||||||
Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> result = Maps.newHashMap();
|
Map<RecipeType<T>, Map<ResourceLocation, T>> recipes
|
||||||
|
) {
|
||||||
|
Map<RecipeType<T>, Map<ResourceLocation, T>> result = Maps.newHashMap();
|
||||||
|
|
||||||
for (RecipeType<?> type : recipes.keySet()) {
|
for (RecipeType<T> type : recipes.keySet()) {
|
||||||
Map<ResourceLocation, Recipe<?>> typeList = Maps.newHashMap();
|
Map<ResourceLocation, T> typeList = Maps.newHashMap();
|
||||||
typeList.putAll(recipes.get(type));
|
typeList.putAll(recipes.get(type));
|
||||||
result.put(type, typeList);
|
result.put(type, typeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
SORTED.clear();
|
SORTED().clear();
|
||||||
RECIPES.forEach((type, list) -> {
|
BCLRecipeManager.<C, T>RECIPES().forEach((type, list) -> {
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
Map<ResourceLocation, Recipe<?>> typeList = result.computeIfAbsent(type, i -> Maps.newHashMap());
|
Map<ResourceLocation, T> typeList = result.computeIfAbsent(type, i -> Maps.newHashMap());
|
||||||
for (Entry<ResourceLocation, Recipe<?>> entry : list.entrySet()) {
|
for (Entry<ResourceLocation, T> entry : list.entrySet()) {
|
||||||
ResourceLocation id = entry.getKey();
|
ResourceLocation id = entry.getKey();
|
||||||
typeList.computeIfAbsent(id, i -> entry.getValue());
|
typeList.computeIfAbsent(id, i -> entry.getValue());
|
||||||
}
|
}
|
||||||
|
@ -76,14 +87,17 @@ public class BCLRecipeManager {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<ResourceLocation, Recipe<?>> getMapByName(Map<ResourceLocation, Recipe<?>> recipes) {
|
public static <C extends Container, T extends Recipe<C>> Map<ResourceLocation, T> getMapByName(Map<ResourceLocation, T> recipes) {
|
||||||
Map<ResourceLocation, Recipe<?>> result = CollectionsUtil.getMutable(recipes);
|
Map<ResourceLocation, T> result = CollectionsUtil.getMutable(recipes);
|
||||||
RECIPES.values()
|
BCLRecipeManager.<C, T>RECIPES().values()
|
||||||
.forEach(map -> map.forEach((location, recipe) -> result.computeIfAbsent(location, i -> recipe)));
|
.forEach(map -> map.forEach((location, recipe) -> result.computeIfAbsent(
|
||||||
|
location,
|
||||||
|
i -> recipe
|
||||||
|
)));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <S extends RecipeSerializer<T>, T extends Recipe<?>> S registerSerializer(
|
public static <C extends Container, S extends RecipeSerializer<T>, T extends Recipe<C>> S registerSerializer(
|
||||||
String modID,
|
String modID,
|
||||||
String id,
|
String id,
|
||||||
S serializer
|
S serializer
|
||||||
|
@ -91,7 +105,7 @@ public class BCLRecipeManager {
|
||||||
return Registry.register(Registry.RECIPE_SERIALIZER, modID + ":" + id, serializer);
|
return Registry.register(Registry.RECIPE_SERIALIZER, modID + ":" + id, serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Recipe<?>> RecipeType<T> registerType(String modID, String type) {
|
public static <C extends Container, T extends Recipe<C>> RecipeType<T> registerType(String modID, String type) {
|
||||||
ResourceLocation recipeTypeId = new ResourceLocation(modID, type);
|
ResourceLocation recipeTypeId = new ResourceLocation(modID, type);
|
||||||
return Registry.register(Registry.RECIPE_TYPE, recipeTypeId, new RecipeType<T>() {
|
return Registry.register(Registry.RECIPE_TYPE, recipeTypeId, new RecipeType<T>() {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -22,7 +22,7 @@ public class GridRecipe {
|
||||||
private ItemLike output;
|
private ItemLike output;
|
||||||
|
|
||||||
private String group;
|
private String group;
|
||||||
private RecipeType<?> type;
|
private RecipeType<CraftingRecipe> type;
|
||||||
private boolean shaped;
|
private boolean shaped;
|
||||||
private String[] shape;
|
private String[] shape;
|
||||||
private final Map<Character, Ingredient> materialKeys = Maps.newHashMap();
|
private final Map<Character, Ingredient> materialKeys = Maps.newHashMap();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue