Better Singleton implementation of RecipeRegistry, and fix up the getStacksInRange to be more flexible about bounds

This commit is contained in:
Pahimar 2016-05-20 13:56:53 -04:00
parent 10cde0e830
commit 5f570fc576
6 changed files with 83 additions and 59 deletions

View file

@ -141,7 +141,7 @@ public class EquivalentExchange3
public RecipeRegistry getRecipeRegistry()
{
return RecipeRegistry.getInstance();
return RecipeRegistry.INSTANCE;
}
public AludelRecipeManager getAludelRecipeManager()

View file

@ -3,6 +3,7 @@ package com.pahimar.ee3.api.exchange;
import com.pahimar.ee3.EquivalentExchange3;
import cpw.mods.fml.common.Mod;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -66,7 +67,7 @@ public final class EnergyValueRegistryProxy {
init();
if (ee3Mod != null) {
return EE3Wrapper.ee3mod.getEnergyValueRegistry().getStacksInRange(start, finish);
return new ArrayList<>(EE3Wrapper.ee3mod.getEnergyValueRegistry().getStacksInRange(start, finish));
}
return Collections.EMPTY_LIST;

View file

@ -7,6 +7,8 @@ import com.pahimar.ee3.api.exchange.EnergyValue;
import com.pahimar.ee3.api.exchange.IEnergyValueProvider;
import com.pahimar.ee3.handler.ConfigurationHandler;
import com.pahimar.ee3.recipe.RecipeRegistry;
import com.pahimar.ee3.reference.Comparators;
import com.pahimar.ee3.util.FilterUtils;
import com.pahimar.ee3.util.LoaderHelper;
import com.pahimar.ee3.util.LogHelper;
import com.pahimar.ee3.util.SerializationHelper;
@ -15,7 +17,6 @@ import cpw.mods.fml.common.Loader;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.oredict.OreDictionary;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
@ -31,7 +32,7 @@ public class EnergyValueRegistry {
public static final EnergyValueRegistry INSTANCE = new EnergyValueRegistry();
private ImmutableSortedMap<WrappedStack, EnergyValue> stackValueMap;
private ImmutableSortedMap<EnergyValue, List<WrappedStack>> valueStackMap;
private ImmutableSortedMap<EnergyValue, Set<WrappedStack>> valueStackMap;
private final Map<WrappedStack, EnergyValue> preCalculationStackValueMap;
private final Map<WrappedStack, EnergyValue> postCalculationStackValueMap;
@ -94,7 +95,7 @@ public class EnergyValueRegistry {
* assignments) query or not
* @return an {@link EnergyValue} if there is one to be found for the provided {@link Object} in the provided Map, null otherwise
*/
private static EnergyValue getEnergyValue(Map<WrappedStack, EnergyValue> valueMap, Object object, boolean strict) {
public static EnergyValue getEnergyValue(Map<WrappedStack, EnergyValue> valueMap, Object object, boolean strict) {
if (WrappedStack.canBeWrapped(object)) {
@ -401,58 +402,69 @@ public class EnergyValueRegistry {
* @param finish
* @return
*/
public List getStacksInRange(Number start, Number finish) {
public Set<ItemStack> getStacksInRange(Number start, Number finish) {
return getStacksInRange(new EnergyValue(start), new EnergyValue(finish));
}
/**
* TODO Finish JavaDoc
*
* @param start
* @param finish
* @param lowerBound
* @param upperBound
* @return
*/
public List getStacksInRange(EnergyValue start, EnergyValue finish) {
public Set<ItemStack> getStacksInRange(EnergyValue lowerBound, EnergyValue upperBound) {
List stacksInRange = new ArrayList<WrappedStack>();
Set<ItemStack> filteredItemStacks = new TreeSet<>(Comparators.ENERGY_VALUE_ITEM_STACK_COMPARATOR);
if (valueStackMap != null) {
Set<ItemStack> greaterThanLowerBound = getStacksInRange(getEnergyValues(), lowerBound, false);
Set<ItemStack> lesserThanUpperBound = getStacksInRange(getEnergyValues(), upperBound, true);
SortedMap<EnergyValue, List<WrappedStack>> tailMap = valueStackMap.tailMap(start);
SortedMap<EnergyValue, List<WrappedStack>> headMap = valueStackMap.headMap(finish);
if (!greaterThanLowerBound.isEmpty() && !lesserThanUpperBound.isEmpty()) {
SortedMap<EnergyValue, List<WrappedStack>> smallerMap;
SortedMap<EnergyValue, List<WrappedStack>> biggerMap;
for (ItemStack itemStack : greaterThanLowerBound) {
if (lesserThanUpperBound.contains(itemStack)) {
filteredItemStacks.add(itemStack);
}
}
}
else if (!greaterThanLowerBound.isEmpty()) {
return greaterThanLowerBound;
}
else if (!lesserThanUpperBound.isEmpty()) {
return lesserThanUpperBound;
}
if (!tailMap.isEmpty() && !headMap.isEmpty()) {
return filteredItemStacks;
}
if (tailMap.size() <= headMap.size()) {
smallerMap = tailMap;
biggerMap = headMap;
/**
* TODO Finish JavaDoc
*
* @param valueMap
* @param energyValueBound
* @param isUpperBound
* @return
*/
private static Set<ItemStack> getStacksInRange(Map<WrappedStack, EnergyValue> valueMap, EnergyValue energyValueBound, boolean isUpperBound) {
Set itemStacks = FilterUtils.filterForItemStacks(valueMap.keySet());
if (valueMap != null) {
if (energyValueBound != null) {
if (isUpperBound) {
return FilterUtils.filterByEnergyValue(valueMap, itemStacks, energyValueBound, FilterUtils.ValueFilterType.VALUE_LOWER_THAN_BOUND, Comparators.ENERGY_VALUE_ITEM_STACK_COMPARATOR);
}
else {
smallerMap = headMap;
biggerMap = tailMap;
}
for (EnergyValue value : smallerMap.keySet()) {
if (biggerMap.containsKey(value)) {
for (WrappedStack wrappedStack : valueStackMap.get(value)) {
if (wrappedStack.getWrappedObject() instanceof ItemStack || wrappedStack.getWrappedObject() instanceof FluidStack) {
stacksInRange.add(wrappedStack.getWrappedObject());
}
else if (wrappedStack.getWrappedObject() instanceof OreStack) {
stacksInRange.addAll(OreDictionary.getOres(((OreStack) wrappedStack.getWrappedObject()).oreName));
}
}
}
return FilterUtils.filterByEnergyValue(valueMap, itemStacks, energyValueBound, FilterUtils.ValueFilterType.VALUE_GREATER_THAN_BOUND, Comparators.ENERGY_VALUE_ITEM_STACK_COMPARATOR);
}
}
}
return stacksInRange;
return new TreeSet<>(Collections.EMPTY_SET);
}
/**
* Sets an {@link EnergyValue} for the provided {@link Object} (if it can be wrapped in a {@link WrappedStack}.
* Depending on whether or not this is a pre-calculation value assignment it's also possible for the calculated
@ -565,11 +577,11 @@ public class EnergyValueRegistry {
computedMap.putAll(tempComputedMap);
tempComputedMap = new TreeMap<>(computedMap);
for (WrappedStack recipeOutput : RecipeRegistry.getInstance().getRecipeMappings().keySet()) {
for (WrappedStack recipeOutput : RecipeRegistry.INSTANCE.getRecipeMappings().keySet()) {
// We won't attempt to recalculate values that already have a pre-calculation value assignment
if (!stackValueMap.containsKey(WrappedStack.wrap(recipeOutput, 1))) {
for (Set<WrappedStack> recipeInputs : RecipeRegistry.getInstance().getRecipeMappings().get(recipeOutput)) {
for (Set<WrappedStack> recipeInputs : RecipeRegistry.INSTANCE.getRecipeMappings().get(recipeOutput)) {
EnergyValue currentOutputValue = getEnergyValue(tempComputedMap, WrappedStack.wrap(recipeOutput, 1), false);
EnergyValue computedOutputValue = computeFromInputs(tempComputedMap, recipeOutput, recipeInputs);
@ -604,7 +616,7 @@ public class EnergyValueRegistry {
private void calculateValueStackMap() {
SortedMap<EnergyValue, List<WrappedStack>> tempValueMap = new TreeMap<>();
SortedMap<EnergyValue, Set<WrappedStack>> tempValueMap = new TreeMap<>();
for (WrappedStack wrappedStack : getEnergyValues().keySet()) {
@ -619,7 +631,7 @@ public class EnergyValueRegistry {
}
}
else {
tempValueMap.put(energyValue, new ArrayList<>(Arrays.asList(wrappedStack)));
tempValueMap.put(energyValue, new TreeSet<>(Arrays.asList(wrappedStack)));
}
}
}

View file

@ -18,7 +18,7 @@ public class WorldEventHandler {
if (!hasInitilialized && FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) {
RecipeRegistry.getInstance().registerVanillaRecipes();
RecipeRegistry.INSTANCE.registerVanillaRecipes();
AludelRecipeManager.registerRecipes();
long startTime = System.nanoTime();

View file

@ -18,7 +18,7 @@ import java.util.TreeSet;
public class RecipeRegistry {
public static final Marker RECIPE_MARKER = MarkerManager.getMarker("EE3_RECIPE", LogHelper.MOD_MARKER);
private static RecipeRegistry recipeRegistry = null;
public static final RecipeRegistry INSTANCE = new RecipeRegistry();
private Multimap<WrappedStack, Set<WrappedStack>> recipeMap;
private ImmutableMultimap<WrappedStack, Set<WrappedStack>> immutableRecipeMap;
@ -27,15 +27,6 @@ public class RecipeRegistry {
recipeMap = TreeMultimap.create(WrappedStack.COMPARATOR, Comparators.WRAPPED_STACK_SET_COMPARATOR);
}
public static RecipeRegistry getInstance() {
if (recipeRegistry == null) {
recipeRegistry = new RecipeRegistry();
}
return recipeRegistry;
}
public void addRecipe(Object recipeOutput, Collection<?> recipeInputList) {
// Wrap the recipe output
@ -86,7 +77,7 @@ public class RecipeRegistry {
public Multimap<WrappedStack, Set<WrappedStack>> getRecipeMappings() {
if (immutableRecipeMap == null) {
immutableRecipeMap = ImmutableMultimap.copyOf(recipeRegistry.recipeMap);
immutableRecipeMap = ImmutableMultimap.copyOf(INSTANCE.recipeMap);
}
return immutableRecipeMap;

View file

@ -1,17 +1,33 @@
package com.pahimar.ee3.util;
import com.pahimar.ee3.api.exchange.EnergyValue;
import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy;
import com.pahimar.ee3.exchange.EnergyValueRegistry;
import com.pahimar.ee3.exchange.OreStack;
import com.pahimar.ee3.exchange.WrappedStack;
import com.pahimar.ee3.reference.Comparators;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import java.util.Collection;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
public class FilterUtils {
public static Set<ItemStack> filterForItemStacks(Set<WrappedStack> wrappedStacks) {
Set<ItemStack> itemStacks = new TreeSet<>(Comparators.ID_COMPARATOR);
for (WrappedStack wrappedStack : wrappedStacks) {
if (wrappedStack.getWrappedObject() instanceof ItemStack) {
itemStacks.add((ItemStack) wrappedStack.getWrappedObject());
}
else if (wrappedStack.getWrappedObject() instanceof OreStack) {
itemStacks.addAll(OreDictionary.getOres(((OreStack) wrappedStack.getWrappedObject()).oreName));
}
}
return itemStacks;
}
public static Set<ItemStack> filterByDisplayName(Set<ItemStack> itemStacks, String filterString) {
return filterByDisplayName(itemStacks, filterString, NameFilterType.STARTS_WITH, null);
}
@ -62,10 +78,14 @@ public class FilterUtils {
}
public static Set<ItemStack> filterByEnergyValue(Collection<ItemStack> itemStacks, Number valueBound, ValueFilterType filterType, Comparator comparator) {
return filterByEnergyValue(itemStacks, new EnergyValue(valueBound.floatValue()), filterType, comparator);
return filterByEnergyValue(EnergyValueRegistry.INSTANCE.getEnergyValues(), itemStacks, new EnergyValue(valueBound.floatValue()), filterType, comparator);
}
public static Set<ItemStack> filterByEnergyValue(Collection<ItemStack> itemStacks, EnergyValue valueBound, ValueFilterType filterType, Comparator comparator) {
return filterByEnergyValue(EnergyValueRegistry.INSTANCE.getEnergyValues(), itemStacks, valueBound, filterType, comparator);
}
public static Set<ItemStack> filterByEnergyValue(Map<WrappedStack, EnergyValue> valueMap, Collection<ItemStack> itemStacks, EnergyValue valueBound, ValueFilterType filterType, Comparator comparator) {
Set<ItemStack> filteredSet = (comparator != null ? new TreeSet<>(comparator) : new TreeSet<>(Comparators.DISPLAY_NAME_COMPARATOR));
@ -77,9 +97,9 @@ public class FilterUtils {
else {
for (ItemStack itemStack : itemStacks) {
EnergyValue energyValue = EnergyValueRegistryProxy.getEnergyValue(itemStack);
EnergyValue energyValue = EnergyValueRegistry.INSTANCE.getEnergyValue(valueMap, itemStack, false);
if (energyValue != null) {
if (energyValue != null && Float.compare(energyValue.getValue(), 0) > 0) {
if (filterType == ValueFilterType.VALUE_LOWER_THAN_BOUND && energyValue.compareTo(valueBound) <= 0) {
filteredSet.add(itemStack);
}