BS 0.0.1 EasySave完成

This commit is contained in:
2025-06-29 01:46:32 +08:00
parent e5bc6a2592
commit 0385ffbd29
15 changed files with 1869 additions and 1992 deletions

View File

@@ -1,7 +1,11 @@
using System; using System;
namespace Convention.EasySave
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property)]
public class EasySaved : Attribute { } public class EasySaved : Attribute { }
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property)] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field | AttributeTargets.Property)]
public class EasySaveIgnored : Attribute { } public class EasySaveIgnored : Attribute { }
}

View File

@@ -2,6 +2,7 @@
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Convention.EasySave.Internal; using Convention.EasySave.Internal;
using Convention.EasySave.Types;
namespace Convention.EasySave namespace Convention.EasySave
{ {
@@ -260,81 +261,6 @@ namespace Convention.EasySave
stream.Write(bytes, 0, bytes.Length); stream.Write(bytes, 0, bytes.Length);
} }
/// <summary>Saves a Texture2D as a PNG or JPG, depending on the file extension used for the filePath.</summary>
/// <param name="texture">The Texture2D we want to save as a JPG or PNG.</param>
/// <param name="imagePath">The relative or absolute path of the PNG or JPG file we want to create.</param>
public static void SaveImage(Texture2D texture, string imagePath)
{
SaveImage(texture, new EasySaveSettings(imagePath));
}
/// <summary>Saves a Texture2D as a PNG or JPG, depending on the file extension used for the filePath.</summary>
/// <param name="texture">The Texture2D we want to save as a JPG or PNG.</param>
/// <param name="imagePath">The relative or absolute path of the PNG or JPG file we want to create.</param>
public static void SaveImage(Texture2D texture, string imagePath, EasySaveSettings settings)
{
SaveImage(texture, new EasySaveSettings(imagePath, settings));
}
/// <summary>Saves a Texture2D as a PNG or JPG, depending on the file extension used for the filePath.</summary>
/// <param name="texture">The Texture2D we want to save as a JPG or PNG.</param>
/// <param name="settings">The settings we want to use to override the default settings.</param>
public static void SaveImage(Texture2D texture, EasySaveSettings settings)
{
SaveImage(texture, 75, settings);
}
/// <summary>Saves a Texture2D as a PNG or JPG, depending on the file extension used for the filePath.</summary>
/// <param name="texture">The Texture2D we want to save as a JPG or PNG.</param>
/// <param name="quality">Quality to encode with, where 1 is minimum and 100 is maximum. Note that this only applies to JPGs.</param>
/// <param name="imagePath">The relative or absolute path of the PNG or JPG file we want to create.</param>
public static void SaveImage(Texture2D texture, int quality, string imagePath)
{
SaveImage(texture, quality, new EasySaveSettings(imagePath));
}
/// <summary>Saves a Texture2D as a PNG or JPG, depending on the file extension used for the filePath.</summary>
/// <param name="texture">The Texture2D we want to save as a JPG or PNG.</param>
/// <param name="quality">Quality to encode with, where 1 is minimum and 100 is maximum. Note that this only applies to JPGs.</param>
/// <param name="imagePath">The relative or absolute path of the PNG or JPG file we want to create.</param>
public static void SaveImage(Texture2D texture, int quality, string imagePath, EasySaveSettings settings)
{
SaveImage(texture, quality, new EasySaveSettings(imagePath, settings));
}
/// <summary>Saves a Texture2D as a PNG or JPG, depending on the file extension used for the filePath.</summary>
/// <param name="texture">The Texture2D we want to save as a JPG or PNG.</param>
/// <param name="quality">Quality to encode with, where 1 is minimum and 100 is maximum. Note that this only applies to JPGs.</param>
/// <param name="settings">The settings we want to use to override the default settings.</param>
public static void SaveImage(Texture2D texture, int quality, EasySaveSettings settings)
{
// Get the file extension to determine what format we want to save the image as.
string extension = EasySaveIO.GetExtension(settings.path).ToLower();
if (string.IsNullOrEmpty(extension))
throw new System.ArgumentException("File path must have a file extension when using EasySave.SaveImage.");
byte[] bytes;
if (extension == ".jpg" || extension == ".jpeg")
bytes = texture.EncodeToJPG(quality);
else if (extension == ".png")
bytes = texture.EncodeToPNG();
else
throw new System.ArgumentException("File path must have extension of .png, .jpg or .jpeg when using EasySave.SaveImage.");
EasySave.SaveRaw(bytes, settings);
}
/// <summary>Saves a Texture2D as a PNG or JPG, depending on the file extension used for the filePath.</summary>
/// <param name="texture">The Texture2D we want to save as a JPG or PNG.</param>
/// <param name="quality">Quality to encode with, where 1 is minimum and 100 is maximum. Note that this only applies to JPGs.</param>
public static byte[] SaveImageToBytes(Texture2D texture, int quality, EasySave.ImageType imageType)
{
if (imageType == ImageType.JPEG)
return texture.EncodeToJPG(quality);
else
return texture.EncodeToPNG();
}
#endregion #endregion
#region EasySave.Load<T> #region EasySave.Load<T>
@@ -720,7 +646,7 @@ namespace Convention.EasySave
return Serialize(value, EasySaveTypeMgr.GetOrCreateEasySaveType(typeof(T)), settings); return Serialize(value, EasySaveTypeMgr.GetOrCreateEasySaveType(typeof(T)), settings);
} }
internal static byte[] Serialize(object value, Convention.EasySave.Types.EasySaveType type, EasySaveSettings settings = null) internal static byte[] Serialize(object value, EasySaveType type, EasySaveSettings settings = null)
{ {
if (settings == null) settings = new EasySaveSettings(); if (settings == null) settings = new EasySaveSettings();
@@ -745,7 +671,7 @@ namespace Convention.EasySave
return (T)Deserialize(EasySaveTypeMgr.GetOrCreateEasySaveType(typeof(T)), bytes, settings); return (T)Deserialize(EasySaveTypeMgr.GetOrCreateEasySaveType(typeof(T)), bytes, settings);
} }
internal static object Deserialize(Convention.EasySave.Types.EasySaveType type, byte[] bytes, EasySaveSettings settings = null) internal static object Deserialize(EasySaveType type, byte[] bytes, EasySaveSettings settings = null)
{ {
if (settings == null) if (settings == null)
settings = new EasySaveSettings(); settings = new EasySaveSettings();
@@ -761,7 +687,7 @@ namespace Convention.EasySave
DeserializeInto(EasySaveTypeMgr.GetOrCreateEasySaveType(typeof(T)), bytes, obj, settings); DeserializeInto(EasySaveTypeMgr.GetOrCreateEasySaveType(typeof(T)), bytes, obj, settings);
} }
public static void DeserializeInto<T>(Convention.EasySave.Types.EasySaveType type, byte[] bytes, T obj, EasySaveSettings settings = null) where T : class public static void DeserializeInto<T>(EasySaveType type, byte[] bytes, T obj, EasySaveSettings settings = null) where T : class
{ {
if (settings == null) if (settings == null)
settings = new EasySaveSettings(); settings = new EasySaveSettings();

View File

@@ -6,6 +6,9 @@ using Convention.EasySave.Types;
using Convention.EasySave.Internal; using Convention.EasySave.Internal;
using System.Linq; using System.Linq;
namespace Convention.EasySave
{
/// <summary>Represents a cached file which can be saved to and loaded from, and commited to storage when necessary.</summary> /// <summary>Represents a cached file which can be saved to and loaded from, and commited to storage when necessary.</summary>
public class EasySaveFile public class EasySaveFile
{ {
@@ -493,7 +496,7 @@ public class EasySaveFile
} }
} }
namespace Convention.EasySave.Internal namespace Internal
{ {
public struct EasySaveData public struct EasySaveData
{ {
@@ -513,3 +516,4 @@ namespace Convention.EasySave.Internal
} }
} }
} }
}

