Serialize computed EnergyValues to disk after the initial computation. If mods change, or the file is not found, the values are computed again. Should significantly improve start up times when many mods are present. Closes #724

This commit is contained in:
Pahimar 2014-08-29 16:25:31 -04:00
parent e70eecb11f
commit fe7afe15d4
6 changed files with 323 additions and 5 deletions

View file

@ -1,5 +1,7 @@
package com.pahimar.ee3.api;
import net.minecraft.nbt.NBTTagCompound;
public final class EnergyValue implements Comparable<EnergyValue>
{
private final float energyValue;
@ -68,10 +70,73 @@ public final class EnergyValue implements Comparable<EnergyValue>
return this.energyValue;
}
public NBTTagCompound writeToNBT(NBTTagCompound nbtTagCompound)
{
nbtTagCompound.setFloat("energyValue", energyValue);
nbtTagCompound.setInteger("energyType", energyType.ordinal());
return nbtTagCompound;
}
public static NBTTagCompound writeEnergyValueToNBT(EnergyValue energyValue)
{
NBTTagCompound nbtTagCompound = new NBTTagCompound();
energyValue.writeToNBT(nbtTagCompound);
return nbtTagCompound;
}
public static EnergyValue loadEnergyValueFromNBT(NBTTagCompound nbtTagCompound)
{
if (nbtTagCompound.hasKey("energyValue") && nbtTagCompound.hasKey("energyType"))
{
float energyValue = nbtTagCompound.getFloat("energyValue");
EnergyType energyType = EnergyType.getEnergyTypeFromOrdinal(nbtTagCompound.getInteger("energyType"));
return new EnergyValue(energyValue, energyType);
}
return null;
}
public static enum EnergyType
{
CORPOREAL, KINETIC, TEMPORAL, ESSENTIA, AMORPHOUS, VOID, OMNI;
UNKNOWN, CORPOREAL, KINETIC, TEMPORAL, ESSENTIA, AMORPHOUS, VOID, OMNI;
public static final EnergyType DEFAULT = EnergyType.CORPOREAL;
public static EnergyType getEnergyTypeFromOrdinal(int ordinal)
{
if (ordinal == CORPOREAL.ordinal())
{
return CORPOREAL;
}
else if (ordinal == KINETIC.ordinal())
{
return KINETIC;
}
else if (ordinal == TEMPORAL.ordinal())
{
return TEMPORAL;
}
else if (ordinal == ESSENTIA.ordinal())
{
return ESSENTIA;
}
else if (ordinal == AMORPHOUS.ordinal())
{
return AMORPHOUS;
}
else if (ordinal == VOID.ordinal())
{
return VOID;
}
else if (ordinal == OMNI.ordinal())
{
return OMNI;
}
else
{
return UNKNOWN;
}
}
}
}

View file

@ -5,14 +5,18 @@ import com.pahimar.ee3.api.EnergyValue;
import com.pahimar.ee3.api.IEnergyValueProvider;
import com.pahimar.ee3.recipe.RecipeRegistry;
import com.pahimar.ee3.util.EnergyValueHelper;
import com.pahimar.ee3.util.INBTTaggable;
import com.pahimar.ee3.util.SerializationHelper;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.oredict.OreDictionary;
import java.util.*;
public class EnergyValueRegistry
public class EnergyValueRegistry implements INBTTaggable
{
private static EnergyValueRegistry energyValueRegistry = null;
private static Map<WrappedStack, EnergyValue> preAssignedMappings;
@ -339,6 +343,18 @@ public class EnergyValueRegistry
}
protected final void init()
{
if (!SerializationHelper.energyValueRegistryFileExist())
{
runDynamicEnergyValueResolution();
}
else
{
SerializationHelper.readEnergyValueRegistryFromFile();
}
}
private void runDynamicEnergyValueResolution()
{
HashMap<WrappedStack, EnergyValue> stackValueMap = new HashMap<WrappedStack, EnergyValue>();
@ -455,6 +471,9 @@ public class EnergyValueRegistry
}
valueMappings = ImmutableSortedMap.copyOf(tempValueMappings);
// Serialize values to disk
SerializationHelper.writeEnergyValueRegistryToFile();
}
private Map<WrappedStack, EnergyValue> computeStackMappings()
@ -572,4 +591,73 @@ public class EnergyValueRegistry
return "No Value Assigned";
}
@Override
public void readFromNBT(NBTTagCompound nbtTagCompound)
{
if (nbtTagCompound != null && nbtTagCompound.hasKey("stackMappingList"))
{
HashMap<WrappedStack, EnergyValue> stackValueMap = new HashMap<WrappedStack, EnergyValue>();
/**
* Read stack value mappings from NBTTagCompound
*/
NBTTagList stackMappingTagList = nbtTagCompound.getTagList("stackMappingList", 10);
for (int i = 0; i < stackMappingTagList.tagCount(); i++)
{
NBTTagCompound tagCompound = stackMappingTagList.getCompoundTagAt(i);
WrappedStack wrappedStack = WrappedStack.fromNBTTagCompound(tagCompound.getCompoundTag("wrappedStack"));
EnergyValue energyValue = EnergyValue.loadEnergyValueFromNBT(tagCompound.getCompoundTag("energyValue"));
stackValueMap.put(wrappedStack, energyValue);
}
ImmutableSortedMap.Builder<WrappedStack, EnergyValue> stackMappingsBuilder = ImmutableSortedMap.naturalOrder();
stackMappingsBuilder.putAll(stackValueMap);
stackMappings = stackMappingsBuilder.build();
/**
* Resolve value stack mappings from the newly loaded stack mappings
*/
SortedMap<EnergyValue, List<WrappedStack>> tempValueMappings = new TreeMap<EnergyValue, List<WrappedStack>>();
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<WrappedStack>(Arrays.asList(stack)));
}
}
}
}
valueMappings = ImmutableSortedMap.copyOf(tempValueMappings);
}
}
@Override
public void writeToNBT(NBTTagCompound nbtTagCompound)
{
NBTTagList stackMappingTagList = new NBTTagList();
for (WrappedStack wrappedStack : stackMappings.keySet())
{
NBTTagCompound stackMappingCompound = new NBTTagCompound();
stackMappingCompound.setTag("wrappedStack", WrappedStack.toNBTTagCompound(wrappedStack));
stackMappingCompound.setTag("energyValue", EnergyValue.writeEnergyValueToNBT(stackMappings.get(wrappedStack)));
stackMappingTagList.appendTag(stackMappingCompound);
}
nbtTagCompound.setTag("stackMappingList", stackMappingTagList);
}
}

