From 06c88806dd24299c7e37e6cce966205753449e13 Mon Sep 17 00:00:00 2001 From: DarkGuardsman Date: Wed, 6 Nov 2013 10:03:29 -0500 Subject: [PATCH] Worked on save manager some more --- src/dark/api/IVirtualObject.java | 4 + src/dark/core/save/NBTFileHelper.java | 45 +++++--- src/dark/core/save/SaveManager.java | 149 ++++++++++++++++++++++++++ 3 files changed, 183 insertions(+), 15 deletions(-) diff --git a/src/dark/api/IVirtualObject.java b/src/dark/api/IVirtualObject.java index f6fb77f0..50b61a8d 100644 --- a/src/dark/api/IVirtualObject.java +++ b/src/dark/api/IVirtualObject.java @@ -13,6 +13,10 @@ public interface IVirtualObject /** File this is saved as, don't create anything here as the manager will do that for you */ public File getSaveFile(); + /** Will only be called after an object has been loaded. Allows the object to know were its been + * loaded from and decide if it wants to use the location as its getSaveFile return */ + public void setSaveFile(File file); + /** Saves the object to NBT */ public void save(NBTTagCompound nbt); diff --git a/src/dark/core/save/NBTFileHelper.java b/src/dark/core/save/NBTFileHelper.java index 49c2e44b..74d30599 100644 --- a/src/dark/core/save/NBTFileHelper.java +++ b/src/dark/core/save/NBTFileHelper.java @@ -90,26 +90,41 @@ public class NBTFileHelper * @return The NBT data */ public static NBTTagCompound loadNBTFile(File saveDirectory, String filename, boolean create) { - try + if (saveDirectory != null && filename != null) { - File file = new File(saveDirectory, filename + ".dat"); - - if (file.exists()) + if(create && !saveDirectory.exists()) { - FMLLog.fine("Loaded " + filename + " data."); - return CompressedStreamTools.readCompressed(new FileInputStream(file)); - } - else if (create) - { - FMLLog.fine("Created new " + filename + " data."); - return new NBTTagCompound(); + saveDirectory.mkdirs(); } + return loadNBTFile(new File(saveDirectory, filename + ".dat"), create); } - catch (Exception e) + return null; + } + + public static NBTTagCompound loadNBTFile(File file, boolean create) + { + if (file != null) { - System.out.println("Failed to load " + filename + ".dat!"); - e.printStackTrace(); - return null; + try + { + + if (file.exists()) + { + FMLLog.fine("Loaded " + file.getName() + " data."); + return CompressedStreamTools.readCompressed(new FileInputStream(file)); + } + else if (create) + { + FMLLog.fine("Created new " + file.getName() + " data."); + return new NBTTagCompound(); + } + } + catch (Exception e) + { + System.out.println("Failed to load " + file.getName() + ".dat!"); + e.printStackTrace(); + return null; + } } return null; } diff --git a/src/dark/core/save/SaveManager.java b/src/dark/core/save/SaveManager.java index 480c3244..060987ae 100644 --- a/src/dark/core/save/SaveManager.java +++ b/src/dark/core/save/SaveManager.java @@ -1,6 +1,155 @@ package dark.core.save; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.logging.Level; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; +import net.minecraftforge.event.ForgeSubscribe; +import net.minecraftforge.event.world.WorldEvent; +import cpw.mods.fml.common.FMLLog; +import dark.api.IVirtualObject; + public class SaveManager { + private static HashMap> idToClassMap = new HashMap>(); + private static HashMap, String> classToIDMap = new HashMap, String>(); + private static List saveList = new ArrayList(); + private static List objects = new ArrayList(); + /** Called when the object wants to be save only on the next save call. Will be removed from the + * save manager after */ + public static void markNeedsSaved(Object object) + { + if (object instanceof IVirtualObject && !saveList.contains(object)) + { + saveList.add(object); + } + } + + /** Registers the object to be saved on each world save event */ + public static void register(Object object) + { + if (object instanceof IVirtualObject && !objects.contains(object)) + { + objects.add(object); + } + } + + public static void registerClass(String id, Class clazz) + { + if (id != null && clazz != null) + { + if (idToClassMap.containsKey(id) && idToClassMap.get(id) != null) + { + System.out.println("[CoreMachine]SaveManager: Something attempted to register a class with the id of another class"); + System.out.println("[CoreMachine]SaveManager: Id:" + id + " Class:" + clazz.getName()); + System.out.println("[CoreMachine]SaveManager: OtherClass:" + idToClassMap.get(id).getName()); + } + else + { + idToClassMap.put(id, clazz); + classToIDMap.put(clazz, id); + } + } + } + + public static Object createAndLoad(File file) + { + if (file.exists()) + { + Object obj = createAndLoad(NBTFileHelper.loadNBTFile(file, false)); + if (obj instanceof IVirtualObject) + { + ((IVirtualObject) obj).setSaveFile(file); + } + return obj; + } + return null; + } + + /** Creates an object from the save using its id */ + public static Object createAndLoad(NBTTagCompound par0NBTTagCompound) + { + Object obj = null; + if (par0NBTTagCompound != null && par0NBTTagCompound.hasKey("id")) + { + try + { + Class clazz = getClass(par0NBTTagCompound.getString("id")); + + if (clazz != null) + { + obj = clazz.newInstance(); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + + if (obj instanceof IVirtualObject) + { + try + { + ((IVirtualObject) obj).load(par0NBTTagCompound); + } + catch (Exception e) + { + FMLLog.log(Level.SEVERE, e, "An object %s(%s) has thrown an exception during loading, its state cannot be restored. Report this to the mod author", par0NBTTagCompound.getString("id"), obj.getClass().getName()); + obj = null; + } + } + else + { + MinecraftServer.getServer().getLogAgent().logWarning("Skipping object with id " + par0NBTTagCompound.getString("id")); + } + + return obj; + } + return null; + } + + @ForgeSubscribe + public void worldSave(WorldEvent evt) + { + SaveManager.saveList.addAll(SaveManager.objects); + for (Object object : SaveManager.saveList) + { + if (object instanceof IVirtualObject) + { + saveObject(object); + } + } + saveList.clear(); + } + + /** Saves an object along with its ID */ + public static void saveObject(Object object) + { + if (object instanceof IVirtualObject && getID(object.getClass()) != null && ((IVirtualObject) object).getSaveFile() != null) + { + File file = ((IVirtualObject) object).getSaveFile(); + file.mkdirs(); + NBTTagCompound tag = new NBTTagCompound(); + ((IVirtualObject) object).save(tag); + tag.setString("id", getID(object.getClass())); + NBTFileHelper.saveNBTFile(file, tag); + } + } + + /** Gets the ID that the class will be saved using */ + public static String getID(Class clazz) + { + return classToIDMap.get(clazz); + } + + /** Gets the class that was registered with the ID */ + public static Class getClass(String id) + { + return idToClassMap.get(id); + } }