View File

@@ -52,7 +52,7 @@ namespace Convention.EasySave.Internal
// This obviously won't work if exceptions are disabled. // This obviously won't work if exceptions are disabled.
try try
{ {
if (assemblyNames.Contains(assembly.GetName().Name)) //if (assemblyNames.Contains(assembly.GetName().Name))
assemblyList.Add(assembly); assemblyList.Add(assembly);
} }
catch { } catch { }

View File

@@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using Convention.EasySave.Internal; using Convention.EasySave.Internal;
namespace Convention.EasySave
{
public class EasySaveSpreadsheet public class EasySaveSpreadsheet
{ {
private int cols = 0; private int cols = 0;
@@ -299,3 +301,4 @@ public class EasySaveSpreadsheet
} }
} }
} }
}

View File

@@ -6,6 +6,8 @@ using System.ComponentModel;
using Convention.EasySave.Types; using Convention.EasySave.Types;
using Convention.EasySave.Internal; using Convention.EasySave.Internal;
namespace Convention.EasySave
{
public abstract class EasySaveReader : System.IDisposable public abstract class EasySaveReader : System.IDisposable
{ {
/// <summary>The settings used to create this reader.</summary> /// <summary>The settings used to create this reader.</summary>
@@ -452,3 +454,4 @@ public abstract class EasySaveReader : System.IDisposable
} }
} }
} }
}

