Пример #1
0
        private static void WriteClass(BinaryWriter writer, SerializedClass obj)
        {
            WriteDefaults(writer, obj);
            writer.Write(obj.Values.Count);

            foreach (var item in obj.Values)
            {
                writer.Write(item.Key);
                writer.Write((int)item.Value.Mode);
                switch (item.Value.Mode)
                {
                case ESerializableMode.Primitive:
                    WritePrimitive(writer, (SerializedPrimitive)item.Value);
                    break;

                case ESerializableMode.Enum:
                    WriteEnum(writer, (SerializedEnum)item.Value);
                    break;

                case ESerializableMode.List:
                    WriteList(writer, (SerializedList)item.Value);
                    break;

                case ESerializableMode.Class:
                    WriteClass(writer, (SerializedClass)item.Value);
                    break;

                default:
                    break;
                }
            }
        }
Пример #2
0
        private SerializedClass DeserializeClass(BinaryReader reader)
        {
            var value = new SerializedClass(DeserializeDefaults(reader));
            var count = reader.ReadInt32();

            for (int i = 0; i < count; i++)
            {
                var name = reader.ReadString();
                var mode = (ESerializableMode)reader.ReadInt32();
                switch (mode)
                {
                case ESerializableMode.Primitive:
                    value.Add(name, DeserializePrimitive(reader));
                    break;

                case ESerializableMode.Enum:
                    value.Add(name, DeserializeEnum(reader));
                    break;

                case ESerializableMode.List:
                    value.Add(name, DeserializeList(reader));
                    break;

                case ESerializableMode.Class:
                    value.Add(name, DeserializeClass(reader));
                    break;

                default:
                    break;
                }
            }

            return(value);
        }
Пример #3
0
        private SerializedClass SerializeClass(object value, Type valueType)
        {
            if (value == null)
            {
                return(new SerializedClass(GetNextID(), valueType.AssemblyQualifiedName)
                {
                    IsNull = true
                });
            }

            if (value is UnityEngine.Object)
            {
                var result = false;
                var fa     = new FakeAsset((UnityEngine.Object)value, out result);
                if (result)
                {
                    return(SerializeClass(fa, typeof(FakeAsset)));
                }
                else
                {
                    return(new SerializedClass(GetNextID(), valueType.AssemblyQualifiedName)
                    {
                        IsNull = true
                    });
                }
            }

            var obj = new SerializedClass(GetNextID(), valueType.AssemblyQualifiedName);

            if (Compare(value, valueType, ref obj.ID))
            {
                obj.IsReference = true;
                return(obj);
            }
            else
            {
                AddToComparables(obj, value, valueType);
            }

            var fields = SerializationHelper.GetFields(valueType, BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic)
                         .Where(f =>
                                (f.IsPublic && f.GetCustomAttributes(typeof(IgnoreSerializationAttribute), false).Length == 0) ||
                                (f.IsPrivate && f.GetCustomAttributes(typeof(RequireSerializationAttribute), false).Length == 1))
                         .OrderBy(f => f.Name).ToList();

            var properties = SerializationHelper.GetProperties(valueType, BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic)
                             .Where(p => p.CanRead && p.CanWrite)
                             .Where(p => p.GetCustomAttributes(typeof(IgnoreSerializationAttribute), false).Length == 0)
                             .OrderBy(p => p.Name).ToList();

            try {
                for (int i = 0; i < fields.Count; i++)
                {
                    var field  = fields[i];
                    var type   = field.FieldType;
                    var tValue = field.GetValue(value);
                    var fname  = string.Format("{0}|{1}", field.Name, i);

                    if (type == typeof(object) && tValue != null)
                    {
                        type = tValue.GetType();
                    }

                    if ((type.ToString() == "System.MonoType" && tValue != null) || type == typeof(Type))
                    {
                        var t = (Type)tValue;
                        var v = "";
                        try {
                            v = t.AssemblyQualifiedName;
                        } catch (Exception) { }
                        obj.Add(fname, SerializeClass(new FakeType(v), typeof(FakeType)));
                    }
                    else if (type.IsArray())
                    {
                        obj.Add(fname, SerializeList(tValue, type));
                    }
                    else if (type.IsEnum)
                    {
                        obj.Add(fname, SerializeEnum(tValue, type));
                    }
                    else if (type.IsValueType && !type.IsPrimitive)
                    {
                        if (type == typeof(decimal))
                        {
                            obj.Add(fname, SerializePrimitive(tValue, type));
                        }
                        else
                        {
                            obj.Add(fname, SerializeClass(tValue, type));
                        }
                    }
                    else if (type.IsValueType)
                    {
                        obj.Add(fname, SerializePrimitive(tValue, type));
                    }
                    else if (type.IsClass)
                    {
                        if (type == typeof(string))
                        {
                            obj.Add(fname, SerializePrimitive(tValue, type));
                        }
                        else if (type.IsList())
                        {
                            obj.Add(fname, SerializeList(tValue, type));
                        }
                        else
                        {
                            obj.Add(fname, SerializeClass(tValue, type));
                        }
                    }
                }

                for (int i = 0; i < properties.Count; i++)
                {
                    var property = properties[i];
                    var type     = property.PropertyType;
                    if (property.GetIndexParameters().Length > 0)
                    {
                        continue;
                    }
                    var tValue = property.GetValue(value, null);
                    var pname  = string.Format("{0}|{1}", property.Name, i);

                    if (type == typeof(object) && tValue != null)
                    {
                        type = tValue.GetType();
                    }

                    if (type.ToString() == "System.MonoType" && tValue != null)
                    {
                        var t = (Type)tValue;
                        var v = "";
                        try {
                            v = t.AssemblyQualifiedName;
                        } catch (Exception) { }
                        obj.Add(pname, SerializeClass(new FakeType(v), typeof(FakeType)));
                    }
                    else if (type.IsArray())
                    {
                        obj.Add(pname, SerializeList(tValue, type));
                    }
                    else if (type.IsEnum)
                    {
                        obj.Add(pname, SerializeEnum(tValue, type));
                    }
                    else if (type.IsValueType && !type.IsPrimitive)
                    {
                        if (type == typeof(double))
                        {
                            obj.Add(pname, SerializePrimitive(tValue, type));
                        }
                        else
                        {
                            obj.Add(pname, SerializeClass(tValue, type));
                        }
                    }
                    else if (type.IsValueType)
                    {
                        obj.Add(pname, SerializePrimitive(tValue, type));
                    }
                    else if (type.IsClass)
                    {
                        if (type == typeof(string))
                        {
                            obj.Add(pname, SerializePrimitive(tValue, type));
                        }
                        else if (type.IsList())
                        {
                            obj.Add(pname, SerializeList(tValue, type));
                        }
                        else
                        {
                            obj.Add(pname, SerializeClass(tValue, type));
                        }
                    }
                }
            } catch (Exception) {
                // pretty ugly but doing this to prevent MissingReferenceExcpetion which apparently isn't catchable
                obj.IsNull = true;
                return(obj);
            }

            return(obj);
        }
