|
@@ -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);
|
|
|
}
|