View File

@@ -1,6 +1,10 @@
public class EasySaveDefaults using Convention.EasySave;
namespace Convention.EasySave
{ {
public EasySaveSerializableSettings settings = new EasySaveSerializableSettings(); public class EasySaveDefaults
{
public EasySaveSettings settings = new EasySaveSerializableSettings();
public bool addMgrToSceneAutomatically = false; public bool addMgrToSceneAutomatically = false;
public bool autoUpdateReferences = true; public bool autoUpdateReferences = true;
@@ -16,3 +20,4 @@
public bool logWarnings = true; public bool logWarnings = true;
public bool logErrors = true; public bool logErrors = true;
} }
}

View File

@@ -1,5 +1,7 @@
using Convention.EasySave.Internal; using Convention.EasySave.Internal;
namespace Convention.EasySave
{
public class EasySaveSettings : System.ICloneable public class EasySaveSettings : System.ICloneable
{ {
@@ -14,35 +16,7 @@ public class EasySaveSettings : System.ICloneable
{ {
if (_defaultSettingsScriptableObject == null) if (_defaultSettingsScriptableObject == null)
{ {
_defaultSettingsScriptableObject = Resources.Load<EasySaveDefaults>(defaultSettingsPath); _defaultSettingsScriptableObject = new();
#if UNITY_EDITOR
if (_defaultSettingsScriptableObject == null)
{
_defaultSettingsScriptableObject = ScriptableObject.CreateInstance<ES3Defaults>();
// If this is the version being submitted to the Asset Store, don't include ES3Defaults.
if (Application.productName.Contains("EasySave Release"))
{
Debug.Log("This has been identified as a release build as the title contains 'EasySave Release', so ES3Defaults will not be created.");
return _defaultSettingsScriptableObject;
}
// Convert the old settings to the new settings if necessary.
var oldSettings = GetOldSettings();
if (oldSettings != null)
{
oldSettings.CopyInto(_defaultSettingsScriptableObject.settings);
// Only enable warning logs by default for new installs as this may look like unexpected behaviour to some.
_defaultSettingsScriptableObject.logWarnings = false;
RemoveOldSettings();
}
CreateDefaultSettingsFolder();
AssetDatabase.CreateAsset(_defaultSettingsScriptableObject, PathToDefaultSettings());
AssetDatabase.SaveAssets();
}
#endif
} }
return _defaultSettingsScriptableObject; return _defaultSettingsScriptableObject;
} }
@@ -78,15 +52,12 @@ public class EasySaveSettings : System.ICloneable
private static readonly string[] resourcesExtensions = new string[] { ".txt", ".htm", ".html", ".xml", ".bytes", ".json", ".csv", ".yaml", ".fnt" }; private static readonly string[] resourcesExtensions = new string[] { ".txt", ".htm", ".html", ".xml", ".bytes", ".json", ".csv", ".yaml", ".fnt" };
[SerializeField]
private EasySave.Location _location; private EasySave.Location _location;
/// <summary>The location where we wish to store data. As it's not possible to save/load from File in WebGL, if the default location is File it will use PlayerPrefs instead.</summary> /// <summary>The location where we wish to store data. As it's not possible to save/load from File in WebGL, if the default location is File it will use PlayerPrefs instead.</summary>
public EasySave.Location location public EasySave.Location location
{ {
get get
{ {
if(_location == EasySave.Location.File && (Application.platform == RuntimePlatform.WebGLPlayer || Application.platform == RuntimePlatform.tvOS))
return EasySave.Location.PlayerPrefs;
return _location; return _location;
} }
set { _location = value; } set { _location = value; }
@@ -153,30 +124,9 @@ public class EasySaveSettings : System.ICloneable
if (directory == EasySave.Directory.PersistentDataPath) if (directory == EasySave.Directory.PersistentDataPath)
return EasySaveIO.persistentDataPath + "/" + path; return EasySaveIO.persistentDataPath + "/" + path;
if (directory == EasySave.Directory.DataPath) if (directory == EasySave.Directory.DataPath)
return Application.dataPath + "/" + path; return PlatformIndicator.DataPath + "/" + path;
throw new System.NotImplementedException("File directory \"" + directory + "\" has not been implemented."); throw new System.NotImplementedException("File directory \"" + directory + "\" has not been implemented.");
} }
if(location == EasySave.Location.Resources)
{
// Check that it has valid extension
var extension = System.IO.Path.GetExtension(path);
bool hasValidExtension = false;
foreach (var ext in resourcesExtensions)
{
if (extension == ext)
{
hasValidExtension = true;
break;
}
}
if(!hasValidExtension)
throw new System.ArgumentException("Extension of file in Resources must be .json, .bytes, .txt, .csv, .htm, .html, .xml, .yaml or .fnt, but path given was \"" + path + "\"");
// Remove extension
string resourcesPath = path.Replace(extension, "");
return resourcesPath;
}
return path; return path;
} }
} }
@@ -371,3 +321,4 @@ public class EasySaveSerializableSettings : EasySaveSettings
public EasySaveSerializableSettings(string path) : base(false) { this.path = path; } public EasySaveSerializableSettings(string path) : base(false) { this.path = path; }
public EasySaveSerializableSettings(string path, EasySave.Location location) : base(false) { this.location = location; } public EasySaveSerializableSettings(string path, EasySave.Location location) : base(false) { this.location = location; }
} }
}

