Skip to content

Commit

Permalink
Use simpler Table and MultiMap instead of Guava's
Browse files Browse the repository at this point in the history
  • Loading branch information
mezz committed Oct 21, 2017
1 parent da91b3f commit 48c6e11
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 134 deletions.
20 changes: 20 additions & 0 deletions src/main/java/mezz/jei/collect/ListMultiMap.java
@@ -0,0 +1,20 @@
package mezz.jei.collect;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

public class ListMultiMap<K, V> extends MultiMap<K, V, List<V>> {
public ListMultiMap() {
this(ArrayList::new);
}

public ListMultiMap(Supplier<List<V>> collectionSupplier) {
super(collectionSupplier);
}

public ListMultiMap(Map<K, List<V>> map, Supplier<List<V>> collectionSupplier) {
super(map, collectionSupplier);
}
}
59 changes: 59 additions & 0 deletions src/main/java/mezz/jei/collect/MultiMap.java
@@ -0,0 +1,59 @@
package mezz.jei.collect;

import com.google.common.collect.ImmutableMultimap;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Supplier;

public class MultiMap<K, V, T extends Collection<V>> {
protected final Map<K, T> map;
private final Function<K, T> collectionMappingFunction;

public MultiMap(Supplier<T> collectionSupplier) {
this(new HashMap<>(), collectionSupplier);
}

public MultiMap(Map<K, T> map, Supplier<T> collectionSupplier) {
this.map = map;
this.collectionMappingFunction = (k -> collectionSupplier.get());
}

public T get(K key) {
return map.computeIfAbsent(key, collectionMappingFunction);
}

public boolean put(K key, V value) {
return get(key).add(value);
}

public boolean contains(K key, V value) {
return get(key).contains(value);
}

public Set<Map.Entry<K, T>> entrySet() {
return map.entrySet();
}

public int getTotalSize() {
int size = 0;
for (T value : map.values()) {
size += value.size();
}
return size;
}

public ImmutableMultimap<K, V> toImmutable() {
ImmutableMultimap.Builder<K, V> builder = ImmutableMultimap.builder();
for (Map.Entry<K, T> entry : map.entrySet()) {
K key = entry.getKey();
for (V value : entry.getValue()) {
builder.put(key, value);
}
}
return builder.build();
}
}
20 changes: 20 additions & 0 deletions src/main/java/mezz/jei/collect/SetMultiMap.java
@@ -0,0 +1,20 @@
package mezz.jei.collect;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;

public class SetMultiMap<K, V> extends MultiMap<K, V, Set<V>> {
public SetMultiMap() {
this(HashSet::new);
}

public SetMultiMap(Supplier<Set<V>> collectionSupplier) {
super(collectionSupplier);
}

public SetMultiMap(Map<K, Set<V>> map, Supplier<Set<V>> collectionSupplier) {
super(map, collectionSupplier);
}
}
57 changes: 57 additions & 0 deletions src/main/java/mezz/jei/collect/Table.java
@@ -0,0 +1,57 @@
package mezz.jei.collect;

import com.google.common.collect.ImmutableTable;

import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;

