Progress on New Save Format

Integrated the base code for our new save format. It still needs more
work but at least some substance is there. Ignore the file not found
messages that come up when trying to save the world's data - since we're
not actually writing files, an exception occurs when we some later code
tries to move non-existent save files.

Also moved the FileFilter functionality out of DungeonHelper and into
its own class, FileFilters, since it's finally needed more broadly.
This commit is contained in:
SenseiKiwi
2013-09-11 22:13:42 -04:00
parent 1d3038288b
commit c2fa4964f8
12 changed files with 397 additions and 93 deletions

View File

@@ -0,0 +1,136 @@
package StevenDimDoors.mod_pocketDim.saving;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.util.FileFilters;
import com.google.common.io.Files;
public class DDSaveHandler
{
public static boolean loadAll()
{
// SenseiKiwi: Loading up our save data is not as simple as just reading files.
// To properly restore dimensions, we need to make sure we always load
// a dimension's parent and root before trying to load it. We'll use
// topological sorting to determine the order in which to recreate the
// dimension objects such that we respect those dependencies.
// Links must be loaded after instantiating all the dimensions and must
// be checked against our dimension blacklist.
// Don't surround this code with try-catch. Our mod should crash if an error
// occurs at this level, since it could lead to some nasty problems.
String basePath = DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/data/";
File dataDirectory = new File(basePath);
// Check if the folder exists. If it doesn't, just return.
if (!dataDirectory.exists())
{
return true;
}
// Load the dimension blacklist
// --insert code here--
// List any dimension data files and read each dimension
DimDataProcessor reader = new DimDataProcessor();
List<PackedDimData> packedDims = new ArrayList<PackedDimData>();
FileFilter dataFileFilter = new FileFilters.RegexFileFilter("dim_-?\\d+\\.txt");
File[] dataFiles = dataDirectory.listFiles(dataFileFilter);
for (File dataFile : dataFiles)
{
PackedDimData packedDim = readDimension(dataFile, reader);
}
return true;
}
private static PackedDimData readDimension(File dataFile, DimDataProcessor reader)
{
try
{
return reader.readFromFile(dataFile);
}
catch (Exception e)
{
System.err.println("Could not read dimension data from: " + dataFile.getAbsolutePath());
System.err.println("The following error occurred:");
printException(e, false);
return null;
}
}
public static boolean saveAll(Iterable<? extends IPackable<PackedDimData>> dimensions) throws IOException
{
// Create the data directory for our dimensions
// Don't catch exceptions here. If we can't create this folder,
// the mod should crash to let the user know early on.
String basePath = DimensionManager.getCurrentSaveRootDirectory() + "/DimensionalDoors/data/";
File basePathFile = new File(basePath);
Files.createParentDirs(basePathFile);
basePathFile = null;
basePath += "dim_";
boolean succeeded = true;
DimDataProcessor writer = new DimDataProcessor();
for (IPackable<PackedDimData> dimension : dimensions)
{
succeeded &= writeDimension(dimension, writer, basePath);
}
return succeeded;
}
private static boolean writeDimension(IPackable<PackedDimData> dimension, DimDataProcessor writer, String basePath)
{
try
{
File tempFile = new File(basePath + (dimension.name() + ".tmp"));
File saveFile = new File(basePath + (dimension.name() + ".txt"));
writer.writeToFile(tempFile, dimension.pack());
saveFile.delete();
tempFile.renameTo(saveFile);
return true;
}
catch (Exception e)
{
System.err.println("Could not save data for dimension #" + dimension.name() + ". The following error occurred:");
printException(e, false);
return false;
}
}
private static void printException(Exception e, boolean verbose)
{
if (e.getCause() == null)
{
if (verbose)
{
e.printStackTrace();
}
else
{
System.err.println(e.getMessage());
}
}
else
{
System.out.println(e.getMessage());
System.err.println("Caused by an underlying error:");
if (verbose)
{
e.getCause().printStackTrace();
}
else
{
System.err.println(e.getCause().getMessage());
}
}
}
}

View File

@@ -0,0 +1,28 @@
package StevenDimDoors.mod_pocketDim.saving;
import java.io.InputStream;
import java.io.OutputStream;
import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor;
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
public class DimDataProcessor extends BaseConfigurationProcessor<PackedDimData>
{
@Override
public PackedDimData readFromStream(InputStream inputStream)
throws ConfigurationProcessingException
{
// TODO Auto-generated method stub
return null;
}
@Override
public void writeToStream(OutputStream outputStream, PackedDimData data)
throws ConfigurationProcessingException
{
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,7 @@
package StevenDimDoors.mod_pocketDim.saving;
public interface IPackable<T>
{
public String name();
public T pack();
}

View File

@@ -0,0 +1,42 @@
package StevenDimDoors.mod_pocketDim.saving;
import java.util.List;
import StevenDimDoors.mod_pocketDim.Point3D;
public class PackedDimData
{
// These fields will be public since this is a simple data container
public final int ID;
public final boolean IsDungeon;
public final boolean IsFilled;
public final int Depth;
public final int PackDepth;
public final int ParentID;
public final int RootID;
public final Point3D Origin;
public final int Orientation;
public final List<Integer> ChildIDs;
public final List<PackedLinkData> Links;
public final List<PackedLinkTail> Tails;
// FIXME Missing dungeon data, not sure how to include it
public PackedDimData(int id, int depth, int packDepth, int parentID, int rootID, int orientation,
boolean isDungeon, boolean isFilled, Point3D origin, List<Integer> childIDs, List<PackedLinkData> links,
List<PackedLinkTail> tails)
{
ID = id;
Depth = depth;
PackDepth = packDepth;
ParentID = parentID;
RootID = rootID;
Orientation = orientation;
IsDungeon = isDungeon;
IsFilled = isFilled;
Origin = origin;
ChildIDs = childIDs;
Links = links;
Tails = tails;
}
}

View File

@@ -0,0 +1,6 @@
package StevenDimDoors.mod_pocketDim.saving;
public class PackedLinkData
{
}

View File

@@ -0,0 +1,6 @@
package StevenDimDoors.mod_pocketDim.saving;
public class PackedLinkTail
{
}