Bläddra i källkod

Fixed Serialization

Kenric Nugteren 2 år sedan
förälder
incheckning
6b9bac2265

+ 1 - 1
InABox.Core/DigitalForms/Layouts/Fields/DFLayoutVideoField/DFLayoutVideoFieldProperties.cs

@@ -16,7 +16,7 @@ namespace InABox.Core
         }
 
         [IntegerEditor(ToolTip = "Maximum video length (sec)")]
-        public int MaximumVideoLength { get; set; } = 0
+        public int MaximumVideoLength { get; set; } = 0;
 
         [EnumLookupEditor(typeof(VideoQuality))]
         public VideoQuality Quality { get; set; } = VideoQuality.Default;

+ 68 - 6
InABox.Core/Serialization.cs

@@ -329,12 +329,22 @@ namespace InABox.Core
             }
             else if (typeof(IPackable).IsAssignableFrom(type) && value is IPackable pack)
             {
+                writer.Write(true);
                 pack.Pack(writer);
             }
+            else if (typeof(IPackable).IsAssignableFrom(type) && value is null)
+            {
+                writer.Write(false);
+            }
             else if (typeof(ISerializeBinary).IsAssignableFrom(type) && value is ISerializeBinary binary)
             {
+                writer.Write(true);
                 binary.SerializeBinary(writer);
             }
+            else if (typeof(ISerializeBinary).IsAssignableFrom(type) && value is null)
+            {
+                writer.Write(false);
+            }
             else if (Nullable.GetUnderlyingType(type) is Type t)
             {
                 if(value == null)
@@ -444,15 +454,29 @@ namespace InABox.Core
             }
             else if (typeof(IPackable).IsAssignableFrom(type))
             {
-                var packable = (Activator.CreateInstance(type) as IPackable)!;
-                packable.Unpack(reader);
-                return packable;
+                if (reader.ReadBoolean())
+                {
+                    var packable = (Activator.CreateInstance(type) as IPackable)!;
+                    packable.Unpack(reader);
+                    return packable;
+                }
+                else
+                {
+                    return null;
+                }
             }
             else if (typeof(ISerializeBinary).IsAssignableFrom(type))
             {
-                var obj = (Activator.CreateInstance(type) as ISerializeBinary)!;
-                obj.DeserializeBinary(reader);
-                return obj;
+                if (reader.ReadBoolean())
+                {
+                    var obj = (Activator.CreateInstance(type) as ISerializeBinary)!;
+                    obj.DeserializeBinary(reader);
+                    return obj;
+                }
+                else
+                {
+                    return null;
+                }
             }
             else if (Nullable.GetUnderlyingType(type) is Type t)
             {
@@ -476,6 +500,39 @@ namespace InABox.Core
             DatabaseSchema.Properties(type)
                 .Where(x => !(x is StandardProperty st) || st.Property.GetCustomAttribute<DoNotSerialize>() == null);
 
+        private static void WriteOriginalValues<TObject>(this BinaryWriter writer, TObject obj)
+            where TObject : BaseObject
+        {
+            var originalValues = new List<Tuple<Type, string, object?>>();
+            foreach (var (key, value) in obj.OriginalValues)
+            {
+                if (DatabaseSchema.Property(typeof(TObject), key) is IProperty prop)
+                {
+                    originalValues.Add(new Tuple<Type, string, object?>(prop.PropertyType, key, value));
+                }
+            }
+
+            writer.Write(originalValues.Count);
+            foreach (var (type, key, value) in originalValues)
+            {
+                writer.Write(key);
+                writer.WriteBinaryValue(type, value);
+            }
+        }
+        private static void ReadOriginalValues<TObject>(this BinaryReader reader, TObject obj)
+            where TObject : BaseObject
+        {
+            var nOriginalValues = reader.ReadInt32();
+            for (int i = 0; i < nOriginalValues; ++i)
+            {
+                var key = reader.ReadString();
+                if (DatabaseSchema.Property(typeof(TObject), key) is IProperty prop)
+                {
+                    obj.OriginalValues[key] = reader.ReadBinaryValue(prop.PropertyType);
+                }
+            }
+        }
+
         /// <summary>
         /// An implementation of binary serialising a <typeparamref name="TObject"/>; this is the inverse of <see cref="ReadObject{TObject}(BinaryReader)"/>.
         /// </summary>
@@ -496,6 +553,7 @@ namespace InABox.Core
                 writer.Write(property.Name);
                 writer.WriteBinaryValue(property.PropertyType, property.Getter()(entity));
             }
+            writer.WriteOriginalValues(entity);
         }
 
         /// <summary>
@@ -516,6 +574,8 @@ namespace InABox.Core
                 var property = DatabaseSchema.Property(typeof(TObject), propName);
                 property?.Setter()(obj, reader.ReadBinaryValue(property.PropertyType));
             }
+            reader.ReadOriginalValues(obj);
+
             return obj;
         }
 
@@ -547,6 +607,7 @@ namespace InABox.Core
                 {
                     writer.WriteBinaryValue(property.PropertyType, property.Getter()(obj));
                 }
+                writer.WriteOriginalValues(obj);
             }
         }
 
@@ -578,6 +639,7 @@ namespace InABox.Core
                 {
                     property?.Setter()(obj, reader.ReadBinaryValue(property.PropertyType));
                 }
+                reader.ReadOriginalValues(obj);
 
                 objs.Add(obj);
             }