Make Beatmap ISerializable and add more JsonIgnores

This commit is contained in:
smoogipoo
2017-12-06 00:37:37 +09:00
parent 58777a9674
commit b584178e85
14 changed files with 322 additions and 15 deletions

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace osu.Game.IO.Serialization.Converters
{
public class TypedListConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(List<T>);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var list = new List<T>();
var localSerializer = createLocalSerializer();
var obj = JObject.Load(reader);
var lookupTable = new List<string>();
localSerializer.Populate(obj["LookupTable"].CreateReader(), lookupTable);
foreach (var tok in obj["Items"])
{
var itemReader = tok.CreateReader();
var typeName = lookupTable[(int)tok["Type"]];
var instance = (T)Activator.CreateInstance(Type.GetType(typeName));
localSerializer.Populate(itemReader, instance);
list.Add(instance);
}
return list;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var list = (List<T>)value;
var localSerializer = createLocalSerializer();
var lookupTable = new List<string>();
var objects = new List<JObject>();
foreach (var item in list)
{
var type = item.GetType().AssemblyQualifiedName;
int typeId = lookupTable.IndexOf(type);
if (typeId == -1)
{
lookupTable.Add(type);
typeId = lookupTable.Count - 1;
}
var itemObject = JObject.FromObject(item, localSerializer);
itemObject.AddFirst(new JProperty("Type", typeId));
objects.Add(itemObject);
}
writer.WriteStartObject();
writer.WritePropertyName("LookupTable");
localSerializer.Serialize(writer, lookupTable);
writer.WritePropertyName("Items");
writer.WriteStartArray();
foreach (var item in objects)
item.WriteTo(writer);
writer.WriteEndArray();
writer.WriteEndObject();
}
private JsonSerializer createLocalSerializer()
{
var localSettings = JsonSerializableExtensions.CreateGlobalSettings();
localSettings.Converters = localSettings.Converters.Where(c => !(c is TypedListConverter<T>)).ToArray();
return JsonSerializer.Create(localSettings);
}
}
}

View File

@ -0,0 +1,35 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenTK;
namespace osu.Game.IO.Serialization.Converters
{
public class Vector2Converter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(Vector2);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var obj = JObject.Load(reader);
return new Vector2((float)obj["X"], (float)obj["Y"]);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var vector = (Vector2)value;
writer.WriteStartObject();
writer.WritePropertyName("X");
writer.WriteValue(vector.X);
writer.WritePropertyName("Y");
writer.WriteValue(vector.Y);
writer.WriteEndObject();
}
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using Newtonsoft.Json;
using osu.Game.IO.Serialization.Converters;
namespace osu.Game.IO.Serialization
{
@ -11,20 +12,21 @@ namespace osu.Game.IO.Serialization
public static class JsonSerializableExtensions
{
public static string Serialize(this IJsonSerializable obj)
{
return JsonConvert.SerializeObject(obj, new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
}
public static string Serialize(this IJsonSerializable obj) => JsonConvert.SerializeObject(obj, CreateGlobalSettings());
public static T Deserialize<T>(this string objString)
{
return JsonConvert.DeserializeObject<T>(objString);
}
public static T Deserialize<T>(this string objString) => JsonConvert.DeserializeObject<T>(objString, CreateGlobalSettings());
public static T DeepClone<T>(this T obj)
where T : IJsonSerializable
public static void DeserializeInto<T>(this string objString, T target) => JsonConvert.PopulateObject(objString, target, CreateGlobalSettings());
public static T DeepClone<T>(this T obj) where T : IJsonSerializable => Deserialize<T>(Serialize(obj));
public static JsonSerializerSettings CreateGlobalSettings() => new JsonSerializerSettings
{
return Deserialize<T>(Serialize(obj));
}
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Formatting = Formatting.Indented,
ObjectCreationHandling = ObjectCreationHandling.Replace,
DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate,
Converters = new JsonConverter[] { new Vector2Converter() }
};
}
}