UI update 02
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public static class ColorUtil
|
||||
{
|
||||
private static Dictionary<string, Color32> s_ColorCached = new Dictionary<string, Color32>();
|
||||
public static readonly Color32 clearColor32 = new Color32(0, 0, 0, 0);
|
||||
public static readonly Color32 white = new Color32(255, 255, 255, 255);
|
||||
public static readonly Vector2 zeroVector2 = Vector2.zero;
|
||||
|
||||
/// <summary>
|
||||
/// Convert the html string to color.
|
||||
/// ||将字符串颜色值转成Color。
|
||||
/// </summary>
|
||||
/// <param name="hexColorStr"></param>
|
||||
/// <returns></returns>
|
||||
public static Color32 GetColor(string hexColorStr)
|
||||
{
|
||||
if (s_ColorCached.ContainsKey(hexColorStr))
|
||||
{
|
||||
return s_ColorCached[hexColorStr];
|
||||
}
|
||||
Color color;
|
||||
ColorUtility.TryParseHtmlString(hexColorStr, out color);
|
||||
s_ColorCached[hexColorStr] = (Color32) color;
|
||||
return s_ColorCached[hexColorStr];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4260c3b8fdaff435a8bc10375b812bd8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,309 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public static class DateTimeUtil
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
private static readonly DateTime k_LocalDateTime1970 = TimeZoneInfo.ConvertTimeFromUtc(new DateTime(1970, 1, 1), TimeZoneInfo.Local);
|
||||
#else
|
||||
private static readonly DateTime k_LocalDateTime1970 = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
|
||||
#endif
|
||||
private static readonly DateTime k_DateTime1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
public static readonly int ONE_SECOND = 1;
|
||||
public static readonly int ONE_MINUTE = ONE_SECOND * 60;
|
||||
public static readonly int ONE_HOUR = ONE_MINUTE * 60;
|
||||
public static readonly int ONE_DAY = ONE_HOUR * 24;
|
||||
public static readonly int ONE_MONTH = ONE_DAY * 30;
|
||||
public static readonly int ONE_YEAR = ONE_DAY * 365;
|
||||
public static readonly int MIN_TIME_SPLIT_NUMBER = 4;
|
||||
|
||||
private static string s_YearDateFormatter = "yyyy";
|
||||
//private static string s_MonthDateFormatter = "MM";
|
||||
//private static string s_DayDateFormatter = "dd";
|
||||
//private static string s_HourDateFormatter = "HH:mm";
|
||||
//private static string s_MinuteDateFormatter = "mm:ss";
|
||||
private static string s_SecondDateFormatter = "HH:mm:ss";
|
||||
//private static string s_FullDateFormatter = "yyyy-MM-dd HH:mm:ss";
|
||||
private static Regex s_DateOrTimeRegex = new Regex(@"^(date|time)\s*[:\s]+(.*)", RegexOptions.IgnoreCase);
|
||||
|
||||
public static bool IsDateOrTimeRegex(string regex)
|
||||
{
|
||||
return regex.StartsWith("date") || regex.StartsWith("time");
|
||||
}
|
||||
|
||||
public static bool IsDateOrTimeRegex(string regex, ref bool date, ref string formatter)
|
||||
{
|
||||
if (IsDateOrTimeRegex(regex))
|
||||
{
|
||||
if (regex == "date" || regex == "time")
|
||||
{
|
||||
date = regex == "date";
|
||||
formatter = "";
|
||||
return true;
|
||||
}
|
||||
var mc = s_DateOrTimeRegex.Matches(regex);
|
||||
date = mc[0].Groups[1].Value == "date";
|
||||
formatter = mc[0].Groups[2].Value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static double GetTimestamp()
|
||||
{
|
||||
return (DateTime.Now - k_LocalDateTime1970).TotalSeconds;
|
||||
}
|
||||
|
||||
public static double GetTimestamp(DateTime time, bool local = false)
|
||||
{
|
||||
if (local)
|
||||
{
|
||||
return (time - k_LocalDateTime1970).TotalSeconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (time - k_DateTime1970).TotalSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
public static double GetTimestamp(string dateTime, bool local = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
return GetTimestamp(DateTime.Parse(dateTime), local);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static DateTime GetDateTime(double timestamp, bool local = false)
|
||||
{
|
||||
var dateTime = local ? k_LocalDateTime1970.AddSeconds(timestamp) : k_DateTime1970.AddSeconds(timestamp);
|
||||
return dateTime;
|
||||
}
|
||||
|
||||
public static string GetDefaultDateTimeString(double timestamp, double range = 0, bool local = false)
|
||||
{
|
||||
var dateString = String.Empty;
|
||||
var dateTime = GetDateTime(timestamp, local);
|
||||
if (range <= 0 || range >= DateTimeUtil.ONE_DAY)
|
||||
{
|
||||
dateString = dateTime.ToString("yyyy-MM-dd");
|
||||
}
|
||||
else
|
||||
{
|
||||
dateString = dateTime.ToString(s_SecondDateFormatter);
|
||||
}
|
||||
return dateString;
|
||||
}
|
||||
|
||||
internal static string GetDateTimeFormatString(DateTime dateTime, double range)
|
||||
{
|
||||
var dateString = String.Empty;
|
||||
if (range >= DateTimeUtil.ONE_YEAR * DateTimeUtil.MIN_TIME_SPLIT_NUMBER)
|
||||
{
|
||||
dateString = dateTime.ToString(s_YearDateFormatter);
|
||||
}
|
||||
else if (range >= DateTimeUtil.ONE_MONTH * DateTimeUtil.MIN_TIME_SPLIT_NUMBER)
|
||||
{
|
||||
dateString = dateTime.Month == 1 ?
|
||||
dateTime.ToString(s_YearDateFormatter) :
|
||||
XCSettings.lang.GetMonthAbbr(dateTime.Month);
|
||||
}
|
||||
else if (range >= DateTimeUtil.ONE_DAY * DateTimeUtil.MIN_TIME_SPLIT_NUMBER)
|
||||
{
|
||||
dateString = dateTime.Day == 1 ?
|
||||
XCSettings.lang.GetMonthAbbr(dateTime.Month) :
|
||||
XCSettings.lang.GetDay(dateTime.Day);
|
||||
}
|
||||
else if (range >= DateTimeUtil.ONE_HOUR * DateTimeUtil.MIN_TIME_SPLIT_NUMBER)
|
||||
{
|
||||
dateString = dateTime.ToString(s_SecondDateFormatter);
|
||||
}
|
||||
else if (range >= DateTimeUtil.ONE_MINUTE * DateTimeUtil.MIN_TIME_SPLIT_NUMBER)
|
||||
{
|
||||
dateString = dateTime.ToString(s_SecondDateFormatter);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateString = dateTime.ToString(s_SecondDateFormatter);
|
||||
}
|
||||
return dateString;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据给定的最大最小时间戳范围,计算合适的Tick值
|
||||
/// </summary>
|
||||
/// <param name="list"></param>
|
||||
/// <param name="minTimestamp"></param>
|
||||
/// <param name="maxTimestamp"></param>
|
||||
/// <param name="splitNumber"></param>
|
||||
internal static float UpdateTimeAxisDateTimeList(List<double> list, double minTimestamp, double maxTimestamp, int splitNumber, double ceilRate, bool local)
|
||||
{
|
||||
var range = maxTimestamp - minTimestamp;
|
||||
if (range <= 0)
|
||||
{
|
||||
list.Clear();
|
||||
return 0;
|
||||
}
|
||||
var dtMin = GetDateTime(minTimestamp, local);
|
||||
var dtMax = GetDateTime(maxTimestamp, local);
|
||||
int tick;
|
||||
if (ceilRate != 0)
|
||||
{
|
||||
var tickSecond = (int)ceilRate;
|
||||
tick = GetTickSecond(range, 0, tickSecond);
|
||||
var let = minTimestamp % tickSecond;
|
||||
var defaultTimestamp = let == 0 ? minTimestamp : minTimestamp - let + tickSecond;
|
||||
var startTimestamp = (int)GetFirstMaxValue(list, minTimestamp, defaultTimestamp);
|
||||
while (startTimestamp > minTimestamp)
|
||||
{
|
||||
startTimestamp -= tick;
|
||||
}
|
||||
if (startTimestamp < minTimestamp)
|
||||
{
|
||||
startTimestamp += tick;
|
||||
}
|
||||
list.Clear();
|
||||
AddTickTimestamp(list, startTimestamp, maxTimestamp, tick);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (range >= ONE_YEAR * MIN_TIME_SPLIT_NUMBER)
|
||||
{
|
||||
var num = splitNumber <= 0 ? GetSplitNumber(range, ONE_YEAR) : (int)Math.Max(range / (splitNumber * ONE_YEAR), 1);
|
||||
var dtStart = GetDateTime(GetFirstMaxValue(list, minTimestamp), local);
|
||||
dtStart = new DateTime(dtStart.Year, dtStart.Month, 1);
|
||||
while (dtStart > dtMin)
|
||||
{
|
||||
dtStart = dtStart.AddYears(-num);
|
||||
}
|
||||
if (dtStart < dtMin)
|
||||
{
|
||||
dtStart = dtStart.AddYears(num);
|
||||
}
|
||||
tick = num * 365 * 24 * 3600;
|
||||
list.Clear();
|
||||
while (dtStart.Ticks < dtMax.Ticks)
|
||||
{
|
||||
list.Add(DateTimeUtil.GetTimestamp(dtStart, local));
|
||||
dtStart = dtStart.AddYears(num);
|
||||
}
|
||||
}
|
||||
else if (range >= ONE_MONTH * MIN_TIME_SPLIT_NUMBER)
|
||||
{
|
||||
var num = splitNumber <= 0 ? GetSplitNumber(range, ONE_MONTH) : (int)Math.Max(range / (splitNumber * ONE_MONTH), 1);
|
||||
var dtStart = GetDateTime(GetFirstMaxValue(list, minTimestamp), local);
|
||||
dtStart = new DateTime(dtStart.Year, dtStart.Month, 1);
|
||||
while (dtStart > dtMin)
|
||||
{
|
||||
dtStart = dtStart.AddMonths(-num);
|
||||
}
|
||||
if (dtStart < dtMin)
|
||||
{
|
||||
dtStart = dtStart.AddMonths(num);
|
||||
}
|
||||
tick = num * 30 * 24 * 3600;
|
||||
list.Clear();
|
||||
while (dtStart.Ticks < dtMax.Ticks)
|
||||
{
|
||||
list.Add(DateTimeUtil.GetTimestamp(dtStart, local));
|
||||
dtStart = dtStart.AddMonths(num);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int tickSecond;
|
||||
if (range >= ONE_DAY * MIN_TIME_SPLIT_NUMBER)
|
||||
{
|
||||
tickSecond = ONE_DAY;
|
||||
}
|
||||
else if (range >= ONE_HOUR * MIN_TIME_SPLIT_NUMBER)
|
||||
{
|
||||
tickSecond = ONE_HOUR;
|
||||
}
|
||||
else if (range >= ONE_MINUTE * MIN_TIME_SPLIT_NUMBER)
|
||||
{
|
||||
tickSecond = ONE_MINUTE;
|
||||
}
|
||||
else
|
||||
{
|
||||
tickSecond = ONE_SECOND;
|
||||
}
|
||||
tick = GetTickSecond(range, splitNumber, tickSecond);
|
||||
var let = minTimestamp % tickSecond;
|
||||
var defaultTimestamp = let == 0 ? minTimestamp : minTimestamp - let + tickSecond;
|
||||
var startTimestamp = (int)GetFirstMaxValue(list, minTimestamp, defaultTimestamp);
|
||||
while (startTimestamp > minTimestamp)
|
||||
{
|
||||
startTimestamp -= tick;
|
||||
}
|
||||
if (startTimestamp < minTimestamp)
|
||||
{
|
||||
startTimestamp += tick;
|
||||
}
|
||||
list.Clear();
|
||||
AddTickTimestamp(list, startTimestamp, maxTimestamp, tick);
|
||||
}
|
||||
}
|
||||
return tick;
|
||||
}
|
||||
|
||||
private static double GetFirstMaxValue(List<double> list, double minTimestamp, double defaultTimestamp = 0)
|
||||
{
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (list[i] >= minTimestamp)
|
||||
{
|
||||
return list[i];
|
||||
}
|
||||
}
|
||||
return defaultTimestamp == 0 ? minTimestamp : defaultTimestamp;
|
||||
}
|
||||
|
||||
private static int GetSplitNumber(double range, int tickSecond)
|
||||
{
|
||||
var num = 1;
|
||||
while (range / (num * tickSecond) > 8)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
private static int GetTickSecond(double range, int splitNumber, int tickSecond)
|
||||
{
|
||||
var num = 0;
|
||||
if (splitNumber > 0)
|
||||
{
|
||||
num = (int)Math.Max(range / (splitNumber * tickSecond), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
num = 1;
|
||||
var tick = tickSecond;
|
||||
while (range / tick > 8)
|
||||
{
|
||||
num++;
|
||||
tick = num * tickSecond;
|
||||
}
|
||||
}
|
||||
return num * tickSecond;
|
||||
}
|
||||
|
||||
private static void AddTickTimestamp(List<double> list, double startTimestamp, double maxTimestamp, int tickSecond)
|
||||
{
|
||||
while (startTimestamp <= maxTimestamp)
|
||||
{
|
||||
list.Add(startTimestamp);
|
||||
startTimestamp += tickSecond;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f0ac80f189a04b5c826f40c8bc8af64
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,131 @@
|
||||
#if UNITY_EDITOR
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public static class DefineSymbolsUtil
|
||||
{
|
||||
private static readonly StringBuilder s_StringBuilder = new StringBuilder();
|
||||
|
||||
public static void AddGlobalDefine(string symbol)
|
||||
{
|
||||
var flag = false;
|
||||
var num = 0;
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
foreach (var buildTargetGroup in (BuildTargetGroup[]) Enum.GetValues(typeof(BuildTargetGroup)))
|
||||
{
|
||||
if (IsValidBuildTargetGroup(buildTargetGroup))
|
||||
{
|
||||
var buildTargetName = NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup);
|
||||
var symbols = PlayerSettings.GetScriptingDefineSymbols(buildTargetName);
|
||||
symbols = symbols.Replace(" ", "");
|
||||
if (Array.IndexOf(symbols.Split(';'), symbol) != -1) continue;
|
||||
flag = true;
|
||||
num++;
|
||||
var defines = symbols + (symbols.Length > 0 ? ";" + symbol : symbol);
|
||||
PlayerSettings.SetScriptingDefineSymbols(buildTargetName, defines);
|
||||
}
|
||||
}
|
||||
#else
|
||||
foreach (var buildTargetGroup in (BuildTargetGroup[]) Enum.GetValues(typeof(BuildTargetGroup)))
|
||||
{
|
||||
if (IsValidBuildTargetGroup(buildTargetGroup))
|
||||
{
|
||||
var symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup);
|
||||
symbols = symbols.Replace(" ", "");
|
||||
if (Array.IndexOf(symbols.Split(';'), symbol) != -1) continue;
|
||||
flag = true;
|
||||
num++;
|
||||
var defines = symbols + (symbols.Length > 0 ? ";" + symbol : symbol);
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, defines);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (flag)
|
||||
{
|
||||
Debug.LogFormat("Added global define symbol \"{0}\" to {1} BuildTargetGroups.", symbol, num);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveGlobalDefine(string symbol)
|
||||
{
|
||||
var flag = false;
|
||||
var num = 0;
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
foreach (var buildTargetGroup in (BuildTargetGroup[]) Enum.GetValues(typeof(BuildTargetGroup)))
|
||||
{
|
||||
if (IsValidBuildTargetGroup(buildTargetGroup))
|
||||
{
|
||||
var buildTargetName = NamedBuildTarget.FromBuildTargetGroup(buildTargetGroup);
|
||||
var symbols = PlayerSettings.GetScriptingDefineSymbols(buildTargetName).Split(';');
|
||||
if (Array.IndexOf(symbols, symbol) == -1) continue;
|
||||
flag = true;
|
||||
num++;
|
||||
s_StringBuilder.Length = 0;
|
||||
foreach (var str in symbols)
|
||||
{
|
||||
if (!str.Equals(symbol))
|
||||
{
|
||||
if (s_StringBuilder.Length > 0) s_StringBuilder.Append(";");
|
||||
s_StringBuilder.Append(str);
|
||||
}
|
||||
}
|
||||
PlayerSettings.SetScriptingDefineSymbols(buildTargetName, s_StringBuilder.ToString());
|
||||
}
|
||||
}
|
||||
#else
|
||||
foreach (var buildTargetGroup in (BuildTargetGroup[]) Enum.GetValues(typeof(BuildTargetGroup)))
|
||||
{
|
||||
if (IsValidBuildTargetGroup(buildTargetGroup))
|
||||
{
|
||||
var symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup).Split(';');
|
||||
if (Array.IndexOf(symbols, symbol) == -1) continue;
|
||||
flag = true;
|
||||
num++;
|
||||
s_StringBuilder.Length = 0;
|
||||
foreach (var str in symbols)
|
||||
{
|
||||
if (!str.Equals(symbol))
|
||||
{
|
||||
if (s_StringBuilder.Length > 0) s_StringBuilder.Append(";");
|
||||
s_StringBuilder.Append(str);
|
||||
}
|
||||
}
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, s_StringBuilder.ToString());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (flag)
|
||||
{
|
||||
Debug.LogFormat("Removed global define symbol \"{0}\" to {1} BuildTargetGroups.", symbol, num);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsValidBuildTargetGroup(BuildTargetGroup group)
|
||||
{
|
||||
if (group == BuildTargetGroup.Unknown) return false;
|
||||
var type = Type.GetType("UnityEditor.Modules.ModuleManager, UnityEditor.dll");
|
||||
if (type == null) return true;
|
||||
var method1 = type.GetMethod("GetTargetStringFromBuildTargetGroup", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
var method2 = typeof(PlayerSettings).GetMethod("GetPlatformName", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
if (method1 == null || method2 == null) return true;
|
||||
var str1 = (string) method1.Invoke(null, new object[] { group });
|
||||
var str2 = (string) method2.Invoke(null, new object[] { group });
|
||||
if (string.IsNullOrEmpty(str1))
|
||||
{
|
||||
return !string.IsNullOrEmpty(str2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91545951242fa441eb1a9bba3a6ad5a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public static class JsonUtil
|
||||
{
|
||||
|
||||
public static IEnumerator GetWebJson<T>(string url, Action<T[]> callback)
|
||||
{
|
||||
var www = UnityWebRequest.Get(url);
|
||||
yield return www;
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (www.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (www.isNetworkError || www.isHttpError)
|
||||
#endif
|
||||
{
|
||||
Debug.LogError("GetWebJson Error: " + www.error);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
var json = www.downloadHandler.text.Trim();
|
||||
callback(GetJsonArray<T>(json));
|
||||
www.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerator GetWebJson<T>(string url, Action<T> callback)
|
||||
{
|
||||
var www = UnityWebRequest.Get(url);
|
||||
yield return www;
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
if (www.result != UnityWebRequest.Result.Success)
|
||||
#else
|
||||
if (www.isNetworkError || www.isHttpError)
|
||||
#endif
|
||||
{
|
||||
Debug.LogError("GetWebJson Error: " + www.error);
|
||||
}
|
||||
else
|
||||
{
|
||||
var json = www.downloadHandler.text.Trim();
|
||||
callback(GetJsonObject<T>(json));
|
||||
www.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public static T GetJsonObject<T>(string json)
|
||||
{
|
||||
return JsonUtility.FromJson<T>(json);
|
||||
}
|
||||
|
||||
public static T[] GetJsonArray<T>(string json)
|
||||
{
|
||||
string newJson = "{ \"array\": " + json + "}";
|
||||
Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(newJson);
|
||||
return wrapper.array;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private class Wrapper<T>
|
||||
{
|
||||
#pragma warning disable 0649
|
||||
public T[] array;
|
||||
#pragma warning restore 0649
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 88e9115d32af34a3dae0d5c3e32de41c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public static class PropertyUtil
|
||||
{
|
||||
public static bool SetColor(ref Color currentValue, Color newValue)
|
||||
{
|
||||
if (currentValue.r == newValue.r && currentValue.g == newValue.g && currentValue.b == newValue.b && currentValue.a == newValue.a)
|
||||
return false;
|
||||
|
||||
currentValue = newValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool SetColor(ref Color32 currentValue, Color32 newValue)
|
||||
{
|
||||
if (currentValue.r == newValue.r && currentValue.g == newValue.g && currentValue.b == newValue.b && currentValue.a == newValue.a)
|
||||
return false;
|
||||
|
||||
currentValue = newValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool SetStruct<T>(ref T currentValue, T newValue) where T : struct
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(currentValue, newValue))
|
||||
return false;
|
||||
|
||||
currentValue = newValue;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool SetClass<T>(ref T currentValue, T newValue, bool notNull = false) where T : class
|
||||
{
|
||||
if (notNull)
|
||||
{
|
||||
if (newValue == null)
|
||||
{
|
||||
Debug.LogError("can not be null.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ((currentValue == null && newValue == null) || (currentValue != null && currentValue.Equals(newValue)))
|
||||
return false;
|
||||
|
||||
currentValue = newValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1f52eadd805d43aea47947fb81e761f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,133 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public static class ReflectionUtil
|
||||
{
|
||||
private static Dictionary<object, MethodInfo> listClearMethodInfoCaches = new Dictionary<object, MethodInfo>();
|
||||
private static Dictionary<object, MethodInfo> listAddMethodInfoCaches = new Dictionary<object, MethodInfo>();
|
||||
|
||||
public static void InvokeListClear(object obj, FieldInfo field)
|
||||
{
|
||||
var list = field.GetValue(obj);
|
||||
MethodInfo method;
|
||||
if (!listClearMethodInfoCaches.TryGetValue(list, out method))
|
||||
{
|
||||
method = list.GetType().GetMethod("Clear");
|
||||
listClearMethodInfoCaches[list] = method;
|
||||
}
|
||||
method.Invoke(list, new object[] { });
|
||||
}
|
||||
public static int InvokeListCount(object obj, FieldInfo field)
|
||||
{
|
||||
var list = field.GetValue(obj);
|
||||
return (int) list.GetType().GetProperty("Count").GetValue(list, null);
|
||||
}
|
||||
|
||||
public static void InvokeListAdd(object obj, FieldInfo field, object item)
|
||||
{
|
||||
var list = field.GetValue(obj);
|
||||
MethodInfo method;
|
||||
if (!listAddMethodInfoCaches.TryGetValue(list, out method))
|
||||
{
|
||||
method = list.GetType().GetMethod("Add");
|
||||
listAddMethodInfoCaches[list] = method;
|
||||
}
|
||||
method.Invoke(list, new object[] { item });
|
||||
}
|
||||
|
||||
public static T InvokeListGet<T>(object obj, FieldInfo field, int i)
|
||||
{
|
||||
var list = field.GetValue(obj);
|
||||
var item = list.GetType().GetProperty("Item").GetValue(list, new object[] { i });
|
||||
return (T) item;
|
||||
}
|
||||
|
||||
public static void InvokeListAddTo<T>(object obj, FieldInfo field, Action<T> callback)
|
||||
{
|
||||
var list = field.GetValue(obj);
|
||||
var listType = list.GetType();
|
||||
var count = Convert.ToInt32(listType.GetProperty("Count").GetValue(list, null));
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var item = listType.GetProperty("Item").GetValue(list, new object[] { i });
|
||||
callback((T) item);
|
||||
}
|
||||
}
|
||||
|
||||
public static object DeepCloneSerializeField(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
var type = obj.GetType();
|
||||
if (type.IsValueType || type == typeof(string))
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
else if (type.IsArray)
|
||||
{
|
||||
var elementType = Type.GetType(type.FullName.Replace("[]", string.Empty));
|
||||
var array = obj as Array;
|
||||
var copied = Array.CreateInstance(elementType, array.Length);
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
copied.SetValue(DeepCloneSerializeField(array.GetValue(i)), i);
|
||||
return Convert.ChangeType(copied, obj.GetType());
|
||||
}
|
||||
else if (type.IsClass)
|
||||
{
|
||||
object returnObj;
|
||||
var listObj = obj as IList;
|
||||
if (listObj != null)
|
||||
{
|
||||
var properties = type.GetProperties();
|
||||
var customList = typeof(List<>).MakeGenericType((properties[properties.Length - 1]).PropertyType);
|
||||
returnObj = (IList) Activator.CreateInstance(customList);
|
||||
var list = (IList) returnObj;
|
||||
foreach (var item in ((IList) obj))
|
||||
{
|
||||
if (item == null)
|
||||
continue;
|
||||
list.Add(DeepCloneSerializeField(item));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
returnObj = Activator.CreateInstance(type);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var fileds = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
for (int i = 0; i < fileds.Length; i++)
|
||||
{
|
||||
var field = fileds[i];
|
||||
if (!field.IsDefined(typeof(SerializeField), false))
|
||||
continue;
|
||||
var filedValue = field.GetValue(obj);
|
||||
if (filedValue == null)
|
||||
{
|
||||
field.SetValue(returnObj, filedValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
field.SetValue(returnObj, DeepCloneSerializeField(filedValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
return returnObj;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("DeepCloneSerializeField: Unknown type:" + type + "," + obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03acc4ee710ff4bad9a1740391c86cb9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Assertions;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public static class RuntimeUtil
|
||||
{
|
||||
public static bool HasSubclass(Type type)
|
||||
{
|
||||
var typeMap = GetAllTypesDerivedFrom(type);
|
||||
foreach (var t in typeMap)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> GetAllTypesDerivedFrom<T>()
|
||||
{
|
||||
#if UNITY_EDITOR && UNITY_2019_2_OR_NEWER
|
||||
return UnityEditor.TypeCache.GetTypesDerivedFrom<T>();
|
||||
#else
|
||||
return GetAllAssemblyTypes().Where(t => t.IsSubclassOf(typeof(T)));
|
||||
#endif
|
||||
}
|
||||
public static IEnumerable<Type> GetAllTypesDerivedFrom(Type type)
|
||||
{
|
||||
#if UNITY_EDITOR && UNITY_2019_2_OR_NEWER
|
||||
return UnityEditor.TypeCache.GetTypesDerivedFrom(type);
|
||||
#else
|
||||
return GetAllAssemblyTypes().Where(t => t.IsSubclassOf(type));
|
||||
#endif
|
||||
}
|
||||
|
||||
static IEnumerable<Type> m_AssemblyTypes;
|
||||
|
||||
public static IEnumerable<Type> GetAllAssemblyTypes()
|
||||
{
|
||||
if (m_AssemblyTypes == null)
|
||||
{
|
||||
m_AssemblyTypes = AppDomain.CurrentDomain.GetAssemblies()
|
||||
.SelectMany(t =>
|
||||
{
|
||||
var innerTypes = new Type[0];
|
||||
try
|
||||
{
|
||||
innerTypes = t.GetTypes();
|
||||
}
|
||||
catch { }
|
||||
return innerTypes;
|
||||
});
|
||||
}
|
||||
return m_AssemblyTypes;
|
||||
}
|
||||
|
||||
public static T GetAttribute<T>(this Type type, bool check = true) where T : Attribute
|
||||
{
|
||||
if (type.IsDefined(typeof(T), false))
|
||||
return (T) type.GetCustomAttributes(typeof(T), false) [0];
|
||||
else
|
||||
{
|
||||
if (check)
|
||||
Assert.IsTrue(false, "Attribute not found:" + type.Name);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static T GetAttribute<T>(this MemberInfo type, bool check = true) where T : Attribute
|
||||
{
|
||||
if (type.IsDefined(typeof(T), false))
|
||||
return (T) type.GetCustomAttributes(typeof(T), false) [0];
|
||||
else
|
||||
{
|
||||
if (check)
|
||||
Assert.IsTrue(false, "Attribute not found:" + type.Name);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44becf1664ae64397b44adcf65e6d8d2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user