From a2f2cea246f693a1195448149daff1e96adfd8ed Mon Sep 17 00:00:00 2001 From: Cory Leach Date: Wed, 20 Oct 2021 16:49:28 -0500 Subject: [PATCH 1/2] Addition of Copy method to ISerializationMethod interface. Added Copy method to SaveLoadManager to allow objects to be duplicated via serialization. --- Runtime/ISerializationMethod.cs | 1 + Runtime/SaveLoadManager.cs | 23 +++++++++++++++ Runtime/SerializationMethodBinary.cs | 12 ++++++++ Runtime/SerializationMethodBinaryEncrypted.cs | 11 ++++++++ Runtime/SerializationMethodJsonDotNet.cs | 20 +++++++++++++ .../SerializationMethodJsonDotNetEncrypted.cs | 21 ++++++++++++++ Runtime/SerializationMethodUnityJson.cs | 21 ++++++++++++++ .../SerializationMethodUnityJsonEncrypted.cs | 23 ++++++++++++++- Tests/Runtime/SaveLoadManagerTests.cs | 28 +++++++++++++++++++ 9 files changed, 159 insertions(+), 1 deletion(-) diff --git a/Runtime/ISerializationMethod.cs b/Runtime/ISerializationMethod.cs index 4dd4efb..b4b18d2 100644 --- a/Runtime/ISerializationMethod.cs +++ b/Runtime/ISerializationMethod.cs @@ -9,6 +9,7 @@ public interface ISerializationMethod { void Save(object savedObject, FileStream fileStream); object Load(System.Type savedObjectType, FileStream fileStream); + object Copy(object copyObject); } } diff --git a/Runtime/SaveLoadManager.cs b/Runtime/SaveLoadManager.cs index 58e31a8..c46f557 100644 --- a/Runtime/SaveLoadManager.cs +++ b/Runtime/SaveLoadManager.cs @@ -73,6 +73,29 @@ public void Save(object obj, string filename, string folder = null) var saveLoadMethod = GetSaveLoadMethod(saveMethod); SaveLoadUtility.Save(obj,saveLoadMethod,filename,folder, baseFolder); } + + /// + /// Creat a copy of an object by serializing and deserializing it + /// + /// object to be copied + /// duplicated instance + public object Copy(object obj) + { + var saveLoadMethod = GetSaveLoadMethod(saveMethod); + return saveLoadMethod.Copy(obj); + } + + /// + /// Creat a copy of an object by serializing and deserializing it + /// + /// object to be copied + /// Type of object to be copied. + /// duplicated instance + public T Copy(T obj) + { + var saveLoadMethod = GetSaveLoadMethod(saveMethod); + return (T)saveLoadMethod.Copy(obj); + } /// /// Load an object from disk diff --git a/Runtime/SerializationMethodBinary.cs b/Runtime/SerializationMethodBinary.cs index 28f0f38..51df710 100644 --- a/Runtime/SerializationMethodBinary.cs +++ b/Runtime/SerializationMethodBinary.cs @@ -32,6 +32,18 @@ public object Load(Type savedObjectType, FileStream fileStream) loadedObj = formatter.Deserialize(fileStream); return loadedObj; } + + public object Copy(object copyObject) + { + using (var stream = new MemoryStream()) + { + var formatter = new BinaryFormatter(); + formatter.Serialize(stream, copyObject); + stream.Position = 0; + return formatter.Deserialize(stream); + } + } + } } diff --git a/Runtime/SerializationMethodBinaryEncrypted.cs b/Runtime/SerializationMethodBinaryEncrypted.cs index 1db27a9..5003340 100644 --- a/Runtime/SerializationMethodBinaryEncrypted.cs +++ b/Runtime/SerializationMethodBinaryEncrypted.cs @@ -58,6 +58,17 @@ public void SetEncryption(string key, string salt) _key = key; _salt = salt; } + + public object Copy(object copyObject) + { + using (var stream = new MemoryStream()) + { + var formatter = new BinaryFormatter(); + formatter.Serialize(stream, copyObject); + stream.Position = 0; + return formatter.Deserialize(stream); + } + } } } diff --git a/Runtime/SerializationMethodJsonDotNet.cs b/Runtime/SerializationMethodJsonDotNet.cs index 399f4fb..ffa38dd 100644 --- a/Runtime/SerializationMethodJsonDotNet.cs +++ b/Runtime/SerializationMethodJsonDotNet.cs @@ -31,6 +31,26 @@ public object Load(Type savedObjectType, FileStream fileStream) return loadedObj; } + + public object Copy(object copyObject) + { + using (var stream = new MemoryStream()) + { + var writeJson = JsonConvert.SerializeObject(copyObject); + + var streamWriter = new StreamWriter(stream); + streamWriter.Write(writeJson); + streamWriter.Flush(); + + stream.Position = 0; + + using (var streamReader = new StreamReader(stream)) + { + var readJson = streamReader.ReadToEnd(); + return JsonConvert.DeserializeObject(readJson, copyObject.GetType()); + } + } + } } } diff --git a/Runtime/SerializationMethodJsonDotNetEncrypted.cs b/Runtime/SerializationMethodJsonDotNetEncrypted.cs index 3ce072b..270bdd7 100644 --- a/Runtime/SerializationMethodJsonDotNetEncrypted.cs +++ b/Runtime/SerializationMethodJsonDotNetEncrypted.cs @@ -66,6 +66,27 @@ public void SetEncryption(string key, string salt) _key = key; _salt = salt; } + + public object Copy(object copyObject) + { + using (var stream = new MemoryStream()) + { + var writeJson = JsonConvert.SerializeObject(copyObject); + + var streamWriter = new StreamWriter(stream); + streamWriter.Write(writeJson); + streamWriter.Flush(); + + stream.Position = 0; + + using (var streamReader = new StreamReader(stream)) + { + var readJson = streamReader.ReadToEnd(); + return JsonConvert.DeserializeObject(readJson, copyObject.GetType()); + } + } + } + } } diff --git a/Runtime/SerializationMethodUnityJson.cs b/Runtime/SerializationMethodUnityJson.cs index 512c347..f0d40b6 100644 --- a/Runtime/SerializationMethodUnityJson.cs +++ b/Runtime/SerializationMethodUnityJson.cs @@ -30,6 +30,27 @@ public object Load(Type savedObjectType, FileStream fileStream) return loadedObj; } + + public object Copy(object copyObject) + { + using (var stream = new MemoryStream()) + { + var writeJson = JsonUtility.ToJson(copyObject); + var streamWriter = new StreamWriter(stream); + streamWriter.Write(writeJson); + streamWriter.Flush(); + + stream.Position = 0; + + using (var streamReader = new StreamReader(stream)) + { + var readJson = streamReader.ReadToEnd(); + streamReader.Close(); + return JsonUtility.FromJson(readJson, copyObject.GetType()); + } + } + } + } } diff --git a/Runtime/SerializationMethodUnityJsonEncrypted.cs b/Runtime/SerializationMethodUnityJsonEncrypted.cs index acf030d..e09cc46 100644 --- a/Runtime/SerializationMethodUnityJsonEncrypted.cs +++ b/Runtime/SerializationMethodUnityJsonEncrypted.cs @@ -16,7 +16,7 @@ public SerializationMethodUnityJsonEncrypted(string key, string salt) public void Save(object savedObject, FileStream fileStream) { - //TODO: Using Unity's json serializer... does not support dictionaries. Do better. + //Note: Use JsonDotNet method for Dictionary serialization var json = JsonUtility.ToJson(savedObject); using (var memoryStream = new MemoryStream()) { @@ -64,6 +64,27 @@ public void SetEncryption(string key, string salt) _key = key; _salt = salt; } + + public object Copy(object copyObject) + { + using (var stream = new MemoryStream()) + { + var writeJson = JsonUtility.ToJson(copyObject); + var streamWriter = new StreamWriter(stream); + streamWriter.Write(writeJson); + streamWriter.Flush(); + + stream.Position = 0; + + using (var streamReader = new StreamReader(stream)) + { + var readJson = streamReader.ReadToEnd(); + streamReader.Close(); + return JsonUtility.FromJson(readJson, copyObject.GetType()); + } + } + } + } } diff --git a/Tests/Runtime/SaveLoadManagerTests.cs b/Tests/Runtime/SaveLoadManagerTests.cs index e43b476..bf3401c 100644 --- a/Tests/Runtime/SaveLoadManagerTests.cs +++ b/Tests/Runtime/SaveLoadManagerTests.cs @@ -113,6 +113,34 @@ public void CanSaveAndLoad([Values] SerializationMethodType method) Object.Destroy(manager); } + [Test] + public void CanCopy([Values] SerializationMethodType method) + { + var manager = CreateManager(method); + + var testObject = new SaveLoadTestObject() + { + listOfStrings = new List {"one", "two"}, + count = 10, + }; + + var loadedObject = manager.Copy(testObject); + + Assert.NotNull(loadedObject); + Assert.IsFalse(ReferenceEquals(testObject,loadedObject)); + Assert.NotNull(loadedObject.listOfStrings); + Assert.IsTrue(loadedObject.listOfStrings.Count == testObject.listOfStrings.Count); + + for (int i = 0; i < testObject.listOfStrings.Count; i++) + { + Assert.IsTrue(testObject.listOfStrings[i] == loadedObject.listOfStrings[i]); + } + + Assert.IsTrue(testObject.count == loadedObject.count); + + Object.Destroy(manager); + } + [Test] public void LoadReturnsNullWhenFileDoesnotExist([Values] SerializationMethodType method) { From f63c320a6189c798aee4929782944d7107db0448 Mon Sep 17 00:00:00 2001 From: Cory Leach Date: Wed, 20 Oct 2021 17:57:22 -0500 Subject: [PATCH 2/2] Version Bump --- README.md | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e20db8e..d74d7a5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

Gameframe.SaveLoad 👋

- Version + Version Twitter: coryleach @@ -13,7 +13,7 @@ Serialization helper utility that supports save, load and encryption. #### Using UnityPackageManager (for Unity 2019.3 or later) Open the package manager window (menu: Window > Package Manager)
Select "Add package from git URL...", fill in the pop-up with the following link:
-https://github.com/coryleach/UnitySaveLoad.git#1.0.3
+https://github.com/coryleach/UnitySaveLoad.git#1.0.4
#### Using UnityPackageManager (for Unity 2019.1 or later) @@ -21,7 +21,7 @@ Find the manifest.json file in the Packages folder of your project and edit it t ```js { "dependencies": { - "com.gameframe.saveload": "https://github.com/coryleach/UnitySaveLoad.git#1.0.3", + "com.gameframe.saveload": "https://github.com/coryleach/UnitySaveLoad.git#1.0.4", ... }, } diff --git a/package.json b/package.json index c5268f1..f4b6173 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.gameframe.saveload", "displayName": "Gameframe.SaveLoad", - "version": "1.0.3", + "version": "1.0.4", "description": "Serialization helper utility that supports save, load and encryption.", "keywords": [], "author": {