View file

@ -1,6 +1,7 @@
package com.pahimar.ee3.exchange;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.oredict.OreDictionary;
import java.util.Arrays;
@ -50,6 +51,10 @@ public class OreStack implements Comparable<OreStack>
}
};
private OreStack()
{
}
public OreStack(String oreName)
{
this(oreName, 1);
@ -117,6 +122,26 @@ public class OreStack implements Comparable<OreStack>
return object instanceof OreStack && (comparator.compare(this, (OreStack) object) == 0);
}
public NBTTagCompound writeToNBT(NBTTagCompound nbtTagCompound)
{
nbtTagCompound.setString("oreName", oreName);
nbtTagCompound.setInteger("stackSize", stackSize);
return nbtTagCompound;
}
public void readFromNBT(NBTTagCompound nbtTagCompound)
{
this.oreName = nbtTagCompound.getString("oreName");
this.stackSize = nbtTagCompound.getInteger("stackSize");
}
public static OreStack loadOreStackFromNBT(NBTTagCompound nbtTagCompound)
{
OreStack oreStack = new OreStack();
oreStack.readFromNBT(nbtTagCompound);
return oreStack.oreName != null ? oreStack : null;
}
@Override
public String toString()
{

View file

@ -5,6 +5,7 @@ import com.pahimar.ee3.util.ItemHelper;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
@ -272,7 +273,7 @@ public class WrappedStack implements Comparable<WrappedStack>
}
else if (object instanceof ItemStack)
{
if (((ItemStack)object).getItem() != null)
if (((ItemStack) object).getItem() != null)
{
return true;
}
@ -308,6 +309,74 @@ public class WrappedStack implements Comparable<WrappedStack>
this.stackSize = stackSize;
}
public static NBTTagCompound toNBTTagCompound(WrappedStack wrappedStack)
{
if (wrappedStack != null && wrappedStack.getWrappedStack() != null)
{
NBTTagCompound wrappedStackTagCompound = new NBTTagCompound();
if (wrappedStack.getWrappedStack() instanceof ItemStack)
{
NBTTagCompound wrappedItemTagCompound = new NBTTagCompound();
((ItemStack) wrappedStack.getWrappedStack()).writeToNBT(wrappedItemTagCompound);
wrappedStackTagCompound.setInteger("objectType", 0);
wrappedStackTagCompound.setTag("wrappedStack", wrappedItemTagCompound);
wrappedStackTagCompound.setInteger("stackSize", wrappedStack.getStackSize());
return wrappedStackTagCompound;
}
else if (wrappedStack.getWrappedStack() instanceof OreStack)
{
NBTTagCompound wrappedOreTagCompound = new NBTTagCompound();
((OreStack) wrappedStack.getWrappedStack()).writeToNBT(wrappedOreTagCompound);
wrappedStackTagCompound.setInteger("objectType", 1);
wrappedStackTagCompound.setTag("wrappedStack", wrappedOreTagCompound);
wrappedStackTagCompound.setInteger("stackSize", wrappedStack.getStackSize());
return wrappedStackTagCompound;
}
else if (wrappedStack.getWrappedStack() instanceof FluidStack)
{
NBTTagCompound wrappedFluidTagCompound = new NBTTagCompound();
((FluidStack) wrappedStack.getWrappedStack()).writeToNBT(wrappedFluidTagCompound);
wrappedStackTagCompound.setInteger("objectType", 2);
wrappedStackTagCompound.setTag("wrappedStack", wrappedFluidTagCompound);
wrappedStackTagCompound.setInteger("stackSize", wrappedStack.getStackSize());
return wrappedStackTagCompound;
}
}
return null;
}
public static WrappedStack fromNBTTagCompound(NBTTagCompound nbtTagCompound)
{
if (nbtTagCompound.hasKey("objectType") && nbtTagCompound.hasKey("wrappedStack") && nbtTagCompound.hasKey("stackSize"))
{
int objectType = nbtTagCompound.getInteger("objectType");
int stackSize = nbtTagCompound.getInteger("stackSize");
if (objectType == 0)
{
ItemStack itemStack = ItemStack.loadItemStackFromNBT(nbtTagCompound.getCompoundTag("wrappedStack"));
return new WrappedStack(itemStack, stackSize);
}
else if (objectType == 1)
{
OreStack oreStack = OreStack.loadOreStackFromNBT(nbtTagCompound.getCompoundTag("wrappedStack"));
return new WrappedStack(oreStack, stackSize);
}
else if (objectType == 2)
{
FluidStack fluidStack = FluidStack.loadFluidStackFromNBT(nbtTagCompound.getCompoundTag("wrappedStack"));
return new WrappedStack(fluidStack, stackSize);
}
else
{
return new WrappedStack();
}
}
return new WrappedStack();
}
/**
*
*/

