public static GameObject[] Unpack(byte[] bytes, UABConfig config = null, List <ISerializer> serializers = null) { var unzipped = Zipper.UnzipString(bytes); var dataDeserialized = UABSerializer.DeserializeValueType <UABPackage>(unzipped); return(Builder.Unpack(dataDeserialized, config, serializers)); }
public static byte[] PackToBytes(GameObject[] objects, UABConfig config = null, List <ISerializer> serializers = null) { var package = Builder.Pack(objects, config, serializers); var dataSerialized = UABSerializer.SerializeValueType(package); var zipped = Zipper.ZipString(dataSerialized); return(zipped); }
public object Deserialize(object component, UABField[] data, List <ISerializer> serializers) { if (UABSerializer.HasProperties(component) == true) { var fields = component.GetType().GetAllProperties() .Where(x => x.GetCustomAttributes(true).Any(a => a is System.ObsoleteAttribute) == false && x.CanWrite == true && UABSerializer.FilterProperties(x) == true).ToArray(); //var fields = component.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.SetProperty | System.Reflection.BindingFlags.Instance); //if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) UnityEngine.Debug.Log(component + " :: " + UABSerializer.HasProperties(component) + " :: " + fields.Length); for (int i = 0; i < data.Length; ++i) { var fieldInfo = fields.FirstOrDefault(x => x.Name == data[i].name); if (fieldInfo != null) { fieldInfo.SetValue(component, this.Unpack(component, fieldInfo.PropertyType, data[i], serializers), null); } else { if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) { UnityEngine.Debug.LogWarningFormat("Property with the name `{0}` was not found on property deserialization stage. Be sure you have no per-platform #ifdef directives in your scripts. Skipped.", data[i].name); } } } } else { var fields = component.GetType().GetAllFields(); for (int i = 0; i < data.Length; ++i) { var fieldInfo = fields.FirstOrDefault(x => x.Name == data[i].name); if (fieldInfo != null) { fieldInfo.SetValue(component, this.Unpack(component, fieldInfo.FieldType, data[i], serializers)); } else { if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) { UnityEngine.Debug.LogWarningFormat("Field with the name `{0}` was not found on field deserialization stage. Be sure you have no per-platform #ifdef directives in your scripts. Skipped.", data[i].name); } } } } return(component); }
public object Unpack(object container, System.Type fieldType, UABField fieldData, List <ISerializer> serializers) { for (int i = 0; i < serializers.Count; ++i) { var s = serializers[i]; if ((s is IBinarySerializer) == false && s.IsValid(fieldData.serializatorId) == true) { object obj = container; s.DeserializeBeforeRef(this, fieldData, ref obj, serializers); return(obj); } } object result = null; if (fieldData.fieldType == FieldType.ArrayType) { if (fieldData.fields == null) { fieldData.fields = new UABField[0]; } var elementType = fieldType.GetEnumerableType(); if (fieldType.IsGenericType == true) { IList list = (IList)System.Activator.CreateInstance(typeof(List <>).MakeGenericType(elementType)); for (int i = 0; i < fieldData.fields.Length; ++i) { var item = fieldData.fields[i]; if (item != null) { list.Add(this.Unpack(null, elementType, item, serializers)); } else { list.Add(null); } } result = list; } else if (fieldType.IsArray == true) { var filledArray = System.Array.CreateInstance(elementType, fieldData.fields.Length); for (int i = 0; i < fieldData.fields.Length; ++i) { var item = fieldData.fields[i]; if (item != null) { filledArray.SetValue(this.Unpack(null, elementType, item, serializers), i); } else { filledArray.SetValue(null, i); } } result = filledArray; } } else if (fieldData.fieldType == FieldType.NestedType) { var type = fieldType; object instance = null; try { instance = System.Activator.CreateInstance(type); } catch (System.Exception) { instance = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type); } //fieldInfo.SetValue(obj, instance); result = instance; this.Deserialize(instance, fieldData.fields, serializers); } else if (fieldData.fieldType == FieldType.ValueType) { //if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) UnityEngine.Debug.Log(obj + " :: " + fieldInfo.Name + " = " + fieldData.data + " << " + fieldData.serializatorId); object value = null; var found = false; for (int i = 0; i < serializers.Count; ++i) { if (serializers[i].IsValid(fieldData.serializatorId) == true) { object obj = container; serializers[i].DeserializeBeforeRef(this, fieldData, ref obj, serializers); value = obj; found = true; break; } } if (found == false) { // no custom serializator was found - use default //fieldInfo.SetValue(obj, UABSerializer.DeserializeValueType(fieldData.data)); try { if (fieldType.IsEnum == true) { value = System.Enum.ToObject(fieldType, int.Parse(fieldData.data)); } else { value = System.Convert.ChangeType(fieldData.data, fieldType); } } catch (System.Exception) { //if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) UnityEngine.Debug.LogException(ex); value = UABSerializer.DeserializeValueType(fieldData.data, fieldType); } } //fieldInfo.SetValue(obj, value); result = value; } else if (fieldData.fieldType == FieldType.ReferenceType) { // Unpack ref type //if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) UnityEngine.Debug.Log("Unpack ref type: " + fieldData.data); //UAB.Builder.RegisterReferenceUnpack(fieldData, fieldInfo, obj, contextCallback); var data = UABSerializer.DeserializeValueType(fieldData.data, typeof(UABReference)) as UABReference; if (data != null) { if (data.isLocal == false) { var rf = UnityEngine.UI.Windows.WindowSystemResources.Load <ObjectReference>(data.instanceId); if (rf != null) { //if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) UnityEngine.Debug.LogWarning("Resources.Load: " + rf + " :: " + data.instanceId + " :: " + container); //fieldInfo.SetValue(container, rf.reference); result = rf.reference; } else { if (UnityEngine.UI.Windows.Constants.LOGS_ENABLED == true) { UnityEngine.Debug.LogWarning(string.Format("Resource Reference was not found `{0}`.", data.instanceId)); } } } else { if (data.instanceId != "0") { object obj = null; Object value; if (this.GetTempByInstanceID(data.instanceId, out value) == true) { if (data.isGameObject == true) { obj = (object)((value as Transform).gameObject); } else { obj = (object)value; } result = obj; } else { throw new UnityException(string.Format("Package malformed. Local reference `{0}` was not found.", data.instanceId)); } } } } else { throw new UnityException("Package malformed. UABReference deserialization failed."); } } else if (fieldData.fieldType == FieldType.BinaryType) { var data = UABSerializer.DeserializeValueType(fieldData.data, typeof(UABBinary)) as UABBinary; if (data != null) { var binHeader = this.GetBinaryHeader(data.instanceId); if (binHeader != null) { var found = false; for (int i = 0; i < serializers.Count; ++i) { if (serializers[i].IsValid(binHeader.field.serializatorId) == true) { object obj = null; var binData = this.GetBinaryData(binHeader.binDataInstanceId); if (binData != null) { var field = new UABField(); field.data = binData.data; field.fields = binHeader.field.fields; serializers[i].DeserializeBeforeRef(this, field, ref obj, serializers); result = obj; found = true; } break; } } if (found == false) { throw new UnityException(string.Format("Package malformed. Serializer was not found by id `{0}`.", binHeader.field.serializatorId)); } } else { throw new UnityException(string.Format("Package malformed. Binary Header was not found by id `{0}`.", data.instanceId)); } } else { throw new UnityException("Package malformed. UABBinary deserialization failed."); } } return(result); }
public UABField Pack(string fieldName, System.Type fieldType, object value, List <ISerializer> serializers) { var uField = new UABField(); uField.name = fieldName; uField.fieldType = FieldType.ValueType; if (value == null || (value is Object && (value as Object) == null)) { uField.data = null; return(uField); } if ((value is Object) == false) { for (int i = 0; i < serializers.Count; ++i) { var s = serializers[i]; if ((s is IBinarySerializer) == false && s.IsValid(value) == true) { s.Serialize(this, uField, ref value, serializers); return(uField); } } } var type = fieldType; if (value.IsArray() == true) { // array uField.fieldType = FieldType.ArrayType; } else if ( (type.IsClass == true || type.IsValueType == true) && type.IsSerializable == true && type.IsSimpleType() == false && type.IsEnum == false) { // nested uField.fieldType = FieldType.NestedType; uField.fields = this.Serialize(value, serializers); } else if ( type.IsSimpleType() == true || type.IsValueType == true || type.IsEnum == true) { // value type uField.fieldType = FieldType.ValueType; } else { // ref type uField.fieldType = FieldType.ReferenceType; if (UAB.Builder.IsBinary(this.currentBundleName, value as Object) == true) { // binary type uField.fieldType = FieldType.BinaryType; } } if (uField.fieldType == FieldType.ValueType) { var found = false; for (int i = 0; i < serializers.Count; ++i) { if (serializers[i].IsValid(value) == true) { serializers[i].Serialize(this, uField, ref value, serializers); found = true; break; } } if (found == false) { // no custom serializator was found - use default uField.serializatorId = "-1"; if (value is string) { uField.data = (string)value; } else { uField.data = UABSerializer.SerializeValueType(value); } } } else if (uField.fieldType == FieldType.ReferenceType) { //Debug.Log("Pack ref type: " + value); this.RegisterReferencePack(uField, value); } else if (uField.fieldType == FieldType.BinaryType) { this.RegisterBinaryPack(uField, value); } else if (uField.fieldType == FieldType.ArrayType) { var count = 0; var enumerator = ((IEnumerable)value).GetEnumerator(); while (enumerator.MoveNext() == true) { ++count; } //Debug.Log("Pack arr type: " + count); if (count > 0) { enumerator.Reset(); uField.fields = new UABField[count]; count = 0; while (enumerator.MoveNext() == true) { var element = enumerator.Current; uField.fields[count] = (element == null ? null : this.Pack(null, element.GetType(), element, serializers)); ++count; } } } return(uField); }
public UABField[] Serialize(object component, bool forced, List <ISerializer> serializers) { var list = ListPool <UABField> .Get(); if (UABSerializer.HasProperties(component) == true) { var fields = component.GetType().GetAllProperties() .Where(x => x.GetCustomAttributes(true).Any(a => a is System.ObsoleteAttribute) == false && x.CanWrite == true && UABSerializer.FilterProperties(x) == true).ToArray(); for (int i = 0; i < fields.Length; ++i) { var field = fields[i]; var ignoreAttr = field.GetCustomAttributes(typeof(BundleIgnoreAttribute), inherit: true); if ((ignoreAttr != null && ignoreAttr.Length != 0)) { continue; } if (this.IsSkipped(fields[i].PropertyType) == true) { continue; } list.Add(this.Pack(fields[i].Name, fields[i].PropertyType, fields[i].GetValue(component, null), serializers)); } } else { var fields = component.GetType().GetAllFields(); for (int i = 0; i < fields.Length; ++i) { var field = fields[i]; if (forced == false) { var attr = field.GetCustomAttributes(typeof(SerializeField), inherit: true); if ((attr == null || attr.Length == 0) && field.IsPublic == false) { continue; } } var ignoreAttr = field.GetCustomAttributes(typeof(BundleIgnoreAttribute), inherit: true); if ((ignoreAttr != null && ignoreAttr.Length != 0)) { continue; } if (this.IsSkipped(fields[i].FieldType) == true) { continue; } list.Add(this.Pack(fields[i].Name, fields[i].FieldType, fields[i].GetValue(component), serializers)); } } var uFields = list.ToArray(); ListPool <UABField> .Release(list); return(uFields); }
public void BuildReferences(Transform root) { var list = this.tempReferencesPack; for (int i = 0; i < list.Count; ++i) { var uField = list[i].uField; var value = list[i].value; var isObjectNull = (value as UnityEngine.Object) == null; var instanceId = Builder.GetInstanceID(value).ToString(); var isLocal = (isObjectNull == false ? Builder.GetRoot(value) == root : true); var isGameObject = (value is GameObject); var postInstanceId = string.Empty; //Debug.Log(Builder.GetRoot(value) + " :: " + root); var resultInstanceId = string.Empty; if (isLocal == false && isObjectNull == false) { // Add resource link #if UNITY_EDITOR var source = value as Object; var assetPath = UnityEditor.AssetDatabase.GetAssetPath(source); instanceId = UnityEditor.AssetDatabase.AssetPathToGUID(assetPath); if (assetPath.StartsWith("Assets/") == false) { // Unity default resource instanceId = "_" + value.GetType().FullName + "." + (value as Object).name; } else { var obj = UnityEditor.AssetDatabase.LoadAssetAtPath <Object>(assetPath); if (obj != source) { if (obj is GameObject) { // Object is storing inside // Finding local asset path postInstanceId = ME.UAB.Extensions.EditorUtilities.GetLocalIdentfierInFile(source).ToString(); } else { var allObjects = UnityEditor.AssetDatabase.LoadAllAssetsAtPath(assetPath); var objectInside = allObjects.FirstOrDefault(x => x.name == source.name); if (objectInside != null) { var index = System.Array.IndexOf(allObjects, objectInside); if (index >= 0) { instanceId = string.Format("{0}_{1}", UnityEditor.AssetDatabase.AssetPathToGUID(assetPath), index); postInstanceId = "inner"; } else { throw new UnityException(string.Format("Object with the name `{0}` was not found in `{1}`. Package cannot be processed.", objectInside.name, assetPath)); } } else { throw new UnityException(string.Format("Object was not found in `{0}`. Package cannot be processed.", assetPath)); } } } else { postInstanceId = "root"; } } var localPath = this.config.UAB_RESOURCES_PATH; var projectPath = "Assets/" + localPath; { // Creating `Resources` directory var path = Application.dataPath + "/" + localPath; if (System.IO.Directory.Exists(path) == false) { System.IO.Directory.CreateDirectory(path); UnityEditor.AssetDatabase.ImportAsset(projectPath); } } { // Creating asset by GUID var guid = instanceId + "_" + postInstanceId; var name = guid + ".asset"; ObjectReference reference = null; var fullPath = projectPath + "/" + name; if (System.IO.File.Exists(fullPath) == false) { reference = ME.UAB.Extensions.EditorUtilities.CreateAsset <ObjectReference>(name, projectPath); } else { reference = UnityEditor.AssetDatabase.LoadAssetAtPath <ObjectReference>(fullPath); } reference.reference = source; UnityEditor.EditorUtility.SetDirty(reference); } #endif resultInstanceId = string.Format("{0}_{1}", instanceId, postInstanceId); } else { if (isGameObject == true) { var go = (value as GameObject); instanceId = Builder.GetInstanceID(go == null ? null : go.transform).ToString(); } resultInstanceId = instanceId; } uField.serializatorId = "-2"; uField.data = UABSerializer.SerializeValueType(new UABReference() { instanceId = resultInstanceId, isLocal = isLocal, isGameObject = isGameObject }); } list.Clear(); }
public void BuildBinaries(ref UABBinaryHeader[] headers, ref UABBinaryData[] data, List <ISerializer> serializers) { var binData = ListPool <UABBinaryData> .Get(); var binHeaders = ListPool <UABBinaryHeader> .Get(); var list = this.tempBinariesPack; for (int i = 0; i < list.Count; ++i) { var uField = list[i].uField; var value = list[i].value; var headerId = string.Empty; var found = false; #if UNITY_EDITOR var instanceId = UnityEditor.AssetDatabase.AssetPathToGUID(UnityEditor.AssetDatabase.GetAssetPath(value as Object)); for (int j = 0; j < serializers.Count; ++j) { if (serializers[j].IsValid(value) == true) { if (binData.Any(x => x.instanceId == instanceId) == false) { var f = new UABField(); serializers[j].Serialize(null, f, ref value, serializers); binData.Add(new UABBinaryData() { instanceId = instanceId, data = f.data }); } var field = new UABField(); serializers[j].Serialize(this, field, ref value, serializers); var header = new UABBinaryHeader() { binDataInstanceId = instanceId }; header.instanceId = header.GetHashCode().ToString(); header.field = field; headerId = header.instanceId; if (binHeaders.Any(x => x.instanceId == header.instanceId) == false) { binHeaders.Add(header); } found = true; break; } } #endif uField.serializatorId = "-3"; uField.data = UABSerializer.SerializeValueType(new UABBinary() { instanceId = headerId }); if (found == false) { throw new UnityException(string.Format("Binary Serializer was not found for type `{0}`. Package cannot be processed.", value.GetType().ToString())); } } list.Clear(); data = binData.ToArray(); ListPool <UABBinaryData> .Release(binData); headers = binHeaders.ToArray(); ListPool <UABBinaryHeader> .Release(binHeaders); }