Пример #4
0
        private object ReadClass(SerializedClass value)
        {
            if (value.IsNull)
            {
                return(null);
            }

            var    type     = Type.GetType(value.Type);
            object instance = null;

            if (value.IsReference)
            {
                if (deserializedObjects.ContainsKey(value.ID))
                {
                    return(deserializedObjects[value.ID]);
                }
            }

            try {
                instance = Activator.CreateInstance(type, true);
            } catch (MissingMethodException) {
                // No constructor
                deserializedObjects.Add(value.ID, null);
                return(null);
            }

            var fields = SerializationHelper.GetFields(type, BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic)
                         .Where(f =>
                                (f.IsPublic && f.GetCustomAttributes(typeof(IgnoreSerializationAttribute), false).Length == 0) ||
                                (f.IsPrivate && f.GetCustomAttributes(typeof(RequireSerializationAttribute), false).Length == 1))
                         .OrderBy(f => f.Name).ToList();

            var properties = SerializationHelper.GetProperties(type, BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic)
                             .Where(p => p.CanRead && p.CanWrite)
                             .Where(p => p.GetCustomAttributes(typeof(IgnoreSerializationAttribute), false).Length == 0)
                             .OrderBy(p => p.Name).ToList();

            foreach (var item in value.Values)
            {
                var    name   = item.Key.Substring(0, item.Key.IndexOf('|'));
                object tValue = Read(item.Value);

                var field = fields.Where(f => f.Name == name).FirstOrDefault();
                if (field != null)
                {
                    fields.Remove(field);

                    try {
                        field.SetValue(instance, tValue);
                    } catch (Exception e) {
                        Debug.LogException(e);
                    }

                    continue;
                }

                var property = properties.Where(p => p.Name == name).FirstOrDefault();
                if (property != null)
                {
                    properties.Remove(property);
                    try {
                        property.SetValue(instance, tValue, null);
                    } catch (Exception e) {
                        Debug.LogException(e);
                    }

                    continue;
                }
            }

            if (instance is FakeType)
            {
                var ft = (FakeType)instance;
                var v  = ft.GetValue();
                deserializedObjects.Add(value.ID, v);
                instance = v;
            }
            else if (instance is FakeAsset)
            {
                var fa = (FakeAsset)instance;
                var v  = fa.GetValue();
                deserializedObjects.Add(value.ID, v);
                instance = v;
            }
            else
            {
                deserializedObjects.Add(value.ID, instance);
            }

            return(instance);
        }