A game about forced loneliness, made by TACStudios
at master 6.7 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Globalization; 4using System.Reflection; 5using UnityEditor.ShaderGraph.Serialization; 6using UnityEngine; 7 8namespace UnityEditor.Graphing 9{ 10 static class SerializationHelper 11 { 12 [Serializable] 13 public struct TypeSerializationInfo 14 { 15 [SerializeField] 16 public string fullName; 17 18 public bool IsValid() 19 { 20 return !string.IsNullOrEmpty(fullName); 21 } 22 } 23 24 [Serializable] 25 public struct JSONSerializedElement 26 { 27 [SerializeField] 28 public TypeSerializationInfo typeInfo; 29 30 [SerializeField] 31 public string JSONnodeData; 32 } 33 34 public static JSONSerializedElement nullElement 35 { 36 get 37 { 38 return new JSONSerializedElement(); 39 } 40 } 41 42 public static TypeSerializationInfo GetTypeSerializableAsString(Type type) 43 { 44 return new TypeSerializationInfo 45 { 46 fullName = type.FullName 47 }; 48 } 49 50 static Type GetTypeFromSerializedString(TypeSerializationInfo typeInfo) 51 { 52 if (!typeInfo.IsValid()) 53 return null; 54 55 var assemblies = AppDomain.CurrentDomain.GetAssemblies(); 56 foreach (var assembly in assemblies) 57 { 58 var type = assembly.GetType(typeInfo.fullName); 59 if (type != null) 60 return type; 61 } 62 63 return null; 64 } 65 66 public static JSONSerializedElement Serialize<T>(T item) 67 { 68 if (item is JsonObject jsonObject) 69 return new JSONSerializedElement() { JSONnodeData = jsonObject.Serialize() }; 70 71 if (item == null) 72 throw new ArgumentNullException("item", "Can not serialize null element"); 73 74 //check if unknownnode type - if so, return saved metadata 75 //unknown node type will need onbeforeserialize to set guid and edges and all the things 76 var typeInfo = GetTypeSerializableAsString(item.GetType()); 77 var data = JsonUtility.ToJson(item, true); 78 79 if (string.IsNullOrEmpty(data)) 80 throw new ArgumentException(string.Format("Can not serialize {0}", item)); 81 82 83 return new JSONSerializedElement 84 { 85 typeInfo = typeInfo, 86 JSONnodeData = data 87 }; 88 } 89 90 static TypeSerializationInfo DoTypeRemap(TypeSerializationInfo info, Dictionary<TypeSerializationInfo, TypeSerializationInfo> remapper) 91 { 92 TypeSerializationInfo foundInfo; 93 if (remapper.TryGetValue(info, out foundInfo)) 94 return foundInfo; 95 return info; 96 } 97 98 public static T Deserialize<T>(JSONSerializedElement item, Dictionary<TypeSerializationInfo, TypeSerializationInfo> remapper, params object[] constructorArgs) where T : class 99 { 100 T instance; 101 if (typeof(T) == typeof(JsonObject) || typeof(T).IsSubclassOf(typeof(JsonObject))) 102 { 103 try 104 { 105 var culture = CultureInfo.CurrentCulture; 106 var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; 107 instance = Activator.CreateInstance(typeof(T), flags, null, constructorArgs, culture) as T; 108 } 109 catch (Exception e) 110 { 111 throw new Exception(string.Format("Could not construct instance of: {0}", typeof(T)), e); 112 } 113 114 MultiJson.Deserialize(instance as JsonObject, item.JSONnodeData); 115 return instance; 116 } 117 118 if (!item.typeInfo.IsValid() || string.IsNullOrEmpty(item.JSONnodeData)) 119 throw new ArgumentException(string.Format("Can not deserialize {0}, it is invalid", item)); 120 121 TypeSerializationInfo info = item.typeInfo; 122 info.fullName = info.fullName.Replace("UnityEngine.MaterialGraph", "UnityEditor.ShaderGraph"); 123 info.fullName = info.fullName.Replace("UnityEngine.Graphing", "UnityEditor.Graphing"); 124 if (remapper != null) 125 info = DoTypeRemap(info, remapper); 126 127 var type = GetTypeFromSerializedString(info); 128 //if type is null but T is an abstract material node, instead we create an unknowntype node 129 if (type == null) 130 { 131 throw new ArgumentException(string.Format("Can not deserialize ({0}), type is invalid", info.fullName)); 132 } 133 134 try 135 { 136 var culture = CultureInfo.CurrentCulture; 137 var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; 138 instance = Activator.CreateInstance(type, flags, null, constructorArgs, culture) as T; 139 } 140 catch (Exception e) 141 { 142 throw new Exception(string.Format("Could not construct instance of: {0}", type), e); 143 } 144 145 if (instance != null) 146 { 147 JsonUtility.FromJsonOverwrite(item.JSONnodeData, instance); 148 return instance; 149 } 150 Debug.Log("UhOh"); 151 return null; 152 } 153 154 public static List<JSONSerializedElement> Serialize<T>(IEnumerable<T> list) 155 { 156 var result = new List<JSONSerializedElement>(); 157 if (list == null) 158 return result; 159 160 foreach (var element in list) 161 { 162 try 163 { 164 result.Add(Serialize(element)); 165 } 166 catch (Exception e) 167 { 168 Debug.LogException(e); 169 } 170 } 171 return result; 172 } 173 174 public static List<T> Deserialize<T>(IEnumerable<JSONSerializedElement> list, Dictionary<TypeSerializationInfo, TypeSerializationInfo> remapper, params object[] constructorArgs) where T : class 175 { 176 var result = new List<T>(); 177 if (list == null) 178 return result; 179 180 foreach (var element in list) 181 { 182 try 183 { 184 result.Add(Deserialize<T>(element, remapper)); 185 } 186 catch (Exception e) 187 { 188 Debug.LogException(e); 189 Debug.LogError(element.JSONnodeData); 190 } 191 } 192 return result; 193 } 194 } 195}