summaryrefslogtreecommitdiff
path: root/Plugins/MonoGame.Extended/source/MonoGame.Extended/TextureAtlases/TextureAtlasJsonConverter.cs
blob: 2d887091dbb9353840d269a9a210e25521f87f6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
using System;
using System.IO;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using MonoGame.Extended.Content;
using MonoGame.Extended.Serialization;

namespace MonoGame.Extended.TextureAtlases
{
    public class TextureAtlasJsonConverter : JsonConverter<TextureAtlas>
    {
        private readonly ContentManager _contentManager;
        private readonly string _path;

        public TextureAtlasJsonConverter(ContentManager contentManager, string path)
        {
            _contentManager = contentManager;
            _path = path;
        }

        /// <inheritdoc />
        public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(TextureAtlas);

        public override TextureAtlas Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            if(reader.TokenType == JsonTokenType.String)
            {
                // TODO: (Aristurtle 05/20/2024) What is this for? It's just an if block that throws an exception. Need
                // to investigate.
                var textureAtlasAssetName = reader.GetString();
                var contentPath = GetContentPath(textureAtlasAssetName);
                var texturePackerFile = _contentManager.Load<TexturePackerFile>(contentPath, new JsonContentLoader());
                var texture = _contentManager.Load<Texture2D>(texturePackerFile.Metadata.Image);
                //return TextureAtlas.Create(texturePackerFile.Metadata.Image, texture );
                throw new NotImplementedException();
            }
            else
            {
                var metadata = JsonSerializer.Deserialize<InlineTextureAtlas>(ref reader, options);

                // TODO: When we get to .NET Standard 2.1 it would be more robust to use
                // [Path.GetRelativePath](https://docs.microsoft.com/en-us/dotnet/api/system.io.path.getrelativepath?view=netstandard-2.1)
                var textureName = Path.GetFileNameWithoutExtension(metadata.Texture);
                var textureDirectory = Path.GetDirectoryName(metadata.Texture);
                var directory = Path.GetDirectoryName(_path);
                var relativePath = Path.Combine(_contentManager.RootDirectory, directory, textureDirectory, textureName);
                var resolvedAssetName = Path.GetFullPath(relativePath);
                Texture2D texture;
                try
                {
                    texture = _contentManager.Load<Texture2D>(resolvedAssetName);
                }
                catch (Exception ex)
                {
                    if (textureDirectory == null || textureDirectory == "")
                        texture = _contentManager.Load<Texture2D>(textureName);
                    else
                        texture = _contentManager.Load<Texture2D>(textureDirectory + "/" + textureName);
                }
                return TextureAtlas.Create(resolvedAssetName, texture, metadata.RegionWidth, metadata.RegionHeight);
            }
        }

        /// <inheritdoc />
        public override void Write(Utf8JsonWriter writer, TextureAtlas value, JsonSerializerOptions options) { }


        // ReSharper disable once ClassNeverInstantiated.Local
        private class InlineTextureAtlas
        {
            public string Texture { get; set; }
            public int RegionWidth { get; set; }
            public int RegionHeight { get; set; }
        }

        private string GetContentPath(string relativePath)
        {
            var directory = Path.GetDirectoryName(_path);
            return Path.Combine(directory, relativePath);
        }
    }
}