/*WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW*\ ( ( ) )
|/ \| ) ) _((_
|| (c) Wanzyee Studio < wanzyeestudio.blogspot.com > || ( ( |_ _ |=n
|\ /| _____)) | ! ] U
\.ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ./ (_(__(S) |___*/
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace WanzyeeStudio.Json{
///
/// Integrate custom Newtonsoft.Json.JsonConverter to use
/// Json.NET in Unity.
///
///
///
/// To use Json.NET, please set Unity "PlayerSettings/Api Compatibility Lavel" to .NET 2.0.
/// Then download from its website and import the .NET 2.0 dll.
/// Json.NET doesn't support serializing some types originally, e.g., UnityEngine.Vector3.
/// This has the defaultSettings includes necessary custom converters by default for Unity using it.
/// And assign to Newtonsoft.Json.JsonConvert.DefaultSettings when initializing if the original null.
///
///
///
/// Now we can use Json.NET just like before:
///
///
///
/// Debug.Log(JsonConvert.SerializeObject(Vector3.up));
/// var vec = JsonConvert.DeserializeObject("{'x':1.0,'y':0.0}");
///
///
///
/// User can directly modify defaultSettings for customization, and override it:
///
///
///
/// JsonConvert.DefaultSettings = () => new JsonSerializerSettings(){
/// Converters = JsonNetUtility.defaultSettings.Converters,
/// DefaultValueHandling = DefaultValueHandling.Populate
/// };
///
///
public static class JsonNetUtility{
#region Fields
///
/// The default Newtonsoft.Json.JsonSerializerSettings.
///
///
///
/// All its properties stay default, but the Converters includes below:
/// 1. Any custom Newtonsoft.Json.JsonConverter has constructor without parameters.
/// 2. Any Newtonsoft.Json.JsonConverter from WanzyeeStudio.Json.
/// 3. Newtonsoft.Json.Converters.StringEnumConverter.
/// 4. Newtonsoft.Json.Converters.VersionConverter.
///
///
public static JsonSerializerSettings defaultSettings = new JsonSerializerSettings(){
Converters = CreateConverters()
};
#endregion
#region Methods
///
/// Initialize when start up, set Newtonsoft.Json.JsonConvert.DefaultSettings if not yet.
///
[RuntimeInitializeOnLoadMethod]
private static void Initialize(){
if(null == JsonConvert.DefaultSettings) JsonConvert.DefaultSettings = () => defaultSettings;
}
///
/// Create the converter instances.
///
/// The converters.
private static List CreateConverters(){
var _customs = FindConverterTypes().Select((type) => CreateConverter(type));
var _builtins = new JsonConverter[]{new StringEnumConverter(), new VersionConverter()};
return _customs.Concat(_builtins).Where((converter) => null != converter).ToList();
}
///
/// Try to create the converter of specified type.
///
/// The converter.
/// Type.
private static JsonConverter CreateConverter(Type type){
try{ return Activator.CreateInstance(type) as JsonConverter; }
catch(Exception exception){ Debug.LogErrorFormat("Can't create JsonConverter {0}:\n{1}", type, exception); }
return null;
}
///
/// Find all the valid converter types.
///
/// The types.
private static Type[] FindConverterTypes(){
return AppDomain.CurrentDomain.GetAssemblies(
).SelectMany((dll) => dll.GetTypes()
).Where((type) => typeof(JsonConverter).IsAssignableFrom(type)
).Where((type) => (!type.IsAbstract && !type.IsGenericTypeDefinition)
).Where((type) => null != type.GetConstructor(new Type[0])
).Where((type) => !(null != type.Namespace && type.Namespace.StartsWith("Newtonsoft.Json"))
).OrderBy((type) => null != type.Namespace && type.Namespace.StartsWith("WanzyeeStudio")
).ToArray();
}
#endregion
#if UNITY_EDITOR
///
/// Initialize in edit mode.
///
/*
* http://stackoverflow.com/q/44655667
* There's a bug of RuntimeInitializeOnLoadMethodAttribute issued above.
* Here directly split into two initialize methods to avoid that, and make the code cleaner.
*/
[UnityEditor.InitializeOnLoadMethod]
private static void InitializeEditor(){
Initialize();
}
#endif
}
}