NinePatchJsonConverter.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using System;
  2. using System.Text.Json;
  3. using System.Text.Json.Serialization;
  4. using MonoGame.Extended.Graphics;
  5. namespace MonoGame.Extended.Serialization.Json;
  6. /// <summary>
  7. /// Converts a <see cref="NinePatch"/> value to or from JSON.
  8. /// </summary>
  9. public class NinePatchJsonConverter : JsonConverter<NinePatch>
  10. {
  11. private readonly ITextureRegionService _textureRegionService;
  12. /// <summary>
  13. /// Initializes a new instance of the <see cref="NinePatchJsonConverter"/> class.
  14. /// </summary>
  15. /// <param name="textureRegionService">The texture region service used to retrieve texture regions.</param>
  16. public NinePatchJsonConverter(ITextureRegionService textureRegionService)
  17. {
  18. _textureRegionService = textureRegionService;
  19. }
  20. /// <inheritdoc />
  21. public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(NinePatch);
  22. /// <inheritdoc />
  23. /// <exception cref="JsonException">
  24. /// Thrown if the JSON property does not contain a properly formatted <see cref="NinePatch"/> value
  25. /// </exception>
  26. public override NinePatch Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
  27. {
  28. if (reader.TokenType != JsonTokenType.StartObject)
  29. {
  30. throw new JsonException($"Expected {nameof(JsonTokenType.StartObject)} token");
  31. }
  32. string padding = string.Empty;
  33. string regionName = string.Empty;
  34. while (reader.Read())
  35. {
  36. if (reader.TokenType == JsonTokenType.EndObject)
  37. {
  38. break;
  39. }
  40. if (reader.TokenType == JsonTokenType.PropertyName)
  41. {
  42. var propertyName = reader.GetString();
  43. reader.Read();
  44. if (propertyName.Equals("Padding", StringComparison.Ordinal))
  45. {
  46. padding = reader.GetString();
  47. }
  48. else if (propertyName.Equals("TextureRegion", StringComparison.Ordinal))
  49. {
  50. regionName = reader.GetString();
  51. }
  52. }
  53. }
  54. if (string.IsNullOrEmpty(padding) || string.IsNullOrEmpty(regionName))
  55. {
  56. throw new JsonException($"Missing required properties \"Padding\" and \"TextureRegion\"");
  57. }
  58. var thickness = Thickness.Parse(padding);
  59. var region = _textureRegionService.GetTextureRegion(regionName);
  60. return region.CreateNinePatch(thickness);
  61. }
  62. /// <inheritdoc />
  63. /// <exception cref="ArgumentNullException">
  64. /// Throw if <paramref name="writer"/> is <see langword="null"/>.
  65. /// </exception>
  66. public override void Write(Utf8JsonWriter writer, NinePatch value, JsonSerializerOptions options)
  67. {
  68. ArgumentNullException.ThrowIfNull(writer);
  69. if (value is null)
  70. {
  71. writer.WriteNullValue();
  72. return;
  73. }
  74. writer.WriteStartObject();
  75. writer.WriteString("TextureRegion", value.Name);
  76. writer.WriteString("Padding", value.Padding.ToString());
  77. writer.WriteEndObject();
  78. }
  79. }