View File

@@ -32,7 +32,7 @@ namespace Convention.EasySave.Internal
return CreateStream(stream, settings, fileMode); return CreateStream(stream, settings, fileMode);
} }
catch(System.Exception e) catch(Exception)
{ {
if (stream != null) if (stream != null)
stream.Dispose(); stream.Dispose();

View File

@@ -60,9 +60,6 @@ namespace Convention.EasySave.Types
{ {
var collection = (IList)obj; var collection = (IList)obj;
if (collection.Count == 0)
ES3Debug.LogWarning("LoadInto/ReadInto expects a collection containing instances to load data in to, but the collection is empty.");
if(reader.StartReadCollection()) if(reader.StartReadCollection())
throw new NullReferenceException("The Collection we are trying to load is stored as null, which is not allowed when using ReadInto methods."); throw new NullReferenceException("The Collection we are trying to load is stored as null, which is not allowed when using ReadInto methods.");

View File

@@ -32,7 +32,7 @@ namespace Convention.EasySave.Types
{ {
var array = ReadAsArray(reader); var array = ReadAsArray(reader);
return EasySaveReflection.CreateInstance(type, new object[] { array, Allocator.Persistent }); return EasySaveReflection.CreateInstance(type, new object[] { array/*, Allocator.Persistent*/ });
} }
public override object Read<T>(EasySaveReader reader) public override object Read<T>(EasySaveReader reader)

View File

@@ -19,7 +19,6 @@ namespace Convention.EasySave.Types
public bool isDictionary = false; public bool isDictionary = false;
public bool isTuple = false; public bool isTuple = false;
public bool isEnum = false; public bool isEnum = false;
public bool isES3TypeUnityObject = false;
public bool isReflectedType = false; public bool isReflectedType = false;
public bool isUnsupported = false; public bool isUnsupported = false;
public int priority = 0; public int priority = 0;

View File

@@ -88,8 +88,6 @@ namespace Convention.EasySave.Internal
es3Type = new EasySaveStackType(type); es3Type = new EasySaveStackType(type);
else if (genericType == typeof(HashSet<>)) else if (genericType == typeof(HashSet<>))
es3Type = new EasySaveHashSetType(type); es3Type = new EasySaveHashSetType(type);
else if (genericType == typeof(Unity.Collections.NativeArray<>))
es3Type = new EasySaveNativeArrayType(type);
else if (throwException) else if (throwException)
throw new NotSupportedException("Generic type \"" + type.ToString() + "\" is not supported by Easy Save."); throw new NotSupportedException("Generic type \"" + type.ToString() + "\" is not supported by Easy Save.");
else else
@@ -104,20 +102,8 @@ namespace Convention.EasySave.Internal
} }
else else
{ {
if (EasySaveReflection.IsAssignableFrom(typeof(Component), type)) if (type.Name.StartsWith("Tuple`"))
es3Type = new ES3ReflectedComponentType(type);
else if (EasySaveReflection.IsValueType(type))
es3Type = new EasySaveReflectedValueType(type);
else if (EasySaveReflection.IsAssignableFrom(typeof(ScriptableObject), type))
es3Type = new ES3ReflectedScriptableObjectType(type);
else if (EasySaveReflection.IsAssignableFrom(typeof(UnityEngine.Object), type))
es3Type = new ES3ReflectedUnityObjectType(type);
/*else if (EasySaveReflection.HasParameterlessConstructor(type) || EasySaveReflection.IsAbstract(type) || EasySaveReflection.IsInterface(type))
es3Type = new EasySaveReflectedObjectType(type);*/
else if (type.Name.StartsWith("Tuple`"))
es3Type = new EasySaveTupleType(type); es3Type = new EasySaveTupleType(type);
/*else if (throwException)
throw new NotSupportedException("Type of " + type + " is not supported as it does not have a parameterless constructor. Only value types, Components or ScriptableObjects are supportable without a parameterless constructor. However, you may be able to create an EasySaveType script to add support for it.");*/
else else
es3Type = new EasySaveReflectedObjectType(type); es3Type = new EasySaveReflectedObjectType(type);
} }

View File

@@ -5,6 +5,8 @@ using System;
using Convention.EasySave.Types; using Convention.EasySave.Types;
using Convention.EasySave.Internal; using Convention.EasySave.Internal;
namespace Convention.EasySave
{
public abstract class EasySaveWriter : IDisposable public abstract class EasySaveWriter : IDisposable
{ {
public EasySaveSettings settings; public EasySaveSettings settings;
@@ -217,17 +219,9 @@ public abstract class EasySaveWriter : IDisposable
} }
else else
{ {
throw new NotImplementedException(); StartWriteObject(null);
//if (type.type == typeof(GameObject)) type.Write(value, this);
// ((ES3Type_GameObject)type).saveChildren = settings.saveChildren; EndWriteObject(null);
//StartWriteObject(null);
//if (type.isES3TypeUnityObject)
// ((ES3UnityObjectType)type).WriteObject(value, this, memberReferenceMode);
//else
// type.Write(value, this);
//EndWriteObject(null);
} }
} }
@@ -444,3 +438,4 @@ public abstract class EasySaveWriter : IDisposable
EasySaveIO.CommitBackup(settings); EasySaveIO.CommitBackup(settings);
} }
} }
}

View File

@@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Threading; using System.Threading;
using Convention; using Convention;
using Convention.EasySave;
public class Program public class Program
{ {
@@ -17,6 +19,8 @@ public class Program
static void Main(string[] args) static void Main(string[] args)
{ {
Directory.CreateDirectory(PlatformIndicator.PersistentDataPath);
Console.WriteLine(PlatformIndicator.PersistentDataPath);
EasySave.Save("key", new Vector2X2() EasySave.Save("key", new Vector2X2()
{ {
x = 10, x = 10,