public class Table<R, C, V> {
public static <R, C, V> Table<R, C, V> hashBasedTable() {
return new Table<>(new HashMap<>(), HashMap::new);
}

private final Map<R, Map<C, V>> table;
private final Function<R, Map<C, V>> rowMappingFunction;

public Table(Map<R, Map<C, V>> table, Supplier<Map<C, V>> rowSupplier) {
this.table = table;
this.rowMappingFunction = (k -> rowSupplier.get());
}

@Nullable
public V get(R row, C col) {
Map<C, V> rowMap = getRow(row);
return rowMap.get(col);
}

public V computeIfAbsent(R row, C col, Supplier<V> valueSupplier) {
Map<C, V> rowMap = getRow(row);
return rowMap.computeIfAbsent(col, k -> valueSupplier.get());
}

@Nullable
public V put(R row, C col, V val) {
Map<C, V> rowMap = getRow(row);
return rowMap.put(col, val);
}

public Map<C, V> getRow(R row) {
return table.computeIfAbsent(row, rowMappingFunction);
}

public ImmutableTable<R, C, V> toImmutable() {
ImmutableTable.Builder<R, C, V> builder = ImmutableTable.builder();
for (Map.Entry<R, Map<C, V>> entry : table.entrySet()) {
R row = entry.getKey();
for (Map.Entry<C, V> rowEntry : entry.getValue().entrySet()) {
C col = rowEntry.getKey();
V val = rowEntry.getValue();
builder.put(row, col, val);
}
}
return builder.build();
}
}
@@ -1,25 +1,24 @@
package mezz.jei.plugins.vanilla.brewing;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import mezz.jei.Internal;
import mezz.jei.collect.SetMultiMap;
import net.minecraft.init.Items;
import net.minecraft.init.PotionTypes;
import net.minecraft.item.ItemStack;
import net.minecraft.potion.PotionUtils;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class BrewingRecipeUtil {
public static final ItemStack POTION = new ItemStack(Items.POTIONITEM);
public static final ItemStack WATER_BOTTLE = PotionUtils.addPotionToItemStack(POTION.copy(), PotionTypes.WATER);

private final Map<String, Integer> brewingStepCache = new HashMap<>(); // output potion -> brewing steps
private final Multimap<String, String> potionMap = HashMultimap.create(); // output potion -> input potions
private final SetMultiMap<String, String> potionMap = new SetMultiMap<>(); // output potion -> input potions

public BrewingRecipeUtil() {
clearCache();
Expand Down
16 changes: 8 additions & 8 deletions src/main/java/mezz/jei/recipes/InternalRecipeRegistryPlugin.java
@@ -1,34 +1,34 @@
package mezz.jei.recipes;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ListMultimap;
import mezz.jei.api.ingredients.IIngredientHelper;
import mezz.jei.api.ingredients.IIngredientRegistry;
import mezz.jei.api.recipe.IFocus;
import mezz.jei.api.recipe.IRecipeCategory;
import mezz.jei.api.recipe.IRecipeRegistryPlugin;
import mezz.jei.api.recipe.IRecipeWrapper;
import mezz.jei.collect.ListMultiMap;
import mezz.jei.gui.Focus;
import mezz.jei.ingredients.IngredientUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class InternalRecipeRegistryPlugin implements IRecipeRegistryPlugin {
private final RecipeRegistry recipeRegistry;
private final ImmutableMultimap<String, String> categoriesForRecipeCatalystKeys;
private final IIngredientRegistry ingredientRegistry;
private final ImmutableMap<String, IRecipeCategory> recipeCategoriesMap;
private final RecipeMap recipeInputMap;
private final RecipeMap recipeOutputMap;
private final ListMultimap<IRecipeCategory, IRecipeWrapper> recipeWrappersForCategories;
private final ListMultiMap<IRecipeCategory, IRecipeWrapper> recipeWrappersForCategories;

public InternalRecipeRegistryPlugin(RecipeRegistry recipeRegistry, ImmutableMultimap<String, String> categoriesForRecipeCatalystKeys, IIngredientRegistry ingredientRegistry, ImmutableMap<String, IRecipeCategory> recipeCategoriesMap, RecipeMap recipeInputMap, RecipeMap recipeOutputMap, ListMultimap<IRecipeCategory, IRecipeWrapper> recipeWrappersForCategories) {
public InternalRecipeRegistryPlugin(RecipeRegistry recipeRegistry, ImmutableMultimap<String, String> categoriesForRecipeCatalystKeys, IIngredientRegistry ingredientRegistry, ImmutableMap<String, IRecipeCategory> recipeCategoriesMap, RecipeMap recipeInputMap, RecipeMap recipeOutputMap, ListMultiMap<IRecipeCategory, IRecipeWrapper> recipeWrappersForCategories) {
this.recipeRegistry = recipeRegistry;
this.categoriesForRecipeCatalystKeys = categoriesForRecipeCatalystKeys;
this.ingredientRegistry = ingredientRegistry;
Expand Down
33 changes: 16 additions & 17 deletions src/main/java/mezz/jei/recipes/RecipeMap.java
@@ -1,28 +1,27 @@
package mezz.jei.recipes;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.common.collect.Table;
import mezz.jei.api.ingredients.IIngredientHelper;
import mezz.jei.api.ingredients.IIngredientRegistry;
import mezz.jei.api.recipe.IRecipeCategory;
import mezz.jei.api.recipe.IRecipeWrapper;
import mezz.jei.collect.ListMultiMap;
import mezz.jei.collect.Table;
import mezz.jei.ingredients.IngredientUtil;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* A RecipeMap efficiently links IRecipeWrappers, IRecipeCategory, and Ingredients.
*/
public class RecipeMap {
private final Table<IRecipeCategory, String, List<IRecipeWrapper>> recipeWrapperTable = HashBasedTable.create();
private final ArrayListMultimap<String, String> categoryUidMap = ArrayListMultimap.create();
private final Table<IRecipeCategory, String, List<IRecipeWrapper>> recipeWrapperTable = Table.hashBasedTable();
private final ListMultiMap<String, String> categoryUidMap = new ListMultiMap<>();
private final Ordering<String> recipeCategoryOrdering;
private final IIngredientRegistry ingredientRegistry;

Expand Down Expand Up @@ -57,12 +56,12 @@ public <V> void addRecipeCategory(IRecipeCategory recipeCategory, V ingredient)
public <T extends IRecipeWrapper, V> ImmutableList<T> getRecipeWrappers(IRecipeCategory<T> recipeCategory, V ingredient) {
IIngredientHelper<V> ingredientHelper = ingredientRegistry.getIngredientHelper(ingredient);

//noinspection unchecked
Map<String, List<T>> recipesForType = (Map<String, List<T>>) (Object) recipeWrapperTable.row(recipeCategory);
Map<String, List<IRecipeWrapper>> recipesForType = recipeWrapperTable.getRow(recipeCategory);

ImmutableList.Builder<T> listBuilder = ImmutableList.builder();
for (String key : IngredientUtil.getUniqueIdsWithWildcard(ingredientHelper, ingredient)) {
List<T> recipes = recipesForType.get(key);
@SuppressWarnings("unchecked")
List<T> recipes = (List<T>) recipesForType.get(key);
if (recipes != null) {
listBuilder.addAll(recipes);
}
Expand All @@ -81,8 +80,7 @@ public <T extends IRecipeWrapper> void addRecipe(T recipeWrapper, IRecipeCategor
private <T extends IRecipeWrapper, V> void addRecipe(T recipeWrapper, IRecipeCategory<T> recipeCategory, Class<V> ingredientClass, List<V> ingredients) {
IIngredientHelper<V> ingredientHelper = ingredientRegistry.getIngredientHelper(ingredientClass);

//noinspection unchecked
Map<String, List<T>> recipesWrappersForType = (Map<String, List<T>>) (Object) recipeWrapperTable.row(recipeCategory);
Map<String, List<IRecipeWrapper>> recipesWrappersForType = recipeWrapperTable.getRow(recipeCategory);

Set<String> uniqueIds = new HashSet<>();

Expand All @@ -100,7 +98,8 @@ private <T extends IRecipeWrapper, V> void addRecipe(T recipeWrapper, IRecipeCat
uniqueIds.add(key);
}

List<T> recipeWrappers = recipesWrappersForType.computeIfAbsent(key, k -> Lists.newArrayList());
@SuppressWarnings("unchecked")
List<T> recipeWrappers = (List<T>) recipesWrappersForType.computeIfAbsent(key, k -> new ArrayList<>());

recipeWrappers.add(recipeWrapper);

Expand Down

0 comments on commit 48c6e11

Please sign in to comment.