View file

@ -10,8 +10,6 @@ import net.minecraft.item.ItemStack;
public class PlayerKnowledgeHelper
{
public static boolean canLearnItemStack(ItemStack itemStack, ItemStack alchemicalTomeStack)
{
if (itemStack == null || itemStack.getItem() == null || alchemicalTomeStack == null || !(alchemicalTomeStack.getItem() instanceof ItemAlchemicalTome))

View file

@ -1,9 +1,17 @@
package com.pahimar.ee3.util;
import com.pahimar.ee3.exchange.EnergyValueRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import org.apache.commons.codec.digest.DigestUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -29,4 +37,69 @@ public class SerializationHelper
return DigestUtils.md5Hex(modListString.toString());
}
public static boolean energyValueRegistryFileExist()
{
File dataDirectory = new File(FMLCommonHandler.instance().getMinecraftServerInstance().getEntityWorld().getSaveHandler().getWorldDirectory(), "data" + File.separator + "ee3");
if (!dataDirectory.exists())
{
return false;
}
else if (dataDirectory.isFile())
{
return false;
}
File file = new File(dataDirectory, SerializationHelper.getModListMD5() + ".ee3");
return file.exists() && file.isFile();
}
public static void writeEnergyValueRegistryToFile()
{
File dataDirectory = new File(FMLCommonHandler.instance().getMinecraftServerInstance().getEntityWorld().getSaveHandler().getWorldDirectory(), "data" + File.separator + "ee3");
if (!dataDirectory.exists())
{
dataDirectory.mkdir();
}
NBTTagCompound energyValueRegistryNBT = new NBTTagCompound();
EnergyValueRegistry.getInstance().writeToNBT(energyValueRegistryNBT);
try
{
File file1 = new File(dataDirectory, SerializationHelper.getModListMD5() + ".ee3.tmp");
File file2 = new File(dataDirectory, SerializationHelper.getModListMD5() + ".ee3");
CompressedStreamTools.writeCompressed(energyValueRegistryNBT, new FileOutputStream(file1));
if (file2.exists())
{
file2.delete();
}
file1.renameTo(file2);
}
catch (Exception exception)
{
LogHelper.warn("Failed to save EnergyValueRegistry to file " + dataDirectory.getPath() + SerializationHelper.getModListMD5() + ".ee3");
}
}
public static void readEnergyValueRegistryFromFile()
{
if (energyValueRegistryFileExist())
{
File dataDirectory = new File(FMLCommonHandler.instance().getMinecraftServerInstance().getEntityWorld().getSaveHandler().getWorldDirectory(), "data" + File.separator + "ee3");
File energyValueRegistryFile = new File(dataDirectory, SerializationHelper.getModListMD5() + ".ee3");
try
{
EnergyValueRegistry.getInstance().readFromNBT(CompressedStreamTools.readCompressed(new FileInputStream(energyValueRegistryFile)));
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}