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) {
ContentExtensions.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 (!ContentExtensions.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 = content.GetJsonSerializer();
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 ?? ContentExtensions.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 (IOException) {}
}
throw new ContentLoadException($"Asset {name} not found. Tried files {string.Join(", ", triedFiles)}");
}
}
}