using System.Collections.Generic; using System.IO; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using MLEM.Data.Json; using Newtonsoft.Json; namespace MLEM.Data { /// /// A set of extensions for dealing with /// public static class ContentExtensions { private static readonly Dictionary Serializers = new Dictionary(); private static readonly string[] JsonExtensions = {".json", ".json5", ".jsonc"}; /// /// Adds a to the given content manager, which allows to load JSON-based content. /// Note that calls this method implicitly if no serializer exists. /// /// The content manager to add the json serializer to /// The json serializer to add public static void SetJsonSerializer(this ContentManager content, JsonSerializer serializer) { Serializers[content] = serializer; } /// /// Returns the given content manager's json serializer. /// This method sets a new json serializer using if the given content manager does not yet have one. /// /// The content manager whose serializer to get /// The content manager's serializer public static JsonSerializer GetJsonSerializer(this ContentManager content) { if (!Serializers.TryGetValue(content, out var serializer)) { serializer = JsonConverters.AddAll(new JsonSerializer()); content.SetJsonSerializer(serializer); } return serializer; } /// /// Adds a to the given content manager's . /// /// The content manager to add the converter to /// The converter to add public static void AddJsonConverter(this ContentManager content, JsonConverter converter) { var serializer = GetJsonSerializer(content); serializer.Converters.Add(converter); } /// /// Loads any kind of JSON data using the given content manager's . /// /// The content manager to load content with /// The name of the file to load /// The file extensions that should be appended, or ".json", ".json5" and ".jsonc" by default. /// The json serializer to use, or by default. /// The type of asset to load /// The loaded asset public static T LoadJson(this ContentManager content, string name, string[] extensions = null, JsonSerializer serializer = null) { var triedFiles = new List(); var serializerToUse = serializer ?? content.GetJsonSerializer(); foreach (var extension in extensions ?? JsonExtensions) { var file = Path.Combine(content.RootDirectory, name + extension); triedFiles.Add(file); try { using (var stream = Path.IsPathRooted(file) ? File.OpenText(file) : new StreamReader(TitleContainer.OpenStream(file))) { using (var reader = new JsonTextReader(stream)) return serializerToUse.Deserialize(reader); } } catch (FileNotFoundException) { } } throw new ContentLoadException($"Asset {name} not found. Tried files {string.Join(", ", triedFiles)}"); } } }