diff --git a/Source/Engine/Serialization/JsonConverters.cs b/Source/Engine/Serialization/JsonConverters.cs new file mode 100644 index 000000000..4b5192da5 --- /dev/null +++ b/Source/Engine/Serialization/JsonConverters.cs @@ -0,0 +1,255 @@ +// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. + +using System; +using FlaxEngine.GUI; +using Newtonsoft.Json; + +namespace FlaxEngine.Json +{ + /// + /// Serialize references to the FlaxEngine.Object as Guid. + /// + /// + internal class FlaxObjectConverter : JsonConverter + { + /// + public override unsafe void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) + { + Guid id = Guid.Empty; + if (value is Object obj) + id = obj.ID; + writer.WriteValue(JsonSerializer.GetStringID(&id)); + } + + /// + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.String) + { + JsonSerializer.ParseID((string)reader.Value, out var id); + return Object.Find(ref id, objectType); + } + return null; + } + + /// + public override bool CanConvert(Type objectType) + { + // Skip serialization as reference id for the root object serialization (eg. Script) + var cache = JsonSerializer.Current.Value; + if (cache != null && cache.IsDuringSerialization && cache.SerializerWriter.SerializeStackSize == 0) + { + return false; + } + return typeof(Object).IsAssignableFrom(objectType); + } + } + + /// + /// Serialize SceneReference as Guid in internal format. + /// + /// + internal class SceneReferenceConverter : JsonConverter + { + /// + public override unsafe void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) + { + Guid id = ((SceneReference)value).ID; + writer.WriteValue(JsonSerializer.GetStringID(&id)); + } + + /// + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) + { + SceneReference result = new SceneReference(); + + if (reader.TokenType == JsonToken.String) + { + JsonSerializer.ParseID((string)reader.Value, out result.ID); + } + + return result; + } + + /// + public override bool CanConvert(Type objectType) + { + return objectType == typeof(SceneReference); + } + } + + /// + /// Serialize SoftObjectReference as Guid in internal format. + /// + /// + internal class SoftObjectReferenceConverter : JsonConverter + { + /// + public override unsafe void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) + { + var id = ((SoftObjectReference)value).ID; + writer.WriteValue(JsonSerializer.GetStringID(&id)); + } + + /// + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) + { + var result = new SoftObjectReference(); + if (reader.TokenType == JsonToken.String) + { + JsonSerializer.ParseID((string)reader.Value, out var id); + result.ID = id; + } + return result; + } + + /// + public override bool CanConvert(Type objectType) + { + return objectType == typeof(SoftObjectReference); + } + } + + /// + /// Serialize SoftObjectReference as Guid in internal format. + /// + /// + internal class MarginConverter : JsonConverter + { + /// + public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) + { + var valueMargin = (Margin)value; + + writer.WriteStartObject(); + { + writer.WritePropertyName("Left"); + writer.WriteValue(valueMargin.Left); + writer.WritePropertyName("Right"); + writer.WriteValue(valueMargin.Right); + writer.WritePropertyName("Top"); + writer.WriteValue(valueMargin.Top); + writer.WritePropertyName("Bottom"); + writer.WriteValue(valueMargin.Bottom); + } + writer.WriteEndObject(); + } + + /// + public override void WriteJsonDiff(JsonWriter writer, object value, object other, Newtonsoft.Json.JsonSerializer serializer) + { + var valueMargin = (Margin)value; + var otherMargin = (Margin)other; + writer.WriteStartObject(); + if (!Mathf.NearEqual(valueMargin.Left, otherMargin.Left)) + { + writer.WritePropertyName("Left"); + writer.WriteValue(valueMargin.Left); + } + if (!Mathf.NearEqual(valueMargin.Right, otherMargin.Right)) + { + writer.WritePropertyName("Right"); + writer.WriteValue(valueMargin.Right); + } + if (!Mathf.NearEqual(valueMargin.Top, otherMargin.Top)) + { + writer.WritePropertyName("Top"); + writer.WriteValue(valueMargin.Top); + } + if (!Mathf.NearEqual(valueMargin.Bottom, otherMargin.Bottom)) + { + writer.WritePropertyName("Bottom"); + writer.WriteValue(valueMargin.Bottom); + } + writer.WriteEndObject(); + } + + /// + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) + { + var value = (Margin?)existingValue ?? new Margin(); + if (reader.TokenType == JsonToken.StartObject) + { + while (reader.Read()) + { + switch (reader.TokenType) + { + case JsonToken.PropertyName: + { + var propertyName = (string)reader.Value; + var propertyValue = (float)reader.ReadAsDouble(); + switch (propertyName) + { + case "Left": + value.Left = propertyValue; + break; + case "Right": + value.Right = propertyValue; + break; + case "Top": + value.Top = propertyValue; + break; + case "Bottom": + value.Bottom = propertyValue; + break; + } + break; + } + case JsonToken.Comment: break; + default: return value; + } + } + } + return value; + } + + /// + public override bool CanConvert(Type objectType) + { + return objectType == typeof(Margin); + } + + /// + public override bool CanRead => true; + + /// + public override bool CanWrite => true; + + /// + public override bool CanWriteDiff => true; + } + + /* + /// + /// Serialize Guid values using `N` format + /// + /// + internal class GuidConverter : JsonConverter + { + /// + public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) + { + Guid id = (Guid)value; + writer.WriteValue(id.ToString("N")); + } + + /// + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) + { + if (reader.TokenType == JsonToken.String) + { + var id = Guid.Parse((string)reader.Value); + return id; + } + + return Guid.Empty; + } + + /// + public override bool CanConvert(Type objectType) + { + return objectType == typeof(Guid); + } + } + */ +} diff --git a/Source/Engine/Serialization/JsonSerializer.cs b/Source/Engine/Serialization/JsonSerializer.cs index b3bd51d6f..7d17a6ea0 100644 --- a/Source/Engine/Serialization/JsonSerializer.cs +++ b/Source/Engine/Serialization/JsonSerializer.cs @@ -7,7 +7,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; -using FlaxEngine.GUI; using FlaxEngine.Json.JsonCustomSerializers; using FlaxEngine.Utilities; using Newtonsoft.Json; @@ -16,253 +15,6 @@ using Newtonsoft.Json.Serialization; namespace FlaxEngine.Json { - /// - /// Serialize references to the FlaxEngine.Object as Guid. - /// - /// - internal class FlaxObjectConverter : JsonConverter - { - /// - public override unsafe void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) - { - Guid id = Guid.Empty; - if (value is Object obj) - id = obj.ID; - writer.WriteValue(JsonSerializer.GetStringID(&id)); - } - - /// - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.String) - { - JsonSerializer.ParseID((string)reader.Value, out var id); - return Object.Find(ref id, objectType); - } - return null; - } - - /// - public override bool CanConvert(Type objectType) - { - // Skip serialization as reference id for the root object serialization (eg. Script) - var cache = JsonSerializer.Current.Value; - if (cache != null && cache.IsDuringSerialization && cache.SerializerWriter.SerializeStackSize == 0) - { - return false; - } - return typeof(Object).IsAssignableFrom(objectType); - } - } - - /// - /// Serialize SceneReference as Guid in internal format. - /// - /// - internal class SceneReferenceConverter : JsonConverter - { - /// - public override unsafe void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) - { - Guid id = ((SceneReference)value).ID; - writer.WriteValue(JsonSerializer.GetStringID(&id)); - } - - /// - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) - { - SceneReference result = new SceneReference(); - - if (reader.TokenType == JsonToken.String) - { - JsonSerializer.ParseID((string)reader.Value, out result.ID); - } - - return result; - } - - /// - public override bool CanConvert(Type objectType) - { - return objectType == typeof(SceneReference); - } - } - - /// - /// Serialize SoftObjectReference as Guid in internal format. - /// - /// - internal class SoftObjectReferenceConverter : JsonConverter - { - /// - public override unsafe void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) - { - var id = ((SoftObjectReference)value).ID; - writer.WriteValue(JsonSerializer.GetStringID(&id)); - } - - /// - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) - { - var result = new SoftObjectReference(); - if (reader.TokenType == JsonToken.String) - { - JsonSerializer.ParseID((string)reader.Value, out var id); - result.ID = id; - } - return result; - } - - /// - public override bool CanConvert(Type objectType) - { - return objectType == typeof(SoftObjectReference); - } - } - - /// - /// Serialize SoftObjectReference as Guid in internal format. - /// - /// - internal class MarginConverter : JsonConverter - { - /// - public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) - { - var valueMargin = (Margin)value; - - writer.WriteStartObject(); - { - writer.WritePropertyName("Left"); - writer.WriteValue(valueMargin.Left); - writer.WritePropertyName("Right"); - writer.WriteValue(valueMargin.Right); - writer.WritePropertyName("Top"); - writer.WriteValue(valueMargin.Top); - writer.WritePropertyName("Bottom"); - writer.WriteValue(valueMargin.Bottom); - } - writer.WriteEndObject(); - } - - /// - public override void WriteJsonDiff(JsonWriter writer, object value, object other, Newtonsoft.Json.JsonSerializer serializer) - { - var valueMargin = (Margin)value; - var otherMargin = (Margin)other; - writer.WriteStartObject(); - if (!Mathf.NearEqual(valueMargin.Left, otherMargin.Left)) - { - writer.WritePropertyName("Left"); - writer.WriteValue(valueMargin.Left); - } - if (!Mathf.NearEqual(valueMargin.Right, otherMargin.Right)) - { - writer.WritePropertyName("Right"); - writer.WriteValue(valueMargin.Right); - } - if (!Mathf.NearEqual(valueMargin.Top, otherMargin.Top)) - { - writer.WritePropertyName("Top"); - writer.WriteValue(valueMargin.Top); - } - if (!Mathf.NearEqual(valueMargin.Bottom, otherMargin.Bottom)) - { - writer.WritePropertyName("Bottom"); - writer.WriteValue(valueMargin.Bottom); - } - writer.WriteEndObject(); - } - - /// - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) - { - var value = (Margin?)existingValue ?? new Margin(); - if (reader.TokenType == JsonToken.StartObject) - { - while (reader.Read()) - { - switch (reader.TokenType) - { - case JsonToken.PropertyName: - { - var propertyName = (string)reader.Value; - var propertyValue = (float)reader.ReadAsDouble(); - switch (propertyName) - { - case "Left": - value.Left = propertyValue; - break; - case "Right": - value.Right = propertyValue; - break; - case "Top": - value.Top = propertyValue; - break; - case "Bottom": - value.Bottom = propertyValue; - break; - } - break; - } - case JsonToken.Comment: break; - default: return value; - } - } - } - return value; - } - - /// - public override bool CanConvert(Type objectType) - { - return objectType == typeof(Margin); - } - - /// - public override bool CanRead => true; - - /// - public override bool CanWrite => true; - - /// - public override bool CanWriteDiff => true; - } - - /* - /// - /// Serialize Guid values using `N` format - /// - /// - internal class GuidConverter : JsonConverter - { - /// - public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) - { - Guid id = (Guid)value; - writer.WriteValue(id.ToString("N")); - } - - /// - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) - { - if (reader.TokenType == JsonToken.String) - { - var id = Guid.Parse((string)reader.Value); - return id; - } - - return Guid.Empty; - } - - /// - public override bool CanConvert(Type objectType) - { - return objectType == typeof(Guid); - } - } - */ - /// /// Objects serialization tool (json format). ///