diff --git a/src/main/java/com/pahimar/ee3/EquivalentExchange3.java b/src/main/java/com/pahimar/ee3/EquivalentExchange3.java index bd2acaed..7e4360d3 100644 --- a/src/main/java/com/pahimar/ee3/EquivalentExchange3.java +++ b/src/main/java/com/pahimar/ee3/EquivalentExchange3.java @@ -2,9 +2,7 @@ package com.pahimar.ee3; import com.pahimar.ee3.array.AlchemyArrayRegistry; import com.pahimar.ee3.command.CommandEE; -import com.pahimar.ee3.exchange.CachedOreDictionary; import com.pahimar.ee3.exchange.EnergyValueRegistry; -import com.pahimar.ee3.exchange.NewEnergyValueRegistry; import com.pahimar.ee3.handler.*; import com.pahimar.ee3.init.*; import com.pahimar.ee3.knowledge.AbilityRegistry; @@ -116,17 +114,14 @@ public class EquivalentExchange3 @EventHandler public void postInit(FMLPostInitializationEvent event) { - CachedOreDictionary.getInstance(); - Abilities.initNotLearnables(); + Abilities.init(); } @EventHandler public void onServerStopping(FMLServerStoppingEvent event) { WorldEventHandler.hasInitilialized = false; - - EnergyValueRegistry.getInstance().save(); - NewEnergyValueRegistry.INSTANCE.save(); + EnergyValueRegistry.INSTANCE.save(); TransmutationKnowledgeRegistry.getInstance().clear(); AbilityRegistry.getInstance().save(); } @@ -146,9 +141,9 @@ public class EquivalentExchange3 } } - public NewEnergyValueRegistry getEnergyValueRegistry() + public EnergyValueRegistry getEnergyValueRegistry() { - return NewEnergyValueRegistry.INSTANCE; + return EnergyValueRegistry.INSTANCE; } public RecipeRegistry getRecipeRegistry() diff --git a/src/main/java/com/pahimar/ee3/api/exchange/EnergyValueRegistryProxy.java b/src/main/java/com/pahimar/ee3/api/exchange/EnergyValueRegistryProxy.java index c49fa92f..e2c4066a 100644 --- a/src/main/java/com/pahimar/ee3/api/exchange/EnergyValueRegistryProxy.java +++ b/src/main/java/com/pahimar/ee3/api/exchange/EnergyValueRegistryProxy.java @@ -73,15 +73,24 @@ public final class EnergyValueRegistryProxy { } public static void setEnergyValue(Object object, Number energyValue) { + setEnergyValue(object, new EnergyValue(energyValue), Phase.POST_CALCULATION); + } + + public static void setEnergyValue(Object object, EnergyValue energyValue) { setEnergyValue(object, energyValue, Phase.POST_CALCULATION); } public static void setEnergyValue(Object object, Number energyValue, Phase phase) { + setEnergyValue(object, new EnergyValue(energyValue), phase); + } + + public static void setEnergyValue(Object object, EnergyValue energyValue, Phase phase) { + init(); if (ee3Mod != null) { - EE3Wrapper.ee3mod.getEnergyValueRegistry().setEnergyValue(object, new EnergyValue(energyValue), phase); + EE3Wrapper.ee3mod.getEnergyValueRegistry().setEnergyValue(object, energyValue, phase); } } @@ -97,10 +106,7 @@ public final class EnergyValueRegistryProxy { } public enum Phase { - @Deprecated PRE_ASSIGNMENT, PRE_CALCULATION, - @Deprecated POST_ASSIGNMENT, - POST_CALCULATION, - ALL + POST_CALCULATION } } diff --git a/src/main/java/com/pahimar/ee3/command/CommandSetEnergyValue.java b/src/main/java/com/pahimar/ee3/command/CommandSetEnergyValue.java index 88293459..3cb494a5 100644 --- a/src/main/java/com/pahimar/ee3/command/CommandSetEnergyValue.java +++ b/src/main/java/com/pahimar/ee3/command/CommandSetEnergyValue.java @@ -1,14 +1,10 @@ package com.pahimar.ee3.command; import com.pahimar.ee3.api.exchange.EnergyValue; -import com.pahimar.ee3.exchange.EnergyValueRegistry; +import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy; import com.pahimar.ee3.exchange.WrappedStack; -import com.pahimar.ee3.network.PacketHandler; -import com.pahimar.ee3.network.message.MessageSetEnergyValue; -import com.pahimar.ee3.reference.Files; import com.pahimar.ee3.reference.Messages; import com.pahimar.ee3.reference.Names; -import com.pahimar.ee3.util.SerializationHelper; import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; import net.minecraft.command.WrongUsageException; @@ -19,7 +15,6 @@ import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import java.util.List; -import java.util.Map; public class CommandSetEnergyValue extends CommandBase { @@ -93,46 +88,13 @@ public class CommandSetEnergyValue extends CommandBase if (wrappedStack != null && newEnergyValue != null && Float.compare(newEnergyValue.getValue(), 0) > 0) { - if (args[1].equalsIgnoreCase("pre")) - { - EnergyValueRegistry.getInstance().setEnergyValue(wrappedStack, newEnergyValue); - - Map preAssignedValues = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.PRE_CALCULATION_ENERGY_VALUES); - preAssignedValues.put(wrappedStack, newEnergyValue); - SerializationHelper.writeEnergyValueStackMapToJsonFile(Files.PRE_CALCULATION_ENERGY_VALUES, preAssignedValues); - EnergyValueRegistry.getInstance().setShouldRegenNextRestart(true); + if (args[1].equalsIgnoreCase("pre")) { + EnergyValueRegistryProxy.setEnergyValue(wrappedStack, newEnergyValue, EnergyValueRegistryProxy.Phase.PRE_CALCULATION); } - else if (args[1].equalsIgnoreCase("global-pre")) - { - EnergyValueRegistry.getInstance().setEnergyValue(wrappedStack, newEnergyValue); - - Map preAssignedValues = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.Global.preCalcluationEnergyValueFile); - preAssignedValues.put(wrappedStack, newEnergyValue); - SerializationHelper.writeEnergyValueStackMapToJsonFile(Files.Global.preCalcluationEnergyValueFile, preAssignedValues); - EnergyValueRegistry.getInstance().setShouldRegenNextRestart(true); + else if (args[1].equalsIgnoreCase("post")) { + EnergyValueRegistryProxy.setEnergyValue(wrappedStack, newEnergyValue); } - else if (args[1].equalsIgnoreCase("post")) - { - EnergyValueRegistry.getInstance().setEnergyValue(wrappedStack, newEnergyValue); - - Map postAssignedValues = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.POST_CALCULATION_ENERGY_VALUES); - postAssignedValues.put(wrappedStack, newEnergyValue); - SerializationHelper.writeEnergyValueStackMapToJsonFile(Files.POST_CALCULATION_ENERGY_VALUES, postAssignedValues); - - PacketHandler.INSTANCE.sendToAll(new MessageSetEnergyValue(wrappedStack, newEnergyValue)); - } - else if (args[1].equalsIgnoreCase("global-post")) - { - EnergyValueRegistry.getInstance().setEnergyValue(wrappedStack, newEnergyValue); - - Map postAssignedValues = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.Global.postCalcluationEnergyValueFile); - postAssignedValues.put(wrappedStack, newEnergyValue); - SerializationHelper.writeEnergyValueStackMapToJsonFile(Files.Global.postCalcluationEnergyValueFile, postAssignedValues); - - PacketHandler.INSTANCE.sendToAll(new MessageSetEnergyValue(wrappedStack, newEnergyValue)); - } - else - { + else { throw new WrongUsageException(Messages.Commands.SET_ENERGY_VALUE_USAGE); } @@ -151,7 +113,7 @@ public class CommandSetEnergyValue extends CommandBase { if (args.length == 2) { - return getListOfStringsMatchingLastWord(args, "pre", "global-pre", "post", "global-post"); + return getListOfStringsMatchingLastWord(args, "pre", "post"); } else if (args.length == 3) { diff --git a/src/main/java/com/pahimar/ee3/command/CommandSetEnergyValueCurrentItem.java b/src/main/java/com/pahimar/ee3/command/CommandSetEnergyValueCurrentItem.java index 7ce64026..8179e4ca 100644 --- a/src/main/java/com/pahimar/ee3/command/CommandSetEnergyValueCurrentItem.java +++ b/src/main/java/com/pahimar/ee3/command/CommandSetEnergyValueCurrentItem.java @@ -1,14 +1,10 @@ package com.pahimar.ee3.command; import com.pahimar.ee3.api.exchange.EnergyValue; -import com.pahimar.ee3.exchange.EnergyValueRegistry; +import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy; import com.pahimar.ee3.exchange.WrappedStack; -import com.pahimar.ee3.network.PacketHandler; -import com.pahimar.ee3.network.message.MessageSetEnergyValue; -import com.pahimar.ee3.reference.Files; import com.pahimar.ee3.reference.Messages; import com.pahimar.ee3.reference.Names; -import com.pahimar.ee3.util.SerializationHelper; import net.minecraft.command.CommandBase; import net.minecraft.command.ICommandSender; import net.minecraft.command.WrongUsageException; @@ -16,7 +12,6 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import java.util.List; -import java.util.Map; public class CommandSetEnergyValueCurrentItem extends CommandBase { @@ -65,41 +60,11 @@ public class CommandSetEnergyValueCurrentItem extends CommandBase { if (args[1].equalsIgnoreCase("pre")) { - EnergyValueRegistry.getInstance().setEnergyValue(wrappedStack, newEnergyValue); - - Map preAssignedValues = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.PRE_CALCULATION_ENERGY_VALUES); - preAssignedValues.put(wrappedStack, newEnergyValue); - SerializationHelper.writeEnergyValueStackMapToJsonFile(Files.PRE_CALCULATION_ENERGY_VALUES, preAssignedValues); - EnergyValueRegistry.getInstance().setShouldRegenNextRestart(true); - } - else if (args[1].equalsIgnoreCase("global-pre")) - { - EnergyValueRegistry.getInstance().setEnergyValue(wrappedStack, newEnergyValue); - - Map preAssignedValues = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.Global.preCalcluationEnergyValueFile); - preAssignedValues.put(wrappedStack, newEnergyValue); - SerializationHelper.writeEnergyValueStackMapToJsonFile(Files.Global.preCalcluationEnergyValueFile, preAssignedValues); - EnergyValueRegistry.getInstance().setShouldRegenNextRestart(true); + EnergyValueRegistryProxy.setEnergyValue(wrappedStack, newEnergyValue, EnergyValueRegistryProxy.Phase.PRE_CALCULATION); } else if (args[1].equalsIgnoreCase("post")) { - EnergyValueRegistry.getInstance().setEnergyValue(wrappedStack, newEnergyValue); - - Map postAssignedValues = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.POST_CALCULATION_ENERGY_VALUES); - postAssignedValues.put(wrappedStack, newEnergyValue); - SerializationHelper.writeEnergyValueStackMapToJsonFile(Files.POST_CALCULATION_ENERGY_VALUES, postAssignedValues); - - PacketHandler.INSTANCE.sendToAll(new MessageSetEnergyValue(wrappedStack, newEnergyValue)); - } - else if (args[1].equalsIgnoreCase("global-post")) - { - EnergyValueRegistry.getInstance().setEnergyValue(wrappedStack, newEnergyValue); - - Map postAssignedValues = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.Global.postCalcluationEnergyValueFile); - postAssignedValues.put(wrappedStack, newEnergyValue); - SerializationHelper.writeEnergyValueStackMapToJsonFile(Files.Global.postCalcluationEnergyValueFile, postAssignedValues); - - PacketHandler.INSTANCE.sendToAll(new MessageSetEnergyValue(wrappedStack, newEnergyValue)); + EnergyValueRegistryProxy.setEnergyValue(wrappedStack, newEnergyValue); } else { @@ -126,7 +91,7 @@ public class CommandSetEnergyValueCurrentItem extends CommandBase { if (args.length == 2) { - return getListOfStringsMatchingLastWord(args, "pre", "global-pre", "post", "global-post"); + return getListOfStringsMatchingLastWord(args, "pre", "post"); } return null; diff --git a/src/main/java/com/pahimar/ee3/command/CommandSyncEnergyValues.java b/src/main/java/com/pahimar/ee3/command/CommandSyncEnergyValues.java index b61b04ff..2f4ee8e8 100644 --- a/src/main/java/com/pahimar/ee3/command/CommandSyncEnergyValues.java +++ b/src/main/java/com/pahimar/ee3/command/CommandSyncEnergyValues.java @@ -68,7 +68,7 @@ public class CommandSyncEnergyValues extends CommandBase if (shouldSync) { LogHelper.info(EnergyValueRegistry.ENERGY_VALUE_MARKER, "Syncing energy values with player '{}' at their request", commandSender.getCommandSenderName()); - PacketHandler.INSTANCE.sendTo(new MessageSyncEnergyValues(EnergyValueRegistry.getInstance()), (EntityPlayerMP) commandSender); + PacketHandler.INSTANCE.sendTo(new MessageSyncEnergyValues(), (EntityPlayerMP) commandSender); commandSender.addChatMessage(new ChatComponentTranslation(Messages.Commands.SYNC_ENERGY_VALUES_SUCCESS)); } else diff --git a/src/main/java/com/pahimar/ee3/exchange/CachedOreDictionary.java b/src/main/java/com/pahimar/ee3/exchange/CachedOreDictionary.java deleted file mode 100644 index ef0bfdf9..00000000 --- a/src/main/java/com/pahimar/ee3/exchange/CachedOreDictionary.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.pahimar.ee3.exchange; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.Multimap; -import com.google.common.collect.TreeMultimap; -import com.pahimar.ee3.reference.Comparators; -import com.pahimar.ee3.util.LogHelper; -import net.minecraft.item.ItemStack; -import net.minecraftforge.oredict.OreDictionary; - -import java.util.*; - -public class CachedOreDictionary -{ - private static CachedOreDictionary cachedOreDictionary = null; - private ImmutableMap idToNameMap; - private ImmutableMap> oreNameToItemStackMap; - private ImmutableMultimap itemStackToOreNameMap; - - private CachedOreDictionary() - { - Map idToOreNameMap = new TreeMap(); - Map> nameToStackMap = new TreeMap>(Comparators.stringComparator); - Multimap stackToNameMultiMap = TreeMultimap.create(WrappedStack.comparator, Comparators.stringComparator); - - for (String oreName : OreDictionary.getOreNames()) - { - idToOreNameMap.put(OreDictionary.getOreID(oreName), oreName); - - List oreNameItemStacks = OreDictionary.getOres(oreName); - nameToStackMap.put(oreName, oreNameItemStacks); - - for (ItemStack itemStack : oreNameItemStacks) - { - stackToNameMultiMap.put(WrappedStack.wrap(itemStack), oreName); - } - } - - idToNameMap = ImmutableMap.copyOf(idToOreNameMap); - oreNameToItemStackMap = ImmutableMap.copyOf(nameToStackMap); - itemStackToOreNameMap = ImmutableMultimap.copyOf(stackToNameMultiMap); - } - - public static CachedOreDictionary getInstance() - { - if (cachedOreDictionary == null) - { - cachedOreDictionary = new CachedOreDictionary(); - } - - return cachedOreDictionary; - } - - public Set getOreNames() - { - return oreNameToItemStackMap.keySet(); - } - - public List getItemStacksForOreName(String oreName) - { - if (oreNameToItemStackMap.containsKey(oreName)) - { - return oreNameToItemStackMap.get(oreName); - } - - return new ArrayList(); - } - - public List getOreNamesForItemStack(ItemStack itemStack) - { - List oreNameList = new ArrayList(); - WrappedStack wrappedStack = WrappedStack.wrap(itemStack); - - if (itemStackToOreNameMap.containsKey(wrappedStack)) - { - for (String oreName : itemStackToOreNameMap.get(wrappedStack)) - { - oreNameList.add(oreName); - } - } - else - { - for (WrappedStack wrappedStack1 : itemStackToOreNameMap.keySet()) - { - - } - } - - return oreNameList; - } - - public void dumpCachedOreDictionaryToLog() - { - for (String oreName : CachedOreDictionary.getInstance().getOreNames()) - { - LogHelper.info("OreName: {}, ItemStacks: {}", oreName, CachedOreDictionary.getInstance().getItemStacksForOreName(oreName)); - } - } -} diff --git a/src/main/java/com/pahimar/ee3/exchange/DynamicEnergyValueInitThread.java b/src/main/java/com/pahimar/ee3/exchange/DynamicEnergyValueInitThread.java deleted file mode 100644 index 82bf8bae..00000000 --- a/src/main/java/com/pahimar/ee3/exchange/DynamicEnergyValueInitThread.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.pahimar.ee3.exchange; - -import com.pahimar.ee3.recipe.AludelRecipeManager; -import com.pahimar.ee3.recipe.RecipeRegistry; -import com.pahimar.ee3.util.LogHelper; - -public class DynamicEnergyValueInitThread implements Runnable -{ - private static DynamicEnergyValueInitThread instance = new DynamicEnergyValueInitThread(); - - public static void initEnergyValueRegistry() - { - new Thread(instance, "DynamicEMC Thread").start(); - } - - @Override - public void run() - { - // Add in recipes to the RecipeRegistry *just* before we do calculations - RecipeRegistry.getInstance().registerVanillaRecipes(); - AludelRecipeManager.registerRecipes(); - - long startTime = System.nanoTime(); -// EnergyValueRegistry.getInstance().init(); - NewEnergyValueRegistry.INSTANCE.compute(); - LogHelper.info(EnergyValueRegistry.ENERGY_VALUE_MARKER, "DynamicEMC system initialized after {} ms", System.nanoTime() - startTime); - } -} diff --git a/src/main/java/com/pahimar/ee3/exchange/EnergyValueRegistry.java b/src/main/java/com/pahimar/ee3/exchange/EnergyValueRegistry.java index 471da510..9ab72e82 100644 --- a/src/main/java/com/pahimar/ee3/exchange/EnergyValueRegistry.java +++ b/src/main/java/com/pahimar/ee3/exchange/EnergyValueRegistry.java @@ -1,14 +1,13 @@ package com.pahimar.ee3.exchange; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedMap; -import com.google.gson.*; +import com.google.gson.JsonParseException; +import com.pahimar.ee3.api.event.EnergyValueEvent; import com.pahimar.ee3.api.exchange.EnergyValue; -import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy; import com.pahimar.ee3.api.exchange.IEnergyValueProvider; import com.pahimar.ee3.handler.ConfigurationHandler; import com.pahimar.ee3.recipe.RecipeRegistry; -import com.pahimar.ee3.reference.Files; -import com.pahimar.ee3.reference.Reference; import com.pahimar.ee3.util.LoaderHelper; import com.pahimar.ee3.util.LogHelper; import com.pahimar.ee3.util.SerializationHelper; @@ -16,619 +15,434 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Loader; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +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; -import java.io.File; -import java.lang.reflect.Type; +import java.io.*; import java.util.*; -public class EnergyValueRegistry implements JsonSerializer, JsonDeserializer -{ +import static com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy.Phase; + +public class EnergyValueRegistry { + + public static final EnergyValueRegistry INSTANCE = new EnergyValueRegistry(); + + private ImmutableSortedMap stackValueMap; + private ImmutableSortedMap> valueStackMap; + + private final Map preCalculationStackValueMap; + private final Map postCalculationStackValueMap; + private transient SortedSet uncomputedStacks; + private transient boolean loadedFromMap; + + public static File energyValuesDirectory; + public static File energyValuesFile; + public static File preCalculationValuesFile; + public static File postCalculationValuesFile; + public static final Marker ENERGY_VALUE_MARKER = MarkerManager.getMarker("EE3_ENERGY_VALUE", LogHelper.MOD_MARKER); - private static final Marker PRE_CALC_MARKER = MarkerManager.getMarker("EE3_ENERGY_VALUE_PRE_CALC", ENERGY_VALUE_MARKER); - private static final Marker POST_CALC_MARKER = MarkerManager.getMarker("EE3_ENERGY_VALUE_POST_CALC", ENERGY_VALUE_MARKER); - private static final Gson JSON_SERIALIZER = (new GsonBuilder()).setPrettyPrinting().registerTypeAdapter(EnergyValueRegistry.class, new EnergyValueRegistry()).registerTypeAdapter(EnergyValueStackMapping.class, new EnergyValueStackMapping()).create(); - private static EnergyValueRegistry energyValueRegistry = null; - private static Map preCalculationMappings; - private static Map postCalculationMappings; - private boolean shouldRegenNextRestart = false; - private ImmutableSortedMap stackMappings; - private ImmutableSortedMap> valueMappings; - private SortedSet uncomputedStacks; + private EnergyValueRegistry() { - private EnergyValueRegistry() - { + ImmutableSortedMap.Builder stackMapBuilder = ImmutableSortedMap.naturalOrder(); + stackValueMap = stackMapBuilder.build(); + + preCalculationStackValueMap = new TreeMap<>(); + postCalculationStackValueMap = new TreeMap<>(); + uncomputedStacks = new TreeSet<>(); + loadedFromMap = false; } - public static EnergyValueRegistry getInstance() - { - if (energyValueRegistry == null) - { - energyValueRegistry = new EnergyValueRegistry(); - } + /** + * Returns an {@link EnergyValue} for a {@link Object} in the provided {@link Map>} of {@link WrappedStack}s mapped + * to EnergyValues + * + *

The order of checking is as follows;

+ *
    + *
  1. {@link ItemStack}s whose {@link Item}s implement {@link IEnergyValueProvider}
  2. + *
  3. Direct EnergyValue mapping of the provided Object in the provided Map
  4. + *
  5. The following criteria are only checked (in order) in the event that this is a non-strict query; + *
      + *
    1. + * ItemStacks that are part of an {@link OreDictionary} entry are checked to see if + * all Ores they are registered to have the same non-null EnergyValue assigned to + * it + *
        + *
      • + * e.g., ItemStack X is associated with OreDictionary entries A, B and C. An EnergyValue + * would be returned for X only if A, B and C all had the same non-null EnergyValue + *
      • + *
      + *
    2. + *
    3. + * ItemStacks are checked to see if there exist {@link OreDictionary#WILDCARD_VALUE} equivalents + *
    4. + *
    5. + * {@link OreStack}s are checked to see if all members of the OreDictionary entry represented by the + * OreStack have the same non-null EnergyValue (similar to the case for ItemStacks above) + *
    6. + *
    + *
  6. + *
+ * + * @param valueMap a {@link Map} of {@link EnergyValue}'s mapped to {@link WrappedStack}'s + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value + * 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 valueMap, Object object, boolean strict) { + if (WrappedStack.canBeWrapped(object)) { - return energyValueRegistry; - } + WrappedStack wrappedStack = WrappedStack.wrap(object, 1); + Object wrappedObject = wrappedStack.getWrappedObject(); - public void addPreCalculationEnergyValue(Object object, float energyValue) - { - addPreCalculationEnergyValue(object, new EnergyValue(energyValue)); - } + if (wrappedObject instanceof ItemStack && ((ItemStack) wrappedObject).getItem() instanceof IEnergyValueProvider && !strict) { - public void addPreCalculationEnergyValue(Object object, EnergyValue energyValue) - { - if (preCalculationMappings == null) - { - preCalculationMappings = new TreeMap(); - } + EnergyValue energyValue = ((IEnergyValueProvider) ((ItemStack) wrappedObject).getItem()).getEnergyValue(((ItemStack) wrappedObject)); - if (WrappedStack.canBeWrapped(object) && energyValue != null && Float.compare(energyValue.getValue(), 0f) > 0) - { - WrappedStack wrappedStack = WrappedStack.wrap(object); + if (energyValue != null && Float.compare(energyValue.getValue(), 0f) > 0) { + return energyValue; + } + } - if (wrappedStack.getStackSize() > 0) - { - WrappedStack factoredWrappedStack = WrappedStack.wrap(wrappedStack, 1); - EnergyValue factoredEnergyValue = EnergyValue.factor(energyValue, wrappedStack.getStackSize()); + if (valueMap != null && !valueMap.isEmpty()) { - if (preCalculationMappings.containsKey(factoredWrappedStack)) - { - if (factoredEnergyValue.compareTo(preCalculationMappings.get(factoredWrappedStack)) < 0) - { - LogHelper.trace(PRE_CALC_MARKER, "[{}] Mod with ID '{}' setEnergyValue a pre-calculation energy value of {} for object {}", LoaderHelper.getLoaderState(), Loader.instance().activeModContainer().getModId(), energyValue, wrappedStack); - preCalculationMappings.put(factoredWrappedStack, factoredEnergyValue); + // First check for a direct energy value mapping to the wrapped object + if (valueMap.containsKey(wrappedStack)) { + return valueMap.get(wrappedStack); + } + else if (!strict) { + + if (wrappedObject instanceof ItemStack) { + + ItemStack unValuedItemStack = ItemStack.copyItemStack((ItemStack) wrappedObject); + EnergyValue minEnergyValue = null; + + int[] oreIds = OreDictionary.getOreIDs(unValuedItemStack); + if (oreIds.length > 0) { + + EnergyValue energyValue = null; + boolean allHaveSameValue = true; + + for (int oreId : oreIds) { + String oreName = OreDictionary.getOreName(oreId); + + if (!"Unknown".equalsIgnoreCase(oreName)) { + + WrappedStack oreStack = WrappedStack.wrap(new OreStack(oreName)); + + if (oreStack != null && valueMap.containsKey(oreStack)) { + + if (energyValue == null) { + energyValue = valueMap.get(oreStack); + } + else if (!energyValue.equals(valueMap.get(oreStack))) { + allHaveSameValue = false; + } + } + else { + allHaveSameValue = false; + } + } + else { + allHaveSameValue = false; + } + } + + if (allHaveSameValue) { + return energyValue; + } + } + else { + for (WrappedStack valuedWrappedStack : valueMap.keySet()) { + if (valuedWrappedStack.getWrappedObject() instanceof ItemStack) { + if (Item.getIdFromItem(((ItemStack) valuedWrappedStack.getWrappedObject()).getItem()) == Item.getIdFromItem(unValuedItemStack.getItem())) { + + ItemStack valuedItemStack = (ItemStack) valuedWrappedStack.getWrappedObject(); + if (valuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE || unValuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE) { + + EnergyValue energyValue = valueMap.get(valuedWrappedStack); + + if (energyValue.compareTo(minEnergyValue) < 0) { + minEnergyValue = energyValue; + } + } + } + } + } + } + } + else if (wrappedObject instanceof OreStack) { + + OreStack oreStack = (OreStack) wrappedObject; + List itemStacks = OreDictionary.getOres(oreStack.oreName); + + if (!itemStacks.isEmpty()) { + + EnergyValue energyValue = null; + boolean allHaveSameValue = true; + + for (ItemStack itemStack : itemStacks) { + WrappedStack wrappedItemStack = WrappedStack.wrap(itemStack, 1); + + if (wrappedItemStack != null && valueMap.containsKey(wrappedItemStack)) { + if (energyValue == null) { + energyValue = valueMap.get(wrappedItemStack); + } + else if (!energyValue.equals(valueMap.get(wrappedItemStack))) { + allHaveSameValue = false; + } + } + else { + allHaveSameValue = false; + } + } + + if (allHaveSameValue) { + return energyValue; + } + } } } - else - { - LogHelper.trace(PRE_CALC_MARKER, "[{}] Mod with ID '{}' setEnergyValue a pre-calculation energy value of {} for object {}", LoaderHelper.getLoaderState(), Loader.instance().activeModContainer().getModId(), energyValue, wrappedStack); - preCalculationMappings.put(factoredWrappedStack, factoredEnergyValue); + } + } + + return null; + } + + /** + * Calculates an {@link EnergyValue} for the provided {@link WrappedStack} output from the provided {@link List} of + * WrappedStack inputs and {@link Map} of energy value mappings to objects. We calculate the energy value for the + * output by, for each input, summing the input's energy value * the input's stack size. That sum is then divided + * by the stack size of the output. If any of the inputs do not have an energy value then no + * energy value can be calculated for the output - therefore we return null + * + * @param valueMap a {@link Map} of {@link EnergyValue}'s mapped to {@link WrappedStack}'s + * @param wrappedOutput the {@link WrappedStack} output for that the inputs "create" + * @param wrappedInputs a {@link List} of {@link WrappedStack}s that "create" the output + * @return an {@link EnergyValue} if there is one that can be calculated, null otherwise + */ + private static EnergyValue computeFromInputs(Map valueMap, WrappedStack wrappedOutput, List wrappedInputs) { + + float sumOfValues = 0f; + + for (WrappedStack wrappedInput : wrappedInputs) { + + EnergyValue inputValue; + int stackSize = Integer.MIN_VALUE; + + if (wrappedInput.getWrappedObject() instanceof ItemStack) { + + ItemStack inputItemStack = (ItemStack) wrappedInput.getWrappedObject(); + + // Check if we are dealing with a potential fluid + if (FluidContainerRegistry.getFluidForFilledItem(inputItemStack) != null) { + + if (inputItemStack.getItem().getContainerItem(inputItemStack) != null) { + stackSize = FluidContainerRegistry.getFluidForFilledItem(inputItemStack).amount * wrappedInput.getStackSize(); + inputValue = getEnergyValue(valueMap, FluidContainerRegistry.getFluidForFilledItem(inputItemStack), false); + } + else { + inputValue = getEnergyValue(valueMap, wrappedInput, false); + } + } + else if (inputItemStack.getItem().getContainerItem(inputItemStack) != null) { + + ItemStack inputContainerItemStack = inputItemStack.getItem().getContainerItem(inputItemStack); + + if (getEnergyValue(valueMap, inputItemStack, false) != null && getEnergyValue(valueMap, inputContainerItemStack, false) != null) { + float itemStackValue = getEnergyValue(valueMap, inputItemStack, false).getValue(); + float containerStackValue = getEnergyValue(valueMap, inputContainerItemStack, false).getValue(); + inputValue = new EnergyValue(itemStackValue - containerStackValue); + } + else { + inputValue = new EnergyValue(0); + } + } + else if (!inputItemStack.getItem().doesContainerItemLeaveCraftingGrid(inputItemStack)) { + inputValue = new EnergyValue(0); + } + else if (OreDictionary.getOreIDs(inputItemStack).length > 0) { + inputValue = getEnergyValue(valueMap, wrappedInput, true); + } + else { + inputValue = getEnergyValue(valueMap, wrappedInput, false); } } - } - } + else if (wrappedInput.getWrappedObject() instanceof OreStack) { - public void addPostCalculationExactEnergyValue(Object object, float energyValue) - { - addPostCalculationExactEnergyValue(object, new EnergyValue(energyValue)); - } + OreStack inputOreStack = (OreStack) wrappedInput.getWrappedObject(); + inputValue = getEnergyValue(valueMap, wrappedInput, false); + for (ItemStack itemStack : OreDictionary.getOres(inputOreStack.oreName)) { + if (!itemStack.getItem().doesContainerItemLeaveCraftingGrid(itemStack)) { + inputValue = new EnergyValue(0); + } + } + } + else { + inputValue = getEnergyValue(valueMap, wrappedInput, false); + } - public void addPostCalculationExactEnergyValue(Object object, EnergyValue energyValue) - { - if (postCalculationMappings == null) - { - postCalculationMappings = new TreeMap(); - } + if (inputValue != null) { - if (WrappedStack.canBeWrapped(object) && energyValue != null && Float.compare(energyValue.getValue(), 0f) > 0) - { - WrappedStack wrappedStack = WrappedStack.wrap(object); + if (stackSize == Integer.MIN_VALUE) { + stackSize = wrappedInput.getStackSize(); + } - if (wrappedStack.getStackSize() > 0) - { - WrappedStack factoredWrappedStack = WrappedStack.wrap(wrappedStack, 1); - EnergyValue factoredEnergyValue = EnergyValue.factor(energyValue, wrappedStack.getStackSize()); - - LogHelper.trace(POST_CALC_MARKER, "[{}] Mod with ID '{}' setEnergyValue a post-calculation energy value of {} for object {}", LoaderHelper.getLoaderState(), Loader.instance().activeModContainer().getModId(), energyValue, wrappedStack); - postCalculationMappings.put(factoredWrappedStack, factoredEnergyValue); + sumOfValues += inputValue.getValue() * stackSize; + } + else { + return null; } } + + return EnergyValue.factor(new EnergyValue(sumOfValues), wrappedOutput.getStackSize()); } - public boolean hasEnergyValue(Object object) - { + /** + * Returns an {@link ImmutableMap} containing the current energy value mappings + * + * @return an {@link ImmutableMap} containing the current energy value mappings + */ + public ImmutableMap getEnergyValues() { + return stackValueMap; + } + + /** + * Returns a {@link Map} containing the pre-calculation energy value mappings + * + * @return a {link Map} containing the pre-calculation energy value mappings + */ + public Map getPreCalculationStackValueMap() { + return preCalculationStackValueMap; + } + + /** + * Returns a {@link Map} containing the post-calculation energy value mappings + * + * @return a {@link Map} containing the post-calculation energy value mappings + */ + public Map getPostCalculationStackValueMap() { + return postCalculationStackValueMap; + } + + /** + * Checks if there exists an {@link EnergyValue} associated with the provided {@link Object}. + * + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @return true if the provided object has an energy value, false otherwise + */ + public boolean hasEnergyValue(Object object) { return hasEnergyValue(object, false); } - public boolean hasEnergyValue(Object object, boolean strict) - { + /** + * Checks if there exists an {@link EnergyValue} associated with the provided {@link Object} + * + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value + * assignments) query or not + * @return true if the provided object has an energy value, false otherwise + */ + public boolean hasEnergyValue(Object object, boolean strict) { return getEnergyValue(object, strict) != null; } - public EnergyValue getEnergyValue(Object object) - { - return getEnergyValue(EnergyValueRegistryProxy.Phase.ALL, object, false); + /** + * Returns an {@link EnergyValue} associated with the provided {@link Object} (if there is one) + * + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @return an {@link EnergyValue} if there is one to be found, null otherwise + */ + public EnergyValue getEnergyValue(Object object) { + return getEnergyValue(object, false); } - public EnergyValue getEnergyValue(Object object, boolean strict) - { - return getEnergyValue(EnergyValueRegistryProxy.Phase.ALL, object, strict); + /** + * Returns an {@link EnergyValue} associated with the provided {@link Object} (if there is one) + * + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value + * assignments) query or not + * @return an {@link EnergyValue} if there is one to be found, null otherwise + */ + public EnergyValue getEnergyValue(Object object, boolean strict) { + return getEnergyValue(stackValueMap, object, strict); } - public EnergyValue getEnergyValue(EnergyValueRegistryProxy.Phase phase, Object object, boolean strict) - { - if (phase == EnergyValueRegistryProxy.Phase.PRE_ASSIGNMENT || phase == EnergyValueRegistryProxy.Phase.PRE_CALCULATION) - { - return getEnergyValueFromMap(preCalculationMappings, object, strict); - } - else if (phase == EnergyValueRegistryProxy.Phase.POST_ASSIGNMENT || phase == EnergyValueRegistryProxy.Phase.POST_CALCULATION) - { - return getEnergyValueFromMap(postCalculationMappings, object, strict); - } - else - { - return getEnergyValueFromMap(energyValueRegistry.stackMappings, object, strict); - } - } + /** + * Returns an {@link EnergyValue} associated with the provided {@link Object} (if there is one) + * + * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} + * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value + * assignments) query or not + * @return an {@link EnergyValue} if there is one to be found, null otherwise + */ + public EnergyValue getEnergyValueForStack(Object object, boolean strict) { - public EnergyValue getEnergyValueForStack(Object object, boolean strict) - { WrappedStack wrappedObject = WrappedStack.wrap(object); - if (wrappedObject != null && getEnergyValue(object, strict) != null) - { + if (wrappedObject != null && getEnergyValue(object, strict) != null) { return new EnergyValue(getEnergyValue(object, strict).getValue() * wrappedObject.getStackSize()); } return null; } - public EnergyValue getEnergyValueFromMap(Map stackEnergyValueMap, Object object) - { - return getEnergyValueFromMap(stackEnergyValueMap, object, false); - } - - public EnergyValue getEnergyValueFromMap(Map stackEnergyValueMap, Object object, boolean strict) - { - if (WrappedStack.canBeWrapped(object)) - { - WrappedStack wrappedStackObject = WrappedStack.wrap(object); - WrappedStack unitWrappedStackObject = WrappedStack.wrap(object); - unitWrappedStackObject.setStackSize(1); - Object wrappedObject = wrappedStackObject.getWrappedObject(); - - /** - * In the event that an Item has an IEnergyValueProvider implementation, route the call to the implementation - */ - if (wrappedObject instanceof ItemStack && ((ItemStack) wrappedObject).getItem() instanceof IEnergyValueProvider && !strict) - { - ItemStack itemStack = (ItemStack) wrappedObject; - IEnergyValueProvider iEnergyValueProvider = (IEnergyValueProvider) itemStack.getItem(); - EnergyValue energyValue = iEnergyValueProvider.getEnergyValue(itemStack); - - if (energyValue != null && energyValue.getValue() > 0f) - { - return energyValue; - } - } - else if (stackEnergyValueMap != null) - { - /** - * Check for a direct value mapping for the object - */ - if (stackEnergyValueMap.containsKey(unitWrappedStackObject)) - { - return stackEnergyValueMap.get(unitWrappedStackObject); - } - else if (!strict) - { - if (wrappedObject instanceof ItemStack) { - EnergyValue lowestValue = null; - ItemStack wrappedItemStack = (ItemStack) wrappedObject; - - /** - * The ItemStack does not have a direct mapping, so check if it is a member of an OreDictionary - * entry. If it is a member of an OreDictionary entry, check if every ore name it is associated - * with has 1) a direct mapping, and 2) the same mapping value - */ - if (OreDictionary.getOreIDs(wrappedItemStack).length >= 1) - { - EnergyValue energyValue = null; - boolean allHaveSameValueFlag = true; - - // Scan all valid ore dictionary values, if they ALL have the same value, then return it - for (int oreID : OreDictionary.getOreIDs(wrappedItemStack)) - { - String oreName = OreDictionary.getOreName(oreID); - if (!oreName.equals("Unknown")) - { - WrappedStack oreStack = WrappedStack.wrap(new OreStack(oreName)); - - if (oreStack != null && stackEnergyValueMap.containsKey(oreStack)) - { - if (energyValue == null) - { - energyValue = stackEnergyValueMap.get(oreStack); - } - else if (!energyValue.equals(stackEnergyValueMap.get(oreStack))) - { - allHaveSameValueFlag = false; - } - } - else - { - allHaveSameValueFlag = false; - } - } - else - { - allHaveSameValueFlag = false; - } - } - - if (energyValue != null && allHaveSameValueFlag) - { - return energyValue; - } - } - else - { - /** - * Scan the stack value map for ItemStacks that have the same Item. If one is found, check - * if it has a wildcard meta value (and therefore is considered the same). Otherwise, check - * if the ItemStack is "damageable" and calculate the value for the damaged stack. - */ - for (WrappedStack valuedStack : stackEnergyValueMap.keySet()) - { - if (valuedStack.getWrappedObject() instanceof ItemStack) - { - ItemStack valuedItemStack = (ItemStack) valuedStack.getWrappedObject(); - - if (Item.getIdFromItem(valuedItemStack.getItem()) == Item.getIdFromItem(wrappedItemStack.getItem())) - { - if (valuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE || wrappedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE) - { - EnergyValue stackValue = stackEnergyValueMap.get(valuedStack); - - if (stackValue.compareTo(lowestValue) < 0) - { - lowestValue = stackValue; - } - } - else if (wrappedItemStack.getItem().isDamageable() && wrappedItemStack.isItemDamaged()) - { - EnergyValue stackValue = new EnergyValue(stackEnergyValueMap.get(valuedStack).getValue() * (1 - (wrappedItemStack.getItemDamage() * 1.0F / wrappedItemStack.getMaxDamage()))); - - if (stackValue.compareTo(lowestValue) < 0) - { - lowestValue = stackValue; - } - } - } - } - } - - return lowestValue; - } - } - else if (wrappedObject instanceof OreStack) - { - OreStack oreStack = (OreStack) wrappedObject; - - if (CachedOreDictionary.getInstance().getItemStacksForOreName(oreStack.oreName).size() >= 1) - { - EnergyValue energyValue = null; - boolean allHaveSameValueFlag = true; - - // Scan all valid ore dictionary values, if they ALL have the same value, then return it - for (ItemStack itemStack : CachedOreDictionary.getInstance().getItemStacksForOreName(oreStack.oreName)) - { - WrappedStack wrappedItemStack = WrappedStack.wrap(itemStack); - - if (wrappedItemStack != null && stackEnergyValueMap.containsKey(wrappedItemStack)) - { - if (energyValue == null) - { - energyValue = stackEnergyValueMap.get(wrappedItemStack); - } - else if (!energyValue.equals(stackEnergyValueMap.get(wrappedItemStack))) - { - allHaveSameValueFlag = false; - } - } - else - { - allHaveSameValueFlag = false; - } - } - - if (energyValue != null && allHaveSameValueFlag) - { - return energyValue; - } - } - } - } - } - } - - return null; - } - - protected final void init() - { - if (!loadEnergyValueRegistryFromFile()) - { - runDynamicEnergyValueResolution(); - } - this.shouldRegenNextRestart = false; - } - - private void runDynamicEnergyValueResolution() - { - TreeMap stackValueMap = new TreeMap(); - uncomputedStacks = null; - - // Add in all mod specified pre-calculation values - stackValueMap.putAll(preCalculationMappings); // TODO Logging - - // Add in all global pre-calculation values - LogHelper.trace(ENERGY_VALUE_MARKER, "Adding EnergyValue mappings from {}", Files.Global.preCalcluationEnergyValueFile); - Map globalPreCalculationValueMap = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.Global.preCalcluationEnergyValueFile); - for (WrappedStack wrappedStack : globalPreCalculationValueMap.keySet()) - { - if (globalPreCalculationValueMap.get(wrappedStack) != null) - { - stackValueMap.put(wrappedStack, globalPreCalculationValueMap.get(wrappedStack)); - LogHelper.trace(ENERGY_VALUE_MARKER, "Adding EnergyValue {} for {}", globalPreCalculationValueMap.get(wrappedStack), wrappedStack); - } - } - - // Add in all instance pre-calculation values - LogHelper.trace(ENERGY_VALUE_MARKER, "Adding EnergyValue mappings from {}", Files.PRE_CALCULATION_ENERGY_VALUES); - Map instancePreAssignedValueMap = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.PRE_CALCULATION_ENERGY_VALUES); - for (WrappedStack wrappedStack : instancePreAssignedValueMap.keySet()) - { - if (instancePreAssignedValueMap.get(wrappedStack) != null) - { - stackValueMap.put(wrappedStack, instancePreAssignedValueMap.get(wrappedStack)); - LogHelper.trace(ENERGY_VALUE_MARKER, "Adding EnergyValue {} for {}", instancePreAssignedValueMap.get(wrappedStack), wrappedStack); - } - } - - /* - * Auto-assignment - */ - Map computedStackValues; - int passNumber = 0; - long computationStartTime = System.currentTimeMillis(); - long passStartTime; - int passComputedValueCount = 0; - int totalComputedValueCount = 0; - LogHelper.info(ENERGY_VALUE_MARKER, "Beginning dynamic value calculation"); - boolean isFirstPass = true; - while ((isFirstPass || passComputedValueCount > 0) && (passNumber < 16)) - { - if (isFirstPass) - { - isFirstPass = false; - } - passComputedValueCount = 0; - passStartTime = System.currentTimeMillis(); - passNumber++; - - // Compute stack mappings from existing stack mappings - computedStackValues = computeStackMappings(stackValueMap, passNumber); - - for (WrappedStack keyStack : computedStackValues.keySet()) - { - EnergyValue factoredExchangeEnergyValue = null; - WrappedStack factoredKeyStack = null; - - if (keyStack != null && keyStack.getWrappedObject() != null && keyStack.getStackSize() > 0) - { - if (computedStackValues.get(keyStack) != null && Float.compare(computedStackValues.get(keyStack).getValue(), 0f) > 0) - { - factoredExchangeEnergyValue = EnergyValue.factor(computedStackValues.get(keyStack), keyStack.getStackSize()); - factoredKeyStack = WrappedStack.wrap(keyStack, 1); - } - } - - if (factoredExchangeEnergyValue != null) - { - if (stackValueMap.containsKey(factoredKeyStack)) - { - if (factoredExchangeEnergyValue.compareTo(stackValueMap.get(factoredKeyStack)) == -1) - { -// LogHelper.trace(String.format("")); TODO Log message - stackValueMap.put(factoredKeyStack, factoredExchangeEnergyValue); - } - } - else - { -// LogHelper.trace(String.format("")); TODO Log message - stackValueMap.put(factoredKeyStack, factoredExchangeEnergyValue); - passComputedValueCount++; - totalComputedValueCount++; - } - } - } - LogHelper.info(ENERGY_VALUE_MARKER, "Pass {}: Calculated {} values for objects in {} ms", passNumber, passComputedValueCount, System.currentTimeMillis() - passStartTime); - } - LogHelper.info(ENERGY_VALUE_MARKER, "Finished dynamic value calculation (calculated {} values for objects in {} ms)", totalComputedValueCount, System.currentTimeMillis() - computationStartTime); - - // Add in all mod specified post-calculation values - // TODO Logging - if (postCalculationMappings != null) - { - for (WrappedStack wrappedStack : postCalculationMappings.keySet()) - { - if (postCalculationMappings.get(wrappedStack) != null) - { - stackValueMap.put(wrappedStack, postCalculationMappings.get(wrappedStack)); - } - } - } - else - { - postCalculationMappings = new TreeMap(); - } - - // Add in all global post-calculation values - LogHelper.trace(ENERGY_VALUE_MARKER, "Adding EnergyValue mappings from {}", Files.Global.postCalcluationEnergyValueFile); - Map globalPostCalculationValueMap = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.Global.postCalcluationEnergyValueFile); - for (WrappedStack wrappedStack : globalPostCalculationValueMap.keySet()) - { - if (globalPostCalculationValueMap.get(wrappedStack) != null) - { - stackValueMap.put(wrappedStack, globalPostCalculationValueMap.get(wrappedStack)); - LogHelper.trace(ENERGY_VALUE_MARKER, "Adding EnergyValue {} for {}", globalPostCalculationValueMap.get(wrappedStack), wrappedStack); - } - } - - // Add in all instance post-calculation values - LogHelper.trace(ENERGY_VALUE_MARKER, "Adding EnergyValue mappings from {}", Files.POST_CALCULATION_ENERGY_VALUES); - Map instancePostCalculationValueMap = SerializationHelper.readEnergyValueStackMapFromJsonFile(Files.POST_CALCULATION_ENERGY_VALUES); - for (WrappedStack wrappedStack : instancePostCalculationValueMap.keySet()) - { - if (instancePostCalculationValueMap.get(wrappedStack) != null) - { - stackValueMap.put(wrappedStack, instancePostCalculationValueMap.get(wrappedStack)); - LogHelper.trace(ENERGY_VALUE_MARKER, "Adding EnergyValue {} for {}", instancePreAssignedValueMap.get(wrappedStack), wrappedStack); - } - } - - /** - * Finalize the stack to value map - */ - ImmutableSortedMap.Builder stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); - stackMappingsBuilder.putAll(stackValueMap); - stackMappings = stackMappingsBuilder.build(); - - /** - * Value map resolution - */ - generateValueStackMappings(); - - // Serialize values to disk - LogHelper.info(ENERGY_VALUE_MARKER, "Saving energy values to disk"); - save(); - - // TODO Make this make "sense" and also ensure it's added as an option to the debug command - for (WrappedStack wrappedStack : uncomputedStacks) - { - if (!hasEnergyValue(wrappedStack)) - { - LogHelper.info(ENERGY_VALUE_MARKER, "Unable to compute a value for object '{}'", wrappedStack); - } - } - } - - private void generateValueStackMappings() - { - SortedMap> tempValueMappings = new TreeMap>(); - - for (WrappedStack stack : stackMappings.keySet()) - { - if (stack != null) - { - EnergyValue value = stackMappings.get(stack); - - if (value != null) - { - if (tempValueMappings.containsKey(value)) - { - if (!(tempValueMappings.get(value).contains(stack))) - { - tempValueMappings.get(value).add(stack); - } - } - else - { - tempValueMappings.put(value, new ArrayList(Arrays.asList(stack))); - } - } - } - } - valueMappings = ImmutableSortedMap.copyOf(tempValueMappings); - } - - private Map computeStackMappings(Map stackValueMappings, int passCount) - { - Map computedStackMap = new TreeMap(); - - for (WrappedStack recipeOutput : RecipeRegistry.getInstance().getRecipeMappings().keySet()) - { - // TODO Review: possible fault in the logic here that is preventing some values from being assigned? - if (!hasEnergyValue(recipeOutput.getWrappedObject(), false) && !computedStackMap.containsKey(recipeOutput)) - { - EnergyValue lowestValue = null; - - for (List recipeInputs : RecipeRegistry.getInstance().getRecipeMappings().get(recipeOutput)) - { - EnergyValue computedValue = NewEnergyValueRegistry.computeFromInputs(stackValueMappings, recipeOutput, recipeInputs); - - if (computedValue != null) - { - if (computedValue.compareTo(lowestValue) < 0) - { - lowestValue = computedValue; - } - } - else - { - if (uncomputedStacks == null) - { - uncomputedStacks = new TreeSet(); - } - - uncomputedStacks.add(recipeOutput); - } - } - - if ((lowestValue != null) && (lowestValue.getValue() > 0f)) - { - computedStackMap.put(WrappedStack.wrap(recipeOutput.getWrappedObject()), lowestValue); - } - } - } - - return computedStackMap; - } - - public List getStacksInRange(int start, int finish) - { + /** + * TODO Finish JavaDoc + * + * @param start + * @param finish + * @return + */ + public List getStacksInRange(Number start, Number finish) { return getStacksInRange(new EnergyValue(start), new EnergyValue(finish)); } - public List getStacksInRange(float start, float finish) - { - return getStacksInRange(new EnergyValue(start), new EnergyValue(finish)); - } + /** + * TODO Finish JavaDoc + * + * @param start + * @param finish + * @return + */ + public List getStacksInRange(EnergyValue start, EnergyValue finish) { - public List getStacksInRange(EnergyValue start, EnergyValue finish) - { List stacksInRange = new ArrayList(); - if (valueMappings != null) - { - SortedMap> tailMap = energyValueRegistry.valueMappings.tailMap(start); - SortedMap> headMap = energyValueRegistry.valueMappings.headMap(finish); + if (valueStackMap != null) { + + SortedMap> tailMap = valueStackMap.tailMap(start); + SortedMap> headMap = valueStackMap.headMap(finish); SortedMap> smallerMap; SortedMap> biggerMap; - if (!tailMap.isEmpty() && !headMap.isEmpty()) - { + if (!tailMap.isEmpty() && !headMap.isEmpty()) { - if (tailMap.size() <= headMap.size()) - { + if (tailMap.size() <= headMap.size()) { smallerMap = tailMap; biggerMap = headMap; } - else - { + else { smallerMap = headMap; biggerMap = tailMap; } - for (EnergyValue value : smallerMap.keySet()) - { - if (biggerMap.containsKey(value)) - { - for (WrappedStack wrappedStack : energyValueRegistry.valueMappings.get(value)) - { - if (wrappedStack.getWrappedObject() instanceof ItemStack || wrappedStack.getWrappedObject() instanceof FluidStack) - { + 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) - { + else if (wrappedStack.getWrappedObject() instanceof OreStack) { stacksInRange.addAll(OreDictionary.getOres(((OreStack) wrappedStack.getWrappedObject()).oreName)); } } @@ -640,190 +454,305 @@ public class EnergyValueRegistry implements JsonSerializer, return stacksInRange; } - public void loadFromMap(Map stackValueMap) { - if (stackValueMap != null) { - ImmutableSortedMap.Builder stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); - stackMappingsBuilder.putAll(stackValueMap); - stackMappings = stackMappingsBuilder.build(); + /** + * 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 + * energy value map to be recomputed to take into account the new mapping. + * + * @param object the object the energy value is being assigned for + * @param energyValue the energy value being setEnergyValue on the object + * @param phase the {@link Phase} of energy value assignment to set this value for + */ + public void setEnergyValue(Object object, EnergyValue energyValue, Phase phase) { + setEnergyValue(object, energyValue, phase, false); + } - /** - * Resolve value stack mappings from the newly loaded stack mappings - */ - generateValueStackMappings(); + /** + * 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 + * energy value map to be recomputed to take into account the new mapping. + * + * @param object the object the energy value is being assigned for + * @param energyValue the energy value being setEnergyValue on the object + * @param phase the {@link Phase} of energy value assignment to set this value for + * @param doRegenValues whether or not the energy value map needs recomputing. Only an option if the energy value + * is being assigned in the PRE_CALCULATION phase + */ + public void setEnergyValue(Object object, EnergyValue energyValue, Phase phase, boolean doRegenValues) { + + if (WrappedStack.canBeWrapped(object) && energyValue != null && Float.compare(energyValue.getValue(), 0f) > 0) { + + WrappedStack wrappedStack = WrappedStack.wrap(object, 1); + EnergyValue factoredEnergyValue = EnergyValue.factor(energyValue, wrappedStack.getStackSize()); + + if (phase == Phase.PRE_CALCULATION) { + if (!FMLCommonHandler.instance().bus().post(new EnergyValueEvent.SetEnergyValueEvent(wrappedStack, factoredEnergyValue, Phase.PRE_CALCULATION))) { + + preCalculationStackValueMap.put(wrappedStack, factoredEnergyValue); + + if (doRegenValues) { + compute(); + } + } + } + else if (!FMLCommonHandler.instance().bus().post(new EnergyValueEvent.SetEnergyValueEvent(wrappedStack, factoredEnergyValue, Phase.POST_CALCULATION))) { + + TreeMap valueMap = new TreeMap<>(stackValueMap); + valueMap.put(wrappedStack, energyValue); + ImmutableSortedMap.Builder stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); + stackValueMap = stackMappingsBuilder.putAll(valueMap).build(); + + postCalculationStackValueMap.put(wrappedStack, factoredEnergyValue); + } + + if (ConfigurationHandler.Settings.energyValueDebugLoggingEnabled) { + LogHelper.info(ENERGY_VALUE_MARKER, "[{}] Mod '{}' set a {} value of {} on object '{}' with doRegen = {}", LoaderHelper.getLoaderState(), Loader.instance().activeModContainer().getModId(), phase, energyValue, wrappedStack, doRegenValues); + } } } - public void setEnergyValue(WrappedStack wrappedStack, EnergyValue energyValue) { - if (wrappedStack != null && energyValue != null && Float.compare(energyValue.getValue(), 0f) > 0) { - TreeMap stackValueMap = new TreeMap(stackMappings); - stackValueMap.put(wrappedStack, energyValue); + /** + * TODO Finish JavaDoc + * + * This is where the magic happens + */ + public void compute() { - ImmutableSortedMap.Builder stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); - stackMappingsBuilder.putAll(stackValueMap); - stackMappings = stackMappingsBuilder.build(); + // Initialize the "working copy" energy value map + final Map stackValueMap = new TreeMap<>(); + uncomputedStacks = new TreeSet<>(); - generateValueStackMappings(); + // Add in all pre-calculation energy value mappings + preCalculationStackValueMap.keySet().stream() + .filter(wrappedStack -> wrappedStack != null && wrappedStack.getWrappedObject() != null && preCalculationStackValueMap.get(wrappedStack) != null) + .forEach(wrappedStack -> stackValueMap.put(wrappedStack, preCalculationStackValueMap.get(wrappedStack))); + + // Calculate values from the known methods to create items, and the pre-calculation value mappings + stackValueMap.putAll(calculateStackValueMap(stackValueMap)); + + // Add in all post-calculation energy value mappings + postCalculationStackValueMap.keySet().stream() + .filter(wrappedStack -> wrappedStack != null && wrappedStack.getWrappedObject() != null && postCalculationStackValueMap.get(wrappedStack) != null) + .forEach(wrappedStack -> stackValueMap.put(wrappedStack, postCalculationStackValueMap.get(wrappedStack))); + + // Bake the final calculated energy value maps + ImmutableSortedMap.Builder stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); + stackMappingsBuilder.putAll(stackValueMap); + this.stackValueMap = stackMappingsBuilder.build(); + calculateValueStackMap(); + + // Save the results to disk + save(); + } + + /** + * + * @param stackValueMap + * @return + */ + private Map calculateStackValueMap(Map stackValueMap) { + + LogHelper.info(ENERGY_VALUE_MARKER, "Beginning energy value calculation"); + long startingTime = System.nanoTime(); + + Map computedMap = new TreeMap<>(stackValueMap); + Map tempComputedMap = new TreeMap<>(); + int passNumber = 0; + + while ((passNumber == 0 || tempComputedMap.size() != computedMap.size()) && passNumber < 16) { + + long passStartTime = System.nanoTime(); + passNumber++; + computedMap.putAll(tempComputedMap); + + tempComputedMap = new TreeMap<>(computedMap); + for (WrappedStack recipeOutput : RecipeRegistry.getInstance().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 (List recipeInputs : RecipeRegistry.getInstance().getRecipeMappings().get(recipeOutput)) { + + EnergyValue currentOutputValue = getEnergyValue(tempComputedMap, WrappedStack.wrap(recipeOutput, 1), false); + EnergyValue computedOutputValue = computeFromInputs(tempComputedMap, recipeOutput, recipeInputs); + + if (computedOutputValue != null && computedOutputValue.compareTo(currentOutputValue) < 0) { + + uncomputedStacks.removeIf(wrappedStack -> uncomputedStacks.contains(WrappedStack.wrap(recipeOutput, 1))); + + if (ConfigurationHandler.Settings.energyValueDebugLoggingEnabled) { + LogHelper.info(ENERGY_VALUE_MARKER, "Pass {}: Calculated value {} for object {}", passNumber, computedOutputValue, recipeOutput); + } + + tempComputedMap.put(WrappedStack.wrap(recipeOutput), computedOutputValue); + } + else if (computedOutputValue != null) { + uncomputedStacks.add(WrappedStack.wrap(recipeOutput, 1)); + } + } + } + } + + long passDuration = System.nanoTime() - passStartTime; + if (ConfigurationHandler.Settings.energyValueDebugLoggingEnabled) { + LogHelper.info(ENERGY_VALUE_MARKER, "Pass {}: Calculated {} values for objects in {} ms", passNumber, tempComputedMap.size(), passDuration / 100000); + } } + long endingTime = System.nanoTime() - startingTime; + LogHelper.info(ENERGY_VALUE_MARKER, "Finished energy value calculation - calculated {} values for objects in {} ms", computedMap.size() - stackValueMap.size(), endingTime / 100000); + + return computedMap; } - public boolean getShouldRegenNextRestart() { - return shouldRegenNextRestart; - } - - public void setShouldRegenNextRestart(boolean shouldRegenNextRestart) { - this.shouldRegenNextRestart = shouldRegenNextRestart; - } - - public ImmutableSortedMap getStackValueMap() { - return stackMappings; - } - - public ImmutableSortedMap> getValueStackMap() { - return valueMappings; + private void calculateValueStackMap() { + + SortedMap> tempValueMap = new TreeMap<>(); + + for (WrappedStack wrappedStack : getEnergyValues().keySet()) { + + if (wrappedStack != null) { + + EnergyValue energyValue = getEnergyValues().get(wrappedStack); + + if (energyValue != null) { + if (tempValueMap.containsKey(energyValue)) { + if (!(tempValueMap.get(energyValue).contains(wrappedStack))) { + tempValueMap.get(energyValue).add(wrappedStack); + } + } + else { + tempValueMap.put(energyValue, new ArrayList<>(Arrays.asList(wrappedStack))); + } + } + } + } + valueStackMap = ImmutableSortedMap.copyOf(tempValueMap); } + /** + * Saves the pre-calculation, post-calculation, and calculated energy value maps to disk + */ public void save() { - File energyValuesDataDirectory = new File(FMLCommonHandler.instance().getMinecraftServerInstance().getEntityWorld().getSaveHandler().getWorldDirectory(), "data" + File.separator + Reference.LOWERCASE_MOD_ID + File.separator + "energyvalues"); - energyValuesDataDirectory.mkdirs(); + /** + * If the current values were synched to us from a server, do not save them to disk as they would override + * the local ones + */ + if (!loadedFromMap) { + writeToJsonFile(stackValueMap, energyValuesFile); + } + writeToJsonFile(preCalculationStackValueMap, preCalculationValuesFile); + writeToJsonFile(postCalculationStackValueMap, postCalculationValuesFile); + } - if (shouldRegenNextRestart) { - File staticEnergyValuesJsonFile = new File(energyValuesDataDirectory, Files.ENERGY_VALUES_JSON); - File md5EnergyValuesJsonFile = new File(energyValuesDataDirectory, SerializationHelper.getModListMD5() + ".json"); + /** + * Loads the pre-calculation, post-calculation, and calculated energy value maps from disk. In the event that either + * the pre/post calculation maps can not be loaded from disk they will be initialized as empty maps. If the + * calculated energy value map can not be loaded from disk then the values will be computed from the pre/post + * calculation maps + */ + public void load() { - // JSON - if (staticEnergyValuesJsonFile.exists()) { - staticEnergyValuesJsonFile.delete(); - } - if (md5EnergyValuesJsonFile.exists()) { - md5EnergyValuesJsonFile.delete(); - } + try { + preCalculationStackValueMap.putAll(readFromJsonFile(preCalculationValuesFile)); + } catch (FileNotFoundException e) { + // TODO Log that no pre-calculation values were loaded from file because file wasn't found + } - shouldRegenNextRestart = false; - } else { - SerializationHelper.compressEnergyValueStackMapToFile(new File(energyValuesDataDirectory, Files.ENERGY_VALUES_JSON), energyValueRegistry.stackMappings); - SerializationHelper.compressEnergyValueStackMapToFile(new File(energyValuesDataDirectory, SerializationHelper.getModListMD5() + ".json.gz"), energyValueRegistry.stackMappings); + try { + postCalculationStackValueMap.putAll(readFromJsonFile(postCalculationValuesFile)); + } catch (FileNotFoundException e) { + // TODO Log that no post-calculation values were loaded from file because file wasn't found + } + + try { + ImmutableSortedMap.Builder stackMapBuilder = ImmutableSortedMap.naturalOrder(); + stackMapBuilder.putAll(readFromJsonFile(energyValuesFile)); + stackValueMap = stackMapBuilder.build(); + calculateValueStackMap(); + } catch (FileNotFoundException e) { + LogHelper.warn("No calculated energy value file found, regenerating"); // TODO Better log message + compute(); } } - public boolean loadFromFile(File energyValueFile) { - if (energyValueFile != null) { - LogHelper.info(ENERGY_VALUE_MARKER, "Attempting to load energy values from file: {}", energyValueFile.getAbsolutePath()); - } + /** + * + * + * @param valueMap + */ + public void load(Map valueMap){ - return false; - } - - public boolean loadEnergyValueRegistryFromFile() { - - File energyValuesDataDirectory = new File(FMLCommonHandler.instance().getMinecraftServerInstance().getEntityWorld().getSaveHandler().getWorldDirectory(), "data" + File.separator + Reference.LOWERCASE_MOD_ID + File.separator + "energyvalues"); - energyValuesDataDirectory.mkdirs(); - - File staticEnergyValuesFile = new File(energyValuesDataDirectory, Files.ENERGY_VALUES_JSON); - File md5EnergyValuesFile = new File(energyValuesDataDirectory, SerializationHelper.getModListMD5() + ".json.gz"); - - Map stackValueMap = null; - - loadFromFile(new File(Files.Global.dataDirectory, Files.ENERGY_VALUES_JSON)); - - if (!ConfigurationHandler.Settings.regenerateEnergyValuesWhen.equalsIgnoreCase("Always")) { - if (ConfigurationHandler.Settings.regenerateEnergyValuesWhen.equalsIgnoreCase("When Mods Change")) { - if (md5EnergyValuesFile.exists()) { - LogHelper.info(ENERGY_VALUE_MARKER, "Attempting to load energy values from file: {}", md5EnergyValuesFile.getAbsolutePath()); - stackValueMap = SerializationHelper.decompressEnergyValueStackMapFromFile(md5EnergyValuesFile); - } - } else if (ConfigurationHandler.Settings.regenerateEnergyValuesWhen.equalsIgnoreCase("Never")) { - if (staticEnergyValuesFile.exists()) { - LogHelper.info(ENERGY_VALUE_MARKER, "Attempting to load energy values from file: {}", staticEnergyValuesFile.getAbsolutePath()); - stackValueMap = SerializationHelper.decompressEnergyValueStackMapFromFile(staticEnergyValuesFile); - } else if (md5EnergyValuesFile.exists()) { - LogHelper.info(ENERGY_VALUE_MARKER, "Attempting to load energy values from file: {}", md5EnergyValuesFile.getAbsolutePath()); - stackValueMap = SerializationHelper.decompressEnergyValueStackMapFromFile(md5EnergyValuesFile); - } - } - - if (stackValueMap != null) { - loadFromMap(stackValueMap); - LogHelper.info(ENERGY_VALUE_MARKER, "Successfully loaded energy values from file"); - return true; - } else { - LogHelper.info(ENERGY_VALUE_MARKER, "No energy value file to load values from, generating new values"); - return false; - } - } else { - return false; - } - } - - public String toJson() - { - return JSON_SERIALIZER.toJson(this); - } - - @Override - public EnergyValueRegistry deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - - if (json.isJsonArray()) { - JsonArray jsonArray = (JsonArray) json; - Map stackValueMap = new TreeMap(); - Iterator iterator = jsonArray.iterator(); - - while (iterator.hasNext()) { - JsonElement jsonElement = iterator.next(); - EnergyValueStackMapping energyValueStackMapping = new EnergyValueStackMapping().deserialize(jsonElement, typeOfT, context); - - if (energyValueStackMapping != null) { - stackValueMap.put(energyValueStackMapping.wrappedStack, energyValueStackMapping.energyValue); - } - } + if (stackValueMap != null) { + loadedFromMap = true; ImmutableSortedMap.Builder stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); - stackMappingsBuilder.putAll(stackValueMap); - stackMappings = stackMappingsBuilder.build(); - - generateValueStackMappings(); + stackMappingsBuilder.putAll(valueMap); + stackValueMap = stackMappingsBuilder.build(); + calculateValueStackMap(); } - - return null; } - @Override - public JsonElement serialize(EnergyValueRegistry energyValueRegistry, Type typeOfSrc, JsonSerializationContext context) { + /** + * @see net.minecraft.nbt.CompressedStreamTools#safeWrite(NBTTagCompound, File) + */ + private static void writeToJsonFile(Map valueMap, File file) { - JsonArray jsonEnergyValueRegistry = new JsonArray(); + File tempFile = new File(file.getAbsolutePath() + "_tmp"); - if (energyValueRegistry != null && energyValueRegistry.stackMappings != null) { - for (WrappedStack wrappedStack : energyValueRegistry.stackMappings.keySet()) { - jsonEnergyValueRegistry.add(EnergyValueStackMapping.jsonSerializer.toJsonTree(new EnergyValueStackMapping(wrappedStack, energyValueRegistry.stackMappings.get(wrappedStack)))); + if (tempFile.exists()) { + tempFile.delete(); + } + + try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(tempFile))) { + + bufferedWriter.write(SerializationHelper.GSON.toJson(valueMap, SerializationHelper.ENERGY_VALUE_MAP_TYPE)); + bufferedWriter.close(); + } + catch (IOException exception) { + exception.printStackTrace(); // TODO Better logging of the exception + } + + if (file.exists()) { + file.delete(); + } + + if (file.exists()) { + LogHelper.warn("Failed to delete " + file); + } + else { + tempFile.renameTo(file); + } + } + + private static Map readFromJsonFile(File file) throws FileNotFoundException { + + Map valueMap = new TreeMap<>(); + + StringBuilder jsonStringBuilder = new StringBuilder(); + try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) { + + jsonStringBuilder = new StringBuilder(); + String line; + while ((line = bufferedReader.readLine()) != null) { + jsonStringBuilder.append(line); + } + } + catch (IOException exception) { + if (exception instanceof FileNotFoundException) { + throw (FileNotFoundException) exception; + } + else { + exception.printStackTrace(); // TODO Better logging of the exception (other) } } - return jsonEnergyValueRegistry; - } - - public void dumpEnergyValueRegistryToLog() { - - dumpEnergyValueRegistryToLog(EnergyValueRegistryProxy.Phase.ALL); - } - - public void dumpEnergyValueRegistryToLog(EnergyValueRegistryProxy.Phase phase) { - - LogHelper.info(ENERGY_VALUE_MARKER, "BEGIN DUMPING {} ENERGY VALUE MAPPINGS", phase); - if (phase == EnergyValueRegistryProxy.Phase.PRE_ASSIGNMENT || phase == EnergyValueRegistryProxy.Phase.PRE_CALCULATION) { - for (WrappedStack wrappedStack : this.preCalculationMappings.keySet()) { - LogHelper.info(ENERGY_VALUE_MARKER, "Object: {}, Value: {}", wrappedStack, EnergyValueRegistry.getInstance().getStackValueMap().get(wrappedStack)); - } - } else if (phase == EnergyValueRegistryProxy.Phase.POST_ASSIGNMENT || phase == EnergyValueRegistryProxy.Phase.POST_CALCULATION) { - if (this.postCalculationMappings != null) { - for (WrappedStack wrappedStack : this.postCalculationMappings.keySet()) { - LogHelper.info(ENERGY_VALUE_MARKER, "Object: {}, Value: {}", wrappedStack, EnergyValueRegistry.getInstance().getStackValueMap().get(wrappedStack)); - } - } - } else if (phase == EnergyValueRegistryProxy.Phase.ALL) { - for (WrappedStack wrappedStack : EnergyValueRegistry.getInstance().getStackValueMap().keySet()) { - LogHelper.info(ENERGY_VALUE_MARKER, "Object: {}, Value: {}", wrappedStack, EnergyValueRegistry.getInstance().getStackValueMap().get(wrappedStack)); - } + try { + valueMap = SerializationHelper.GSON.fromJson(jsonStringBuilder.toString(), SerializationHelper.ENERGY_VALUE_MAP_TYPE); } - LogHelper.info(ENERGY_VALUE_MARKER, "END DUMPING {} ENERGY VALUE MAPPINGS", phase); + catch (JsonParseException exception) { + // TODO Better logging of the exception (failed parsing so no values loaded) + } + + return valueMap; } } diff --git a/src/main/java/com/pahimar/ee3/exchange/EnergyValueStackMapping.java b/src/main/java/com/pahimar/ee3/exchange/EnergyValueStackMapping.java index 23296b94..b7bfed6b 100644 --- a/src/main/java/com/pahimar/ee3/exchange/EnergyValueStackMapping.java +++ b/src/main/java/com/pahimar/ee3/exchange/EnergyValueStackMapping.java @@ -5,6 +5,7 @@ import com.pahimar.ee3.api.exchange.EnergyValue; import java.lang.reflect.Type; +@Deprecated public class EnergyValueStackMapping implements JsonSerializer, JsonDeserializer { public static final Gson jsonSerializer = (new GsonBuilder()).setPrettyPrinting().registerTypeAdapter(EnergyValueStackMapping.class, new EnergyValueStackMapping()).registerTypeAdapter(EnergyValue.class, new EnergyValue()).registerTypeAdapter(WrappedStack.class, new WrappedStack()).create(); diff --git a/src/main/java/com/pahimar/ee3/exchange/JsonFluidStack.java b/src/main/java/com/pahimar/ee3/exchange/JsonFluidStack.java index f087f0b3..2878dc6a 100644 --- a/src/main/java/com/pahimar/ee3/exchange/JsonFluidStack.java +++ b/src/main/java/com/pahimar/ee3/exchange/JsonFluidStack.java @@ -11,6 +11,7 @@ import net.minecraftforge.fluids.FluidStack; import java.lang.reflect.Type; +@Deprecated public class JsonFluidStack implements JsonSerializer, JsonDeserializer { public static final Gson jsonSerializer = (new GsonBuilder()).registerTypeAdapter(JsonFluidStack.class, new JsonFluidStack()).create(); diff --git a/src/main/java/com/pahimar/ee3/exchange/JsonItemStack.java b/src/main/java/com/pahimar/ee3/exchange/JsonItemStack.java index 1be32f20..7c60ba02 100644 --- a/src/main/java/com/pahimar/ee3/exchange/JsonItemStack.java +++ b/src/main/java/com/pahimar/ee3/exchange/JsonItemStack.java @@ -10,6 +10,7 @@ import net.minecraft.nbt.NBTTagCompound; import java.lang.reflect.Type; +@Deprecated public class JsonItemStack implements JsonSerializer, JsonDeserializer { public static final Gson jsonSerializer = (new GsonBuilder()).registerTypeAdapter(JsonItemStack.class, new JsonItemStack()).create(); diff --git a/src/main/java/com/pahimar/ee3/exchange/NewEnergyValueRegistry.java b/src/main/java/com/pahimar/ee3/exchange/NewEnergyValueRegistry.java deleted file mode 100644 index 4032053a..00000000 --- a/src/main/java/com/pahimar/ee3/exchange/NewEnergyValueRegistry.java +++ /dev/null @@ -1,726 +0,0 @@ -package com.pahimar.ee3.exchange; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSortedMap; -import com.google.gson.JsonParseException; -import com.pahimar.ee3.api.event.EnergyValueEvent; -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.util.LogHelper; -import com.pahimar.ee3.util.SerializationHelper; -import cpw.mods.fml.common.FMLCommonHandler; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -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; - -import java.io.*; -import java.util.*; - -import static com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy.Phase; - -public class NewEnergyValueRegistry { - - public static final NewEnergyValueRegistry INSTANCE = new NewEnergyValueRegistry(); - - private ImmutableSortedMap stackValueMap; - private ImmutableSortedMap> valueStackMap; - - private final Map preCalculationStackValueMap; - private final Map postCalculationStackValueMap; - private transient SortedSet uncomputedStacks; - - public static File energyValuesDirectory; - public static File energyValuesFile; - public static File preCalculationValuesFile; - public static File postCalculationValuesFile; - - public static final Marker ENERGY_VALUE_MARKER = MarkerManager.getMarker("EE3_ENERGY_VALUE", LogHelper.MOD_MARKER); - - private NewEnergyValueRegistry() { - - ImmutableSortedMap.Builder stackMapBuilder = ImmutableSortedMap.naturalOrder(); - stackValueMap = stackMapBuilder.build(); - - preCalculationStackValueMap = new TreeMap<>(); - postCalculationStackValueMap = new TreeMap<>(); - uncomputedStacks = new TreeSet<>(); - } - - /** - * Returns an {@link EnergyValue} for a {@link Object} in the provided {@link Map>} of {@link WrappedStack}s mapped - * to EnergyValues - * - *

The order of checking is as follows;

- *
    - *
  1. {@link ItemStack}s whose {@link Item}s implement {@link IEnergyValueProvider}
  2. - *
  3. Direct EnergyValue mapping of the provided Object in the provided Map
  4. - *
  5. The following criteria are only checked (in order) in the event that this is a non-strict query; - *
      - *
    1. - * ItemStacks that are part of an {@link OreDictionary} entry are checked to see if - * all Ores they are registered to have the same non-null EnergyValue assigned to - * it - *
        - *
      • - * e.g., ItemStack X is associated with OreDictionary entries A, B and C. An EnergyValue - * would be returned for X only if A, B and C all had the same non-null EnergyValue - *
      • - *
      - *
    2. - *
    3. - * ItemStacks are checked to see if there exist {@link OreDictionary#WILDCARD_VALUE} equivalents - *
    4. - *
    5. - * {@link OreStack}s are checked to see if all members of the OreDictionary entry represented by the - * OreStack have the same non-null EnergyValue (similar to the case for ItemStacks above) - *
    6. - *
    - *
  6. - *
- * - * @param valueMap a {@link Map} of {@link EnergyValue}'s mapped to {@link WrappedStack}'s - * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} - * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value - * 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 valueMap, Object object, boolean strict) { - - if (WrappedStack.canBeWrapped(object)) { - - WrappedStack wrappedStack = WrappedStack.wrap(object, 1); - Object wrappedObject = wrappedStack.getWrappedObject(); - - if (wrappedObject instanceof ItemStack && ((ItemStack) wrappedObject).getItem() instanceof IEnergyValueProvider && !strict) { - - EnergyValue energyValue = ((IEnergyValueProvider) ((ItemStack) wrappedObject).getItem()).getEnergyValue(((ItemStack) wrappedObject)); - - if (energyValue != null && Float.compare(energyValue.getValue(), 0f) > 0) { - return energyValue; - } - } - - if (valueMap != null && !valueMap.isEmpty()) { - - // First check for a direct energy value mapping to the wrapped object - if (valueMap.containsKey(wrappedStack)) { - return valueMap.get(wrappedStack); - } - else if (!strict) { - - if (wrappedObject instanceof ItemStack) { - - ItemStack unValuedItemStack = ItemStack.copyItemStack((ItemStack) wrappedObject); - EnergyValue minEnergyValue = null; - - int[] oreIds = OreDictionary.getOreIDs(unValuedItemStack); - if (oreIds.length > 0) { - - EnergyValue energyValue = null; - boolean allHaveSameValue = true; - - for (int oreId : oreIds) { - String oreName = OreDictionary.getOreName(oreId); - - if (!"Unknown".equalsIgnoreCase(oreName)) { - - WrappedStack oreStack = WrappedStack.wrap(new OreStack(oreName)); - - if (oreStack != null && valueMap.containsKey(oreStack)) { - - if (energyValue == null) { - energyValue = valueMap.get(oreStack); - } - else if (!energyValue.equals(valueMap.get(oreStack))) { - allHaveSameValue = false; - } - } - else { - allHaveSameValue = false; - } - } - else { - allHaveSameValue = false; - } - } - - if (allHaveSameValue) { - return energyValue; - } - } - else { - for (WrappedStack valuedWrappedStack : valueMap.keySet()) { - if (valuedWrappedStack.getWrappedObject() instanceof ItemStack) { - if (Item.getIdFromItem(((ItemStack) valuedWrappedStack.getWrappedObject()).getItem()) == Item.getIdFromItem(unValuedItemStack.getItem())) { - - ItemStack valuedItemStack = (ItemStack) valuedWrappedStack.getWrappedObject(); - if (valuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE || unValuedItemStack.getItemDamage() == OreDictionary.WILDCARD_VALUE) { - - EnergyValue energyValue = valueMap.get(valuedWrappedStack); - - if (energyValue.compareTo(minEnergyValue) < 0) { - minEnergyValue = energyValue; - } - } - } - } - } - } - } - else if (wrappedObject instanceof OreStack) { - - OreStack oreStack = (OreStack) wrappedObject; - List itemStacks = OreDictionary.getOres(oreStack.oreName); - - if (!itemStacks.isEmpty()) { - - EnergyValue energyValue = null; - boolean allHaveSameValue = true; - - for (ItemStack itemStack : itemStacks) { - WrappedStack wrappedItemStack = WrappedStack.wrap(itemStack, 1); - - if (wrappedItemStack != null && valueMap.containsKey(wrappedItemStack)) { - if (energyValue == null) { - energyValue = valueMap.get(wrappedItemStack); - } - else if (!energyValue.equals(valueMap.get(wrappedItemStack))) { - allHaveSameValue = false; - } - } - else { - allHaveSameValue = false; - } - } - - if (allHaveSameValue) { - return energyValue; - } - } - } - } - } - } - - return null; - } - - /** - * Calculates an {@link EnergyValue} for the provided {@link WrappedStack} output from the provided {@link List} of - * WrappedStack inputs and {@link Map} of energy value mappings to objects. We calculate the energy value for the - * output by, for each input, summing the input's energy value * the input's stack size. That sum is then divided - * by the stack size of the output. If any of the inputs do not have an energy value then no - * energy value can be calculated for the output - therefore we return null - * - * @param valueMap a {@link Map} of {@link EnergyValue}'s mapped to {@link WrappedStack}'s - * @param wrappedOutput the {@link WrappedStack} output for that the inputs "create" - * @param wrappedInputs a {@link List} of {@link WrappedStack}s that "create" the output - * @return an {@link EnergyValue} if there is one that can be calculated, null otherwise - */ - // TODO Make this private when EnergyValueRegistry is properly replaced - public static EnergyValue computeFromInputs(Map valueMap, WrappedStack wrappedOutput, List wrappedInputs) { - - float sumOfValues = 0f; - - for (WrappedStack wrappedInput : wrappedInputs) { - - EnergyValue inputValue; - int stackSize = Integer.MIN_VALUE; - - if (wrappedInput.getWrappedObject() instanceof ItemStack) { - - ItemStack inputItemStack = (ItemStack) wrappedInput.getWrappedObject(); - - // Check if we are dealing with a potential fluid - if (FluidContainerRegistry.getFluidForFilledItem(inputItemStack) != null) { - - if (inputItemStack.getItem().getContainerItem(inputItemStack) != null) { - stackSize = FluidContainerRegistry.getFluidForFilledItem(inputItemStack).amount * wrappedInput.getStackSize(); - inputValue = getEnergyValue(valueMap, FluidContainerRegistry.getFluidForFilledItem(inputItemStack), false); - } - else { - inputValue = getEnergyValue(valueMap, wrappedInput, false); - } - } - else if (inputItemStack.getItem().getContainerItem(inputItemStack) != null) { - - ItemStack inputContainerItemStack = inputItemStack.getItem().getContainerItem(inputItemStack); - - if (getEnergyValue(valueMap, inputItemStack, false) != null && getEnergyValue(valueMap, inputContainerItemStack, false) != null) { - float itemStackValue = getEnergyValue(valueMap, inputItemStack, false).getValue(); - float containerStackValue = getEnergyValue(valueMap, inputContainerItemStack, false).getValue(); - inputValue = new EnergyValue(itemStackValue - containerStackValue); - } - else { - inputValue = new EnergyValue(0); - } - } - else if (!inputItemStack.getItem().doesContainerItemLeaveCraftingGrid(inputItemStack)) { - inputValue = new EnergyValue(0); - } - else if (OreDictionary.getOreIDs(inputItemStack).length > 0) { - inputValue = getEnergyValue(valueMap, wrappedInput, true); - } - else { - inputValue = getEnergyValue(valueMap, wrappedInput, false); - } - } - else if (wrappedInput.getWrappedObject() instanceof OreStack) { - - OreStack inputOreStack = (OreStack) wrappedInput.getWrappedObject(); - inputValue = getEnergyValue(valueMap, wrappedInput, false); - for (ItemStack itemStack : OreDictionary.getOres(inputOreStack.oreName)) { - if (!itemStack.getItem().doesContainerItemLeaveCraftingGrid(itemStack)) { - inputValue = new EnergyValue(0); - } - } - } - else { - inputValue = getEnergyValue(valueMap, wrappedInput, false); - } - - if (inputValue != null) { - - if (stackSize == Integer.MIN_VALUE) { - stackSize = wrappedInput.getStackSize(); - } - - sumOfValues += inputValue.getValue() * stackSize; - } - else { - return null; - } - } - - return EnergyValue.factor(new EnergyValue(sumOfValues), wrappedOutput.getStackSize()); - } - - /** - * Returns an {@link ImmutableMap} containing the current energy value mappings - * - * @return an {@link ImmutableMap} containing the current energy value mappings - */ - public ImmutableMap getEnergyValues() { - return stackValueMap; - } - - /** - * Returns a {@link Map} containing the pre-calculation energy value mappings - * - * @return a {link Map} containing the pre-calculation energy value mappings - */ - public Map getPreCalculationStackValueMap() { - return preCalculationStackValueMap; - } - - /** - * Returns a {@link Map} containing the post-calculation energy value mappings - * - * @return a {@link Map} containing the post-calculation energy value mappings - */ - public Map getPostCalculationStackValueMap() { - return postCalculationStackValueMap; - } - - /** - * Checks if there exists an {@link EnergyValue} associated with the provided {@link Object}. - * - * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} - * @return true if the provided object has an energy value, false otherwise - */ - public boolean hasEnergyValue(Object object) { - return hasEnergyValue(object, false); - } - - /** - * Checks if there exists an {@link EnergyValue} associated with the provided {@link Object} - * - * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} - * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value - * assignments) query or not - * @return true if the provided object has an energy value, false otherwise - */ - public boolean hasEnergyValue(Object object, boolean strict) { - return getEnergyValue(object, strict) != null; - } - - /** - * Returns an {@link EnergyValue} associated with the provided {@link Object} (if there is one) - * - * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} - * @return an {@link EnergyValue} if there is one to be found, null otherwise - */ - public EnergyValue getEnergyValue(Object object) { - return getEnergyValue(object, false); - } - - /** - * Returns an {@link EnergyValue} associated with the provided {@link Object} (if there is one) - * - * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} - * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value - * assignments) query or not - * @return an {@link EnergyValue} if there is one to be found, null otherwise - */ - public EnergyValue getEnergyValue(Object object, boolean strict) { - return getEnergyValue(stackValueMap, object, strict); - } - - /** - * Returns an {@link EnergyValue} associated with the provided {@link Object} (if there is one) - * - * @param object the {@link Object} that is being checked for a corresponding {@link EnergyValue} - * @param strict whether this is a strict (e.g., only looking for direct value assignment vs associative value - * assignments) query or not - * @return an {@link EnergyValue} if there is one to be found, null otherwise - */ - public EnergyValue getEnergyValueForStack(Object object, boolean strict) { - - WrappedStack wrappedObject = WrappedStack.wrap(object); - - if (wrappedObject != null && getEnergyValue(object, strict) != null) { - return new EnergyValue(getEnergyValue(object, strict).getValue() * wrappedObject.getStackSize()); - } - - return null; - } - - /** - * TODO Finish JavaDoc - * - * @param start - * @param finish - * @return - */ - public List getStacksInRange(Number start, Number finish) { - return getStacksInRange(new EnergyValue(start), new EnergyValue(finish)); - } - - /** - * TODO Finish JavaDoc - * - * @param start - * @param finish - * @return - */ - public List getStacksInRange(EnergyValue start, EnergyValue finish) { - - List stacksInRange = new ArrayList(); - - if (valueStackMap != null) { - - SortedMap> tailMap = valueStackMap.tailMap(start); - SortedMap> headMap = valueStackMap.headMap(finish); - - SortedMap> smallerMap; - SortedMap> biggerMap; - - if (!tailMap.isEmpty() && !headMap.isEmpty()) { - - if (tailMap.size() <= headMap.size()) { - smallerMap = tailMap; - biggerMap = headMap; - } - 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 stacksInRange; - } - - /** - * 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 - * energy value map to be recomputed to take into account the new mapping. - * - * @param object the object the energy value is being assigned for - * @param energyValue the energy value being setEnergyValue on the object - * @param phase the {@link Phase} of energy value assignment to set this value for - */ - public void setEnergyValue(Object object, EnergyValue energyValue, Phase phase) { - setEnergyValue(object, energyValue, phase, false); - } - - /** - * 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 - * energy value map to be recomputed to take into account the new mapping. - * - * @param object the object the energy value is being assigned for - * @param energyValue the energy value being setEnergyValue on the object - * @param phase the {@link Phase} of energy value assignment to set this value for - * @param doRegenValues whether or not the energy value map needs recomputing. Only an option if the energy value - * is being assigned in the PRE_CALCULATION phase - */ - public void setEnergyValue(Object object, EnergyValue energyValue, Phase phase, boolean doRegenValues) { - - if (WrappedStack.canBeWrapped(object) && energyValue != null && Float.compare(energyValue.getValue(), 0f) > 0) { - - WrappedStack wrappedStack = WrappedStack.wrap(object, 1); - EnergyValue factoredEnergyValue = EnergyValue.factor(energyValue, wrappedStack.getStackSize()); - - if (phase == Phase.PRE_CALCULATION) { - if (!FMLCommonHandler.instance().bus().post(new EnergyValueEvent.SetEnergyValueEvent(wrappedStack, factoredEnergyValue, Phase.PRE_CALCULATION))) { - - preCalculationStackValueMap.put(wrappedStack, factoredEnergyValue); - - if (doRegenValues) { - compute(); - } - } - } - else if (!FMLCommonHandler.instance().bus().post(new EnergyValueEvent.SetEnergyValueEvent(wrappedStack, factoredEnergyValue, Phase.POST_CALCULATION))) { - - TreeMap valueMap = new TreeMap<>(stackValueMap); - valueMap.put(wrappedStack, energyValue); - ImmutableSortedMap.Builder stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); - stackValueMap = stackMappingsBuilder.putAll(valueMap).build(); - - postCalculationStackValueMap.put(wrappedStack, factoredEnergyValue); - } - } - } - - /** - * This is where the magic happens - */ - public void compute() { - - // Initialize the "working copy" energy value map - TreeMap stackValueMap = new TreeMap<>(); - uncomputedStacks = new TreeSet<>(); - - // Add in all pre-calculation energy value mappings - preCalculationStackValueMap.keySet().stream() - .filter(wrappedStack -> wrappedStack != null && wrappedStack.getWrappedObject() != null && preCalculationStackValueMap.get(wrappedStack) != null) - .forEach(wrappedStack -> stackValueMap.put(wrappedStack, preCalculationStackValueMap.get(wrappedStack))); - - // Calculate values from the known methods to create items, and the pre-calculation value mappings - calculateStackValueMap(stackValueMap); - - // Add in all post-calculation energy value mappings - postCalculationStackValueMap.keySet().stream() - .filter(wrappedStack -> wrappedStack != null && wrappedStack.getWrappedObject() != null && postCalculationStackValueMap.get(wrappedStack) != null) - .forEach(wrappedStack -> stackValueMap.put(wrappedStack, postCalculationStackValueMap.get(wrappedStack))); - - // Bake the final calculated energy value maps - ImmutableSortedMap.Builder stackMappingsBuilder = ImmutableSortedMap.naturalOrder(); - stackMappingsBuilder.putAll(stackValueMap); - this.stackValueMap = stackMappingsBuilder.build(); - calculateValueStackMap(); - - // Save the results to disk - save(); - } - - private Map calculateStackValueMap(Map stackValueMap) { - - LogHelper.info(ENERGY_VALUE_MARKER, "Beginning energy value calculation"); - long startingTime = System.nanoTime(); - - Map computedMap = new TreeMap<>(stackValueMap); - Map tempComputedMap = new TreeMap<>(); - int passNumber = 0; - - while ((passNumber == 0 || tempComputedMap.size() != computedMap.size()) && passNumber < 16) { - - long passStartTime = System.nanoTime(); - passNumber++; - - /** - * @see EnergyValueRegistry#computeStackMappings(Map, int) - */ - tempComputedMap = new TreeMap<>(computedMap); - for (WrappedStack recipeOutput : RecipeRegistry.getInstance().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 (List recipeInputs : RecipeRegistry.getInstance().getRecipeMappings().get(recipeOutput)) { - - // FIXME PRIORITY NUMBER 1 - getting of values should use the same algo in getEnergyValue - EnergyValue currentOutputValue = tempComputedMap.get(WrappedStack.wrap(recipeOutput, 1)); - EnergyValue computedOutputValue = computeFromInputs(tempComputedMap, recipeOutput, recipeInputs); - - if (computedOutputValue != null && computedOutputValue.compareTo(currentOutputValue) < 0) { - - uncomputedStacks.removeIf(wrappedStack -> uncomputedStacks.contains(WrappedStack.wrap(recipeOutput, 1))); - - if (ConfigurationHandler.Settings.energyValueDebugLoggingEnabled) { - LogHelper.info(ENERGY_VALUE_MARKER, "Pass {}: Calculated value {} for object {}", passNumber, computedOutputValue, recipeOutput); - } - - tempComputedMap.put(WrappedStack.wrap(recipeOutput), computedOutputValue); - } - else if (computedOutputValue != null) { - uncomputedStacks.add(WrappedStack.wrap(recipeOutput, 1)); - } - } - } - } - - computedMap.putAll(tempComputedMap); - - long passDuration = System.nanoTime() - passStartTime; - if (ConfigurationHandler.Settings.energyValueDebugLoggingEnabled) { - LogHelper.info(ENERGY_VALUE_MARKER, "Pass {}: Calculated {} values for objects in {} ns", passNumber, tempComputedMap.size(), passDuration); - } - } - long endingTime = System.nanoTime() - startingTime; - LogHelper.info(ENERGY_VALUE_MARKER, "Finished dynamic value calculation (calculated {} values for objects in {} ns)", computedMap.size() - stackValueMap.size(), endingTime); - - return computedMap; - } - - private void calculateValueStackMap() { - - SortedMap> tempValueMap = new TreeMap<>(); - - for (WrappedStack wrappedStack : getEnergyValues().keySet()) { - - if (wrappedStack != null) { - - EnergyValue energyValue = getEnergyValues().get(wrappedStack); - - if (energyValue != null) { - if (tempValueMap.containsKey(energyValue)) { - if (!(tempValueMap.get(energyValue).contains(wrappedStack))) { - tempValueMap.get(energyValue).add(wrappedStack); - } - } - else { - tempValueMap.put(energyValue, new ArrayList<>(Arrays.asList(wrappedStack))); - } - } - } - } - valueStackMap = ImmutableSortedMap.copyOf(tempValueMap); - } - - /** - * Saves the pre-calculation, post-calculation, and calculated energy value maps to disk - */ - public void save() { - - writeToJsonFile(stackValueMap, energyValuesFile); - writeToJsonFile(preCalculationStackValueMap, preCalculationValuesFile); - writeToJsonFile(postCalculationStackValueMap, postCalculationValuesFile); - } - - /** - * Loads the pre-calculation, post-calculation, and calculated energy value maps from disk. In the event that either - * the pre/post calculation maps can not be loaded from disk they will be initialized as empty maps. If the - * calculated energy value map can not be loaded from disk then the values will be computed from the pre/post - * calculation maps - */ - public void load() { - - try { - preCalculationStackValueMap.putAll(readFromJsonFile(preCalculationValuesFile)); - } catch (FileNotFoundException e) { - // TODO Log that no pre-calculation values were loaded from file because file wasn't found - } - - try { - postCalculationStackValueMap.putAll(readFromJsonFile(postCalculationValuesFile)); - } catch (FileNotFoundException e) { - // TODO Log that no post-calculation values were loaded from file because file wasn't found - } - - try { - ImmutableSortedMap.Builder stackMapBuilder = ImmutableSortedMap.naturalOrder(); - stackMapBuilder.putAll(readFromJsonFile(energyValuesFile)); - stackValueMap = stackMapBuilder.build(); - calculateValueStackMap(); - } catch (FileNotFoundException e) { - LogHelper.warn("No calculated energy value file found, regenerating"); // TODO Better log message - compute(); - } - } - - /** - * @see net.minecraft.nbt.CompressedStreamTools#safeWrite(NBTTagCompound, File) - */ - private static void writeToJsonFile(Map valueMap, File file) { - - File tempFile = new File(file.getAbsolutePath() + "_tmp"); - - if (tempFile.exists()) { - tempFile.delete(); - } - - try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(tempFile))) { - - bufferedWriter.write(SerializationHelper.GSON.toJson(valueMap, SerializationHelper.ENERGY_VALUE_MAP_TYPE)); - bufferedWriter.close(); - } - catch (IOException exception) { - exception.printStackTrace(); // TODO Better logging of the exception - } - - if (file.exists()) { - file.delete(); - } - - if (file.exists()) { - LogHelper.warn("Failed to delete " + file); - } - else { - tempFile.renameTo(file); - } - } - - private static Map readFromJsonFile(File file) throws FileNotFoundException { - - Map valueMap = new TreeMap<>(); - - StringBuilder jsonStringBuilder = new StringBuilder(); - try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) { - - jsonStringBuilder = new StringBuilder(); - String line; - while ((line = bufferedReader.readLine()) != null) { - jsonStringBuilder.append(line); - } - } - catch (IOException exception) { - if (exception instanceof FileNotFoundException) { - throw (FileNotFoundException) exception; - } - else { - exception.printStackTrace(); // TODO Better logging of the exception (other) - } - } - - try { - valueMap = SerializationHelper.GSON.fromJson(jsonStringBuilder.toString(), SerializationHelper.ENERGY_VALUE_MAP_TYPE); - } - catch (JsonParseException exception) { - // TODO Better logging of the exception (failed parsing so no values loaded) - } - - return valueMap; - } -} diff --git a/src/main/java/com/pahimar/ee3/exchange/OreStack.java b/src/main/java/com/pahimar/ee3/exchange/OreStack.java index 57d19378..23f3f890 100644 --- a/src/main/java/com/pahimar/ee3/exchange/OreStack.java +++ b/src/main/java/com/pahimar/ee3/exchange/OreStack.java @@ -1,73 +1,58 @@ package com.pahimar.ee3.exchange; import com.pahimar.ee3.reference.Comparators; +import com.pahimar.ee3.util.OreDictionaryHelper; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import java.util.*; +import java.util.stream.Collectors; + +public class OreStack implements Comparable { -public class OreStack implements Comparable -{ public String oreName; public int stackSize; - public static Comparator comparator = new Comparator() - { - @Override - public int compare(OreStack oreStack1, OreStack oreStack2) - { - if (oreStack1 != null && oreStack1.oreName != null) - { - if (oreStack2 != null && oreStack2.oreName != null) - { - if (oreStack1.oreName.equalsIgnoreCase(oreStack2.oreName)) - { - return oreStack1.stackSize - oreStack2.stackSize; - } - else - { - return oreStack1.oreName.compareToIgnoreCase(oreStack2.oreName); - } + + public static Comparator comparator = (oreStack1, oreStack2) -> { + if (oreStack1 != null && oreStack1.oreName != null) { + if (oreStack2 != null && oreStack2.oreName != null) { + if (oreStack1.oreName.equalsIgnoreCase(oreStack2.oreName)) { + return oreStack1.stackSize - oreStack2.stackSize; } - else - { - return -1; + else { + return oreStack1.oreName.compareToIgnoreCase(oreStack2.oreName); } } - else - { - if (oreStack2 != null) - { - return 1; - } - else - { - return 0; - } + else { + return -1; + } + } + else { + if (oreStack2 != null) { + return 1; + } + else { + return 0; } } }; - private OreStack() - { + private OreStack() { } - public OreStack(String oreName) - { + public OreStack(String oreName) { this(oreName, 1); } - public OreStack(String oreName, int stackSize) - { + public OreStack(String oreName, int stackSize) { this.oreName = oreName; this.stackSize = stackSize; } - public static boolean compareOreNames(OreStack oreStack1, OreStack oreStack2) - { - if (oreStack1 != null && oreStack2 != null) - { - if ((oreStack1.oreName != null) && (oreStack2.oreName != null)) - { + public static boolean compareOreNames(OreStack oreStack1, OreStack oreStack2) { + + if (oreStack1 != null && oreStack2 != null) { + if ((oreStack1.oreName != null) && (oreStack2.oreName != null)) { return oreStack1.oreName.equalsIgnoreCase(oreStack2.oreName); } } @@ -75,47 +60,35 @@ public class OreStack implements Comparable return false; } - public static OreStack getOreStackFromList(Object... objects) - { + public static OreStack getOreStackFromList(Object... objects) { return getOreStackFromList(Arrays.asList(objects)); } - public static OreStack getOreStackFromList(List objectList) - { - if (objectList.size() > 0) - { - Map oreNameCountMap = new TreeMap(Comparators.stringComparator); - for (Object listElement : objectList) - { - if (listElement instanceof ItemStack) - { + public static OreStack getOreStackFromList(List objectList) { + + if (objectList.size() > 0) { + Map oreNameCountMap = new TreeMap<>(Comparators.stringComparator); + for (Object listElement : objectList) { + if (listElement instanceof ItemStack) { ItemStack itemStack = (ItemStack) listElement; - for (String oreName : CachedOreDictionary.getInstance().getOreNamesForItemStack(itemStack)) - { - if (oreNameCountMap.containsKey(oreName)) - { + for (String oreName : OreDictionaryHelper.getOreNames(itemStack)) { + if (oreNameCountMap.containsKey(oreName)) { oreNameCountMap.put(oreName, oreNameCountMap.get(oreName) + 1); } - else - { + else { oreNameCountMap.put(oreName, 1); } } } } - List candidateOreStacks = new ArrayList(); - for (String oreName : oreNameCountMap.keySet()) - { - if (oreNameCountMap.get(oreName) == objectList.size()) - { - candidateOreStacks.add(new OreStack(oreName)); - } - } + List candidateOreStacks = oreNameCountMap.keySet().stream() + .filter(oreName -> oreNameCountMap.get(oreName) == objectList.size()) + .map(OreStack::new) + .collect(Collectors.toList()); - if (candidateOreStacks.size() == 1) - { + if (candidateOreStacks.size() == 1) { return candidateOreStacks.get(0); } @@ -125,46 +98,42 @@ public class OreStack implements Comparable return null; } - public static int compare(OreStack oreStack1, OreStack oreStack2) - { + public static int compare(OreStack oreStack1, OreStack oreStack2) { return comparator.compare(oreStack1, oreStack2); } @Override - public boolean equals(Object object) - { + public boolean equals(Object object) { return object instanceof OreStack && (comparator.compare(this, (OreStack) object) == 0); } - public NBTTagCompound writeToNBT(NBTTagCompound nbtTagCompound) - { + public NBTTagCompound writeToNBT(NBTTagCompound nbtTagCompound) { + nbtTagCompound.setString("oreName", oreName); nbtTagCompound.setInteger("stackSize", stackSize); return nbtTagCompound; } - public void readFromNBT(NBTTagCompound nbtTagCompound) - { + public void readFromNBT(NBTTagCompound nbtTagCompound) { + this.oreName = nbtTagCompound.getString("oreName"); this.stackSize = nbtTagCompound.getInteger("stackSize"); } - public static OreStack loadOreStackFromNBT(NBTTagCompound nbtTagCompound) - { + public static OreStack loadOreStackFromNBT(NBTTagCompound nbtTagCompound) { + OreStack oreStack = new OreStack(); oreStack.readFromNBT(nbtTagCompound); return oreStack.oreName != null ? oreStack : null; } @Override - public String toString() - { + public String toString() { return String.format("%sxoreStack.%s", stackSize, oreName); } @Override - public int compareTo(OreStack oreStack) - { + public int compareTo(OreStack oreStack) { return comparator.compare(this, oreStack); } } diff --git a/src/main/java/com/pahimar/ee3/exchange/WrappedStack.java b/src/main/java/com/pahimar/ee3/exchange/WrappedStack.java index c436a877..f552fe18 100644 --- a/src/main/java/com/pahimar/ee3/exchange/WrappedStack.java +++ b/src/main/java/com/pahimar/ee3/exchange/WrappedStack.java @@ -454,34 +454,28 @@ public class WrappedStack implements Comparable, JsonDeserializer< * */ @Override - public int hashCode() - { + public int hashCode() { + int hashCode = 1; hashCode = (37 * hashCode) + stackSize; - if (wrappedStack instanceof ItemStack) - { + if (wrappedStack instanceof ItemStack) { hashCode = (37 * hashCode) + Item.getIdFromItem(((ItemStack) wrappedStack).getItem()); hashCode = (37 * hashCode) + ((ItemStack) wrappedStack).getItemDamage(); - if (((ItemStack) wrappedStack).getTagCompound() != null) - { + if (((ItemStack) wrappedStack).getTagCompound() != null) { hashCode = (37 * hashCode) + ((ItemStack) wrappedStack).getTagCompound().hashCode(); } } - else if (wrappedStack instanceof OreStack) - { - if (((OreStack) wrappedStack).oreName != null) - { + else if (wrappedStack instanceof OreStack) { + if (((OreStack) wrappedStack).oreName != null) { hashCode = (37 * hashCode) + ((OreStack) wrappedStack).oreName.hashCode(); } } - else if (wrappedStack instanceof FluidStack) - { + else if (wrappedStack instanceof FluidStack) { hashCode = (37 * hashCode) + wrappedStack.hashCode(); - if (((FluidStack) wrappedStack).tag != null) - { + if (((FluidStack) wrappedStack).tag != null) { hashCode = (37 * hashCode) + ((FluidStack) wrappedStack).tag.hashCode(); } } diff --git a/src/main/java/com/pahimar/ee3/handler/PlayerEventHandler.java b/src/main/java/com/pahimar/ee3/handler/PlayerEventHandler.java index a4dfc722..6a5dead0 100644 --- a/src/main/java/com/pahimar/ee3/handler/PlayerEventHandler.java +++ b/src/main/java/com/pahimar/ee3/handler/PlayerEventHandler.java @@ -1,6 +1,5 @@ package com.pahimar.ee3.handler; -import com.pahimar.ee3.exchange.EnergyValueRegistry; import com.pahimar.ee3.knowledge.TransmutationKnowledgeRegistry; import com.pahimar.ee3.network.PacketHandler; import com.pahimar.ee3.network.message.MessageChalkSettings; @@ -47,7 +46,7 @@ public class PlayerEventHandler PacketHandler.INSTANCE.sendTo(new MessageChalkSettings(chalkSettings), (EntityPlayerMP) event.player); TransmutationKnowledgeRegistry.getInstance().loadPlayerFromDiskIfNeeded(event.player); - PacketHandler.INSTANCE.sendTo(new MessageSyncEnergyValues(EnergyValueRegistry.getInstance()), (EntityPlayerMP) event.player); + PacketHandler.INSTANCE.sendTo(new MessageSyncEnergyValues(), (EntityPlayerMP) event.player); } } diff --git a/src/main/java/com/pahimar/ee3/handler/WorldEventHandler.java b/src/main/java/com/pahimar/ee3/handler/WorldEventHandler.java index f33c587a..f32c2593 100644 --- a/src/main/java/com/pahimar/ee3/handler/WorldEventHandler.java +++ b/src/main/java/com/pahimar/ee3/handler/WorldEventHandler.java @@ -1,21 +1,29 @@ package com.pahimar.ee3.handler; -import com.pahimar.ee3.exchange.DynamicEnergyValueInitThread; +import com.pahimar.ee3.exchange.EnergyValueRegistry; +import com.pahimar.ee3.recipe.AludelRecipeManager; +import com.pahimar.ee3.recipe.RecipeRegistry; +import com.pahimar.ee3.util.LogHelper; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.relauncher.Side; import net.minecraftforge.event.world.WorldEvent; -public class WorldEventHandler -{ +public class WorldEventHandler { + public static boolean hasInitilialized = false; @SubscribeEvent - public void onWorldLoadEvent(WorldEvent.Load event) - { - if (!hasInitilialized && FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) - { - DynamicEnergyValueInitThread.initEnergyValueRegistry(); + public void onWorldLoadEvent(WorldEvent.Load event) { + + if (!hasInitilialized && FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) { + + RecipeRegistry.getInstance().registerVanillaRecipes(); + AludelRecipeManager.registerRecipes(); + + long startTime = System.nanoTime(); + EnergyValueRegistry.INSTANCE.compute(); + LogHelper.info(EnergyValueRegistry.ENERGY_VALUE_MARKER, "Energy value system initialized {} values after {} ms", EnergyValueRegistry.INSTANCE.getEnergyValues().size(), (System.nanoTime() - startTime) / 100000); hasInitilialized = true; } } diff --git a/src/main/java/com/pahimar/ee3/init/Abilities.java b/src/main/java/com/pahimar/ee3/init/Abilities.java index 80917ee1..31018b19 100644 --- a/src/main/java/com/pahimar/ee3/init/Abilities.java +++ b/src/main/java/com/pahimar/ee3/init/Abilities.java @@ -1,29 +1,23 @@ package com.pahimar.ee3.init; import com.pahimar.ee3.api.knowledge.AbilityRegistryProxy; -import com.pahimar.ee3.exchange.CachedOreDictionary; import com.pahimar.ee3.exchange.OreStack; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; -public class Abilities -{ - public static void initNotLearnables() - { - for (String oreName : OreDictionary.getOreNames()) - { - if (oreName.startsWith("ore")) - { - for (ItemStack itemStack : CachedOreDictionary.getInstance().getItemStacksForOreName(oreName)) - { - AbilityRegistryProxy.setAsNotLearnable(itemStack); - } +public class Abilities { + + public static void init() { + + for (String oreName : OreDictionary.getOreNames()) { + if (oreName.startsWith("ore")) { + OreDictionary.getOres(oreName).forEach(AbilityRegistryProxy::setAsNotLearnable); AbilityRegistryProxy.setAsNotLearnable(new OreStack(oreName)); } } - AbilityRegistryProxy.setAsNotLearnable(new ItemStack(Blocks.coal_ore)); + AbilityRegistryProxy.setAsNotLearnable(new ItemStack(Blocks.coal_ore)); AbilityRegistryProxy.setAsNotLearnable(ModItems.shardMinium); AbilityRegistryProxy.setAsNotLearnable(new ItemStack(ModItems.alchemicalDust, 1, 1)); AbilityRegistryProxy.setAsNotLearnable(new ItemStack(ModItems.alchemicalDust, 1, 2)); diff --git a/src/main/java/com/pahimar/ee3/init/AlchemyArrays.java b/src/main/java/com/pahimar/ee3/init/AlchemyArrays.java index 5abecf77..cba93d2f 100644 --- a/src/main/java/com/pahimar/ee3/init/AlchemyArrays.java +++ b/src/main/java/com/pahimar/ee3/init/AlchemyArrays.java @@ -2,30 +2,13 @@ package com.pahimar.ee3.init; import com.pahimar.ee3.api.array.AlchemyArray; import com.pahimar.ee3.api.array.AlchemyArrayRegistryProxy; -import com.pahimar.ee3.array.*; +import com.pahimar.ee3.array.AlchemyArrayTransmutation; + +public class AlchemyArrays { -public class AlchemyArrays -{ - public static final AlchemyArray accelerantAlchemyArray = new AlchemyArrayAccelerant(); - public static final AlchemyArray combustionAlchemyArray = new AlchemyArrayCombustion(); - public static final AlchemyArray constructionAlchemyArray = new AlchemyArrayConstruction(); - public static final AlchemyArray conveyorAlchemyArray = new AlchemyArrayConveyor(); - public static final AlchemyArray destructionAlchemyArray = new AlchemyArrayDestruction(); - public static final AlchemyArray gelidAlchemyArray = new AlchemyArrayGelid(); - public static final AlchemyArray parthenogenesisAlchemyArray = new AlchemyArrayParthenogenesis(); - public static final AlchemyArray transfigurationAlchemyArray = new AlchemyArrayTransfiguration(); public static final AlchemyArray transmutationAlchemyArray = new AlchemyArrayTransmutation(); - public static void registerAlchemyArrays() - { - AlchemyArrayRegistryProxy.registerAlchemyArray(accelerantAlchemyArray); - AlchemyArrayRegistryProxy.registerAlchemyArray(combustionAlchemyArray); - AlchemyArrayRegistryProxy.registerAlchemyArray(constructionAlchemyArray); - AlchemyArrayRegistryProxy.registerAlchemyArray(conveyorAlchemyArray); - AlchemyArrayRegistryProxy.registerAlchemyArray(destructionAlchemyArray); - AlchemyArrayRegistryProxy.registerAlchemyArray(gelidAlchemyArray); - AlchemyArrayRegistryProxy.registerAlchemyArray(parthenogenesisAlchemyArray); - AlchemyArrayRegistryProxy.registerAlchemyArray(transfigurationAlchemyArray); + public static void registerAlchemyArrays() { AlchemyArrayRegistryProxy.registerAlchemyArray(transmutationAlchemyArray); } } diff --git a/src/main/java/com/pahimar/ee3/inventory/ContainerTransmutationTablet.java b/src/main/java/com/pahimar/ee3/inventory/ContainerTransmutationTablet.java index b77b6f25..12e50d80 100644 --- a/src/main/java/com/pahimar/ee3/inventory/ContainerTransmutationTablet.java +++ b/src/main/java/com/pahimar/ee3/inventory/ContainerTransmutationTablet.java @@ -1,14 +1,13 @@ package com.pahimar.ee3.inventory; import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy; -import com.pahimar.ee3.exchange.EnergyValueRegistry; +import com.pahimar.ee3.api.knowledge.AbilityRegistryProxy; import com.pahimar.ee3.inventory.element.IElementButtonHandler; import com.pahimar.ee3.inventory.element.IElementSliderHandler; import com.pahimar.ee3.inventory.element.IElementTextFieldHandler; import com.pahimar.ee3.item.ItemAlchenomicon; import com.pahimar.ee3.item.ItemMiniumStone; import com.pahimar.ee3.item.ItemPhilosophersStone; -import com.pahimar.ee3.knowledge.AbilityRegistry; import com.pahimar.ee3.knowledge.TransmutationKnowledge; import com.pahimar.ee3.knowledge.TransmutationKnowledgeRegistry; import com.pahimar.ee3.network.PacketHandler; @@ -589,7 +588,7 @@ public class ContainerTransmutationTablet extends ContainerEE implements IElemen @Override public boolean isItemValid(ItemStack itemStack) { - return EnergyValueRegistry.getInstance().hasEnergyValue(itemStack) && AbilityRegistry.getInstance().isRecoverable(itemStack); + return EnergyValueRegistryProxy.hasEnergyValue(itemStack) && AbilityRegistryProxy.isRecoverable(itemStack); } @Override diff --git a/src/main/java/com/pahimar/ee3/knowledge/AbilityRegistry.java b/src/main/java/com/pahimar/ee3/knowledge/AbilityRegistry.java index 12d62007..e309d3df 100644 --- a/src/main/java/com/pahimar/ee3/knowledge/AbilityRegistry.java +++ b/src/main/java/com/pahimar/ee3/knowledge/AbilityRegistry.java @@ -4,8 +4,8 @@ import com.google.gson.*; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import com.pahimar.ee3.api.event.AbilityEvent; +import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy; import com.pahimar.ee3.api.knowledge.AbilityRegistryProxy; -import com.pahimar.ee3.exchange.EnergyValueRegistry; import com.pahimar.ee3.exchange.WrappedStack; import com.pahimar.ee3.reference.Files; import com.pahimar.ee3.util.LoaderHelper; @@ -80,7 +80,7 @@ public class AbilityRegistry implements JsonSerializer, JsonDes } else { - return !notLearnableSet.contains(wrappedObject) && EnergyValueRegistry.getInstance().hasEnergyValue(wrappedObject); + return !notLearnableSet.contains(wrappedObject) && EnergyValueRegistryProxy.hasEnergyValue(wrappedObject); } } @@ -131,7 +131,7 @@ public class AbilityRegistry implements JsonSerializer, JsonDes if (WrappedStack.canBeWrapped(object)) { WrappedStack wrappedObject = WrappedStack.wrap(object); - return !notRecoverableSet.contains(wrappedObject) && EnergyValueRegistry.getInstance().hasEnergyValue(wrappedObject); + return !notRecoverableSet.contains(wrappedObject) && EnergyValueRegistryProxy.hasEnergyValue(wrappedObject); } return false; diff --git a/src/main/java/com/pahimar/ee3/network/message/MessageSetEnergyValue.java b/src/main/java/com/pahimar/ee3/network/message/MessageSetEnergyValue.java index f0bc9d5a..435537aa 100644 --- a/src/main/java/com/pahimar/ee3/network/message/MessageSetEnergyValue.java +++ b/src/main/java/com/pahimar/ee3/network/message/MessageSetEnergyValue.java @@ -1,6 +1,7 @@ package com.pahimar.ee3.network.message; 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.EnergyValueStackMapping; import com.pahimar.ee3.exchange.WrappedStack; @@ -11,8 +12,6 @@ import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; import cpw.mods.fml.common.network.simpleimpl.MessageContext; import io.netty.buffer.ByteBuf; -import java.io.IOException; - public class MessageSetEnergyValue implements IMessage, IMessageHandler { public EnergyValueStackMapping energyValueStackMapping; @@ -39,12 +38,7 @@ public class MessageSetEnergyValue implements IMessage, IMessageHandler -{ - public String jsonEnergyValueRegistry; +public class MessageSyncEnergyValues implements IMessage, IMessageHandler { - public MessageSyncEnergyValues() - { - } + public String jsonString; - public MessageSyncEnergyValues(EnergyValueRegistry energyValueRegistry) - { - this.jsonEnergyValueRegistry = energyValueRegistry.toJson(); + public MessageSyncEnergyValues() { + this.jsonString = SerializationHelper.GSON.toJson(EnergyValueRegistry.INSTANCE.getEnergyValues(), SerializationHelper.ENERGY_VALUE_MAP_TYPE); } /** @@ -36,22 +28,16 @@ public class MessageSyncEnergyValues implements IMessage, IMessageHandler 0) - { - compressedBytes = buf.readBytes(readableBytes).array(); - } + byte[] compressedString; + int compressedStringLength = buf.readInt(); - if (compressedBytes != null) - { - try { - this.jsonEnergyValueRegistry = CompressionHelper.decompress(compressedBytes); - } catch (IOException e) { - e.printStackTrace(); + if (compressedStringLength > 0) { + compressedString = buf.readBytes(compressedStringLength).array(); + + if (compressedString != null) { + this.jsonString = CompressionHelper.decompress(compressedString); } } } @@ -62,26 +48,23 @@ public class MessageSyncEnergyValues implements IMessage, IMessageHandler energyValueStackMap = new TreeMap(); + public IMessage onMessage(MessageSyncEnergyValues message, MessageContext ctx) { - try - { - JsonReader jsonReader = new JsonReader(new StringReader(message.jsonEnergyValueRegistry)); - jsonReader.beginArray(); - while (jsonReader.hasNext()) - { - EnergyValueStackMapping energyValueStackMapping = EnergyValueStackMapping.jsonSerializer.fromJson(jsonReader, EnergyValueStackMapping.class); - if (energyValueStackMapping != null) - { - energyValueStackMap.put(energyValueStackMapping.wrappedStack, energyValueStackMapping.energyValue); - } - } - jsonReader.endArray(); - jsonReader.close(); + if (message.jsonString != null) { + + Map valueMap = null; + + try { + valueMap = SerializationHelper.GSON.fromJson(message.jsonString, SerializationHelper.ENERGY_VALUE_MAP_TYPE); } - catch (IOException e) - { - e.printStackTrace(); + catch (JsonParseException e) { + // TODO Log an error message here } - EnergyValueRegistry.getInstance().loadFromMap(energyValueStackMap); - LogHelper.info(EnergyValueRegistry.ENERGY_VALUE_MARKER, "Client successfully received EnergyValues from server"); + if (valueMap != null) { + EnergyValueRegistry.INSTANCE.load(valueMap); + LogHelper.info(EnergyValueRegistry.ENERGY_VALUE_MARKER, "Client successfully received {} energy values from server", valueMap.size()); + } + else { + // TODO Log a message here + } } - else - { - LogHelper.info(EnergyValueRegistry.ENERGY_VALUE_MARKER, "Client failed to receive EnergyValues from server - falling back to local EnergyValues"); + else { + LogHelper.info(EnergyValueRegistry.ENERGY_VALUE_MARKER, "Client failed to receive energy values from server - falling back to local values"); } return null; diff --git a/src/main/java/com/pahimar/ee3/network/message/MessageTransmutationKnowledgeUpdate.java b/src/main/java/com/pahimar/ee3/network/message/MessageTransmutationKnowledgeUpdate.java index 889c92ee..c111c447 100644 --- a/src/main/java/com/pahimar/ee3/network/message/MessageTransmutationKnowledgeUpdate.java +++ b/src/main/java/com/pahimar/ee3/network/message/MessageTransmutationKnowledgeUpdate.java @@ -12,7 +12,6 @@ import io.netty.buffer.ByteBuf; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.item.ItemStack; -import java.io.IOException; import java.util.Collection; public class MessageTransmutationKnowledgeUpdate implements IMessage, IMessageHandler @@ -83,12 +82,7 @@ public class MessageTransmutationKnowledgeUpdate implements IMessage, IMessageHa if (compressedString != null) { - String uncompressedString = null; - try { - uncompressedString = CompressionHelper.decompress(compressedString); - } catch (IOException e) { - e.printStackTrace(); - } + String uncompressedString = CompressionHelper.decompress(compressedString); this.transmutationKnowledge = TransmutationKnowledge.createFromJson(uncompressedString); } } @@ -102,13 +96,8 @@ public class MessageTransmutationKnowledgeUpdate implements IMessage, IMessageHa byte[] compressedString = null; - if (transmutationKnowledge != null) - { - try { - compressedString = CompressionHelper.compress(transmutationKnowledge.toJson()); - } catch (IOException e) { - e.printStackTrace(); - } + if (transmutationKnowledge != null) { + compressedString = CompressionHelper.compress(transmutationKnowledge.toJson()); } if (compressedString != null) diff --git a/src/main/java/com/pahimar/ee3/reference/Comparators.java b/src/main/java/com/pahimar/ee3/reference/Comparators.java index dd9bbd8b..fb72bae7 100644 --- a/src/main/java/com/pahimar/ee3/reference/Comparators.java +++ b/src/main/java/com/pahimar/ee3/reference/Comparators.java @@ -1,6 +1,6 @@ package com.pahimar.ee3.reference; -import com.pahimar.ee3.exchange.EnergyValueRegistry; +import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; @@ -129,9 +129,9 @@ public class Comparators { if (itemStack1 != null && itemStack2 != null) { - if (EnergyValueRegistry.getInstance().hasEnergyValue(itemStack1) && EnergyValueRegistry.getInstance().hasEnergyValue(itemStack2)) + if (EnergyValueRegistryProxy.hasEnergyValue(itemStack1) && EnergyValueRegistryProxy.hasEnergyValue(itemStack2)) { - return Float.compare(EnergyValueRegistry.getInstance().getEnergyValue(itemStack1).getValue(), EnergyValueRegistry.getInstance().getEnergyValue(itemStack2).getValue()); + return Float.compare(EnergyValueRegistryProxy.getEnergyValue(itemStack1).getValue(), EnergyValueRegistryProxy.getEnergyValue(itemStack2).getValue()); } else { diff --git a/src/main/java/com/pahimar/ee3/reference/Files.java b/src/main/java/com/pahimar/ee3/reference/Files.java index e8b8d285..f33ed767 100644 --- a/src/main/java/com/pahimar/ee3/reference/Files.java +++ b/src/main/java/com/pahimar/ee3/reference/Files.java @@ -1,6 +1,6 @@ package com.pahimar.ee3.reference; -import com.pahimar.ee3.exchange.NewEnergyValueRegistry; +import com.pahimar.ee3.exchange.EnergyValueRegistry; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import java.io.File; @@ -26,11 +26,11 @@ public class Files { dataDirectory = new File(event.getModConfigurationDirectory().getParentFile(), "data" + File.separator + Reference.LOWERCASE_MOD_ID); - NewEnergyValueRegistry.energyValuesDirectory = new File(dataDirectory, "energy-values"); - NewEnergyValueRegistry.energyValuesDirectory.mkdirs(); - NewEnergyValueRegistry.energyValuesFile = new File(NewEnergyValueRegistry.energyValuesDirectory, ENERGY_VALUES_JSON); - NewEnergyValueRegistry.preCalculationValuesFile = new File(NewEnergyValueRegistry.energyValuesDirectory, PRE_CALCULATION_ENERGY_VALUES); - NewEnergyValueRegistry.postCalculationValuesFile = new File(NewEnergyValueRegistry.energyValuesDirectory, POST_CALCULATION_ENERGY_VALUES); + EnergyValueRegistry.energyValuesDirectory = new File(dataDirectory, "energy-values"); + EnergyValueRegistry.energyValuesDirectory.mkdirs(); + EnergyValueRegistry.energyValuesFile = new File(EnergyValueRegistry.energyValuesDirectory, ENERGY_VALUES_JSON); + EnergyValueRegistry.preCalculationValuesFile = new File(EnergyValueRegistry.energyValuesDirectory, PRE_CALCULATION_ENERGY_VALUES); + EnergyValueRegistry.postCalculationValuesFile = new File(EnergyValueRegistry.energyValuesDirectory, POST_CALCULATION_ENERGY_VALUES); abilitiesDataDirectory = new File(dataDirectory, "abilities"); abilitiesDataDirectory.mkdirs(); diff --git a/src/main/java/com/pahimar/ee3/tileentity/TileEntityTransmutationTablet.java b/src/main/java/com/pahimar/ee3/tileentity/TileEntityTransmutationTablet.java index 0e1d2ccb..5ae669db 100644 --- a/src/main/java/com/pahimar/ee3/tileentity/TileEntityTransmutationTablet.java +++ b/src/main/java/com/pahimar/ee3/tileentity/TileEntityTransmutationTablet.java @@ -2,12 +2,11 @@ package com.pahimar.ee3.tileentity; import com.pahimar.ee3.api.exchange.EnergyValue; import com.pahimar.ee3.api.exchange.EnergyValueRegistryProxy; +import com.pahimar.ee3.api.knowledge.AbilityRegistryProxy; import com.pahimar.ee3.block.BlockAshInfusedStoneSlab; -import com.pahimar.ee3.exchange.EnergyValueRegistry; import com.pahimar.ee3.item.ItemAlchenomicon; import com.pahimar.ee3.item.ItemMiniumStone; import com.pahimar.ee3.item.ItemPhilosophersStone; -import com.pahimar.ee3.knowledge.AbilityRegistry; import com.pahimar.ee3.network.PacketHandler; import com.pahimar.ee3.network.message.MessageTileEntityTransmutationTablet; import com.pahimar.ee3.reference.Names; @@ -314,7 +313,7 @@ public class TileEntityTransmutationTablet extends TileEntityEE implements ISide @Override public boolean isItemValidForSlot(int slotIndex, ItemStack itemStack) { - if (slotIndex < STONE_INDEX && EnergyValueRegistry.getInstance().hasEnergyValue(itemStack) && AbilityRegistry.getInstance().isRecoverable(itemStack)) + if (slotIndex < STONE_INDEX && EnergyValueRegistryProxy.hasEnergyValue(itemStack) && AbilityRegistryProxy.isRecoverable(itemStack)) { return true; } diff --git a/src/main/java/com/pahimar/ee3/util/CompressionHelper.java b/src/main/java/com/pahimar/ee3/util/CompressionHelper.java index 55d8c9b5..8ef5e9e8 100644 --- a/src/main/java/com/pahimar/ee3/util/CompressionHelper.java +++ b/src/main/java/com/pahimar/ee3/util/CompressionHelper.java @@ -5,27 +5,44 @@ import java.nio.charset.StandardCharsets; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; -public class CompressionHelper -{ - public static byte[] compress(String uncompressedString) throws IOException { +public class CompressionHelper { + + /** + * + * @param uncompressedString + * @return + */ + public static byte[] compress(String uncompressedString) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream); - gzipOutputStream.write(uncompressedString.getBytes(StandardCharsets.UTF_8)); - gzipOutputStream.close(); + + try (GZIPOutputStream gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream)) { + gzipOutputStream.write(uncompressedString.getBytes(StandardCharsets.UTF_8)); + gzipOutputStream.close(); + } + catch (IOException e) { + e.printStackTrace(); + } return byteArrayOutputStream.toByteArray(); } - public static String decompress(byte[] compressedString) throws IOException { - - GZIPInputStream gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(compressedString)); - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(gzipInputStream, StandardCharsets.UTF_8)); + /** + * + * @param compressedString + * @return + */ + public static String decompress(byte[] compressedString) { StringBuilder stringBuilder = new StringBuilder(); String line; - while ((line = bufferedReader.readLine()) != null) { - stringBuilder.append(line); + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new GZIPInputStream(new ByteArrayInputStream(compressedString)), StandardCharsets.UTF_8))) { + while ((line = bufferedReader.readLine()) != null) { + stringBuilder.append(line); + } + } + catch (IOException e) { + e.printStackTrace(); } return stringBuilder.toString(); diff --git a/src/main/java/com/pahimar/ee3/util/OreDictionaryHelper.java b/src/main/java/com/pahimar/ee3/util/OreDictionaryHelper.java new file mode 100644 index 00000000..2c17e579 --- /dev/null +++ b/src/main/java/com/pahimar/ee3/util/OreDictionaryHelper.java @@ -0,0 +1,22 @@ +package com.pahimar.ee3.util; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.oredict.OreDictionary; + +import java.util.Collection; +import java.util.Set; +import java.util.TreeSet; + +public class OreDictionaryHelper { + + public static Collection getOreNames(ItemStack itemStack) { + + Set oreNames = new TreeSet<>(); + + for (int oreId : OreDictionary.getOreIDs(itemStack)) { + oreNames.add(OreDictionary.getOreName(oreId)); + } + + return oreNames; + } +} diff --git a/src/main/java/com/pahimar/ee3/util/SerializationHelper.java b/src/main/java/com/pahimar/ee3/util/SerializationHelper.java index 5ecc1af4..a6a230d1 100644 --- a/src/main/java/com/pahimar/ee3/util/SerializationHelper.java +++ b/src/main/java/com/pahimar/ee3/util/SerializationHelper.java @@ -1,13 +1,11 @@ package com.pahimar.ee3.util; -import com.google.common.io.Files; import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonWriter; import com.pahimar.ee3.api.exchange.EnergyValue; -import com.pahimar.ee3.exchange.EnergyValueRegistry; import com.pahimar.ee3.exchange.EnergyValueStackMapping; import com.pahimar.ee3.exchange.OreStack; import com.pahimar.ee3.exchange.WrappedStack; @@ -216,72 +214,4 @@ public class SerializationHelper { e.printStackTrace(); } } - - public static void compressEnergyValueStackMapToFile(String fileName, Map energyValueMap) - { - File energyValuesDataDirectory = new File(FMLCommonHandler.instance().getMinecraftServerInstance().getEntityWorld().getSaveHandler().getWorldDirectory(), "data" + File.separator + Reference.LOWERCASE_MOD_ID + File.separator + "energyvalues"); - compressEnergyValueStackMapToFile(new File(energyValuesDataDirectory, fileName), energyValueMap); - } - - public static void compressEnergyValueStackMapToFile(File file, Map energyValueMap) - { - try - { - byte[] energyValueRegistryArray = CompressionHelper.compress(EnergyValueRegistry.getInstance().toJson()); - FileOutputStream fos = new FileOutputStream(file); - fos.write(energyValueRegistryArray); - fos.close(); - } - catch (UnsupportedEncodingException e) - { - e.printStackTrace(); - } - catch (FileNotFoundException e) - { - e.printStackTrace(); - } - catch (IOException e) - { - e.printStackTrace(); - } - } - - public static Map decompressEnergyValueStackMapFromFile(String fileName) - { - File energyValuesDataDirectory = new File(FMLCommonHandler.instance().getMinecraftServerInstance().getEntityWorld().getSaveHandler().getWorldDirectory(), "data" + File.separator + Reference.LOWERCASE_MOD_ID + File.separator + "energyvalues"); - return decompressEnergyValueStackMapFromFile(new File(energyValuesDataDirectory, fileName)); - } - - public static Map decompressEnergyValueStackMapFromFile(File file) - { - Map energyValueStackMap = new TreeMap(); - - try - { - String jsonEnergyValueStackMap = CompressionHelper.decompress(Files.toByteArray(file)); - JsonReader jsonReader = new JsonReader(new StringReader(jsonEnergyValueStackMap)); - jsonReader.beginArray(); - while (jsonReader.hasNext()) - { - EnergyValueStackMapping energyValueStackMapping = EnergyValueStackMapping.jsonSerializer.fromJson(jsonReader, EnergyValueStackMapping.class); - if (energyValueStackMapping != null) - { - energyValueStackMap.put(energyValueStackMapping.wrappedStack, energyValueStackMapping.energyValue); - } - } - jsonReader.endArray(); - jsonReader.close(); - } - catch (FileNotFoundException e) - { - e.printStackTrace(); - } - catch (IOException e) - { - e.printStackTrace(); - } - - - return energyValueStackMap; - } } diff --git a/src/main/resources/assets/ee3/textures/arrays/arrayAccelerant.png b/src/main/resources/assets/ee3/textures/arrays/arrayAccelerant.png deleted file mode 100644 index f907609f..00000000 Binary files a/src/main/resources/assets/ee3/textures/arrays/arrayAccelerant.png and /dev/null differ diff --git a/src/main/resources/assets/ee3/textures/arrays/arrayCombustion.png b/src/main/resources/assets/ee3/textures/arrays/arrayCombustion.png deleted file mode 100644 index f4976bc9..00000000 Binary files a/src/main/resources/assets/ee3/textures/arrays/arrayCombustion.png and /dev/null differ diff --git a/src/main/resources/assets/ee3/textures/arrays/arrayConstruction.png b/src/main/resources/assets/ee3/textures/arrays/arrayConstruction.png deleted file mode 100644 index ea94a600..00000000 Binary files a/src/main/resources/assets/ee3/textures/arrays/arrayConstruction.png and /dev/null differ diff --git a/src/main/resources/assets/ee3/textures/arrays/arrayConveyor.png b/src/main/resources/assets/ee3/textures/arrays/arrayConveyor.png deleted file mode 100644 index 310c32f4..00000000 Binary files a/src/main/resources/assets/ee3/textures/arrays/arrayConveyor.png and /dev/null differ diff --git a/src/main/resources/assets/ee3/textures/arrays/arrayDestruction.png b/src/main/resources/assets/ee3/textures/arrays/arrayDestruction.png deleted file mode 100644 index a987e5af..00000000 Binary files a/src/main/resources/assets/ee3/textures/arrays/arrayDestruction.png and /dev/null differ diff --git a/src/main/resources/assets/ee3/textures/arrays/arrayGelid.png b/src/main/resources/assets/ee3/textures/arrays/arrayGelid.png deleted file mode 100644 index 5159f4f9..00000000 Binary files a/src/main/resources/assets/ee3/textures/arrays/arrayGelid.png and /dev/null differ diff --git a/src/main/resources/assets/ee3/textures/arrays/arrayParthenogenesis.png b/src/main/resources/assets/ee3/textures/arrays/arrayParthenogenesis.png deleted file mode 100644 index 38386a1d..00000000 Binary files a/src/main/resources/assets/ee3/textures/arrays/arrayParthenogenesis.png and /dev/null differ diff --git a/src/main/resources/assets/ee3/textures/arrays/arrayTransfiguration.png b/src/main/resources/assets/ee3/textures/arrays/arrayTransfiguration.png deleted file mode 100644 index 6118a1cd..00000000 Binary files a/src/main/resources/assets/ee3/textures/arrays/arrayTransfiguration.png and /dev/null differ diff --git a/src/main/resources/assets/ee3/textures/arrays/arrayTransmutation.png b/src/main/resources/assets/ee3/textures/arrays/arrayTransmutation.png index 596571d2..0e441b5c 100644 Binary files a/src/main/resources/assets/ee3/textures/arrays/arrayTransmutation.png and b/src/main/resources/assets/ee3/textures/arrays/arrayTransmutation.png differ diff --git a/src/main/resources/assets/ee3/textures/arrays/transmutation.png b/src/main/resources/assets/ee3/textures/arrays/transmutation.png deleted file mode 100644 index 0e441b5c..00000000 Binary files a/src/main/resources/assets/ee3/textures/arrays/transmutation.png and /dev/null differ