Logging.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. using System;
  2. using System.Text;
  3. using UnityEngine;
  4. using Object = UnityEngine.Object;
  5. #if ENABLE_COFFEE_LOGGER
  6. using System.Reflection;
  7. using System.Collections.Generic;
  8. #else
  9. using Conditional = System.Diagnostics.ConditionalAttribute;
  10. #endif
  11. namespace Coffee.UIParticleInternal
  12. {
  13. internal static class Logging
  14. {
  15. #if !ENABLE_COFFEE_LOGGER
  16. private const string k_DisableSymbol = "DISABLE_COFFEE_LOGGER";
  17. [Conditional(k_DisableSymbol)]
  18. #endif
  19. private static void Log_Internal(LogType type, object tag, object message, Object context)
  20. {
  21. #if ENABLE_COFFEE_LOGGER
  22. AppendTag(s_Sb, tag);
  23. s_Sb.Append(message);
  24. switch (type)
  25. {
  26. case LogType.Error:
  27. case LogType.Assert:
  28. case LogType.Exception:
  29. Debug.LogError(s_Sb, context);
  30. break;
  31. case LogType.Warning:
  32. Debug.LogWarning(s_Sb, context);
  33. break;
  34. case LogType.Log:
  35. Debug.Log(s_Sb, context);
  36. break;
  37. }
  38. s_Sb.Length = 0;
  39. #endif
  40. }
  41. #if !ENABLE_COFFEE_LOGGER
  42. [Conditional(k_DisableSymbol)]
  43. #endif
  44. public static void LogIf(bool enable, object tag, object message, Object context = null)
  45. {
  46. if (!enable) return;
  47. Log_Internal(LogType.Log, tag, message, context ? context : tag as Object);
  48. }
  49. #if !ENABLE_COFFEE_LOGGER
  50. [Conditional(k_DisableSymbol)]
  51. #endif
  52. public static void Log(object tag, object message, Object context = null)
  53. {
  54. Log_Internal(LogType.Log, tag, message, context ? context : tag as Object);
  55. }
  56. #if !ENABLE_COFFEE_LOGGER
  57. [Conditional(k_DisableSymbol)]
  58. #endif
  59. public static void LogWarning(object tag, object message, Object context = null)
  60. {
  61. Log_Internal(LogType.Warning, tag, message, context ? context : tag as Object);
  62. }
  63. public static void LogError(object tag, object message, Object context = null)
  64. {
  65. #if ENABLE_COFFEE_LOGGER
  66. Log_Internal(LogType.Error, tag, message, context ? context : tag as Object);
  67. #else
  68. Debug.LogError($"{tag}: {message}", context);
  69. #endif
  70. }
  71. #if !ENABLE_COFFEE_LOGGER
  72. [Conditional(k_DisableSymbol)]
  73. #endif
  74. public static void LogMulticast(Type type, string fieldName, object instance = null, string message = null)
  75. {
  76. #if ENABLE_COFFEE_LOGGER
  77. AppendTag(s_Sb, instance ?? type);
  78. var handler = type
  79. .GetField(fieldName,
  80. BindingFlags.Static | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic)
  81. ?.GetValue(instance);
  82. var list = ((MulticastDelegate)handler)?.GetInvocationList() ?? Array.Empty<Delegate>();
  83. s_Sb.Append("<color=orange>");
  84. s_Sb.Append(type.Name);
  85. s_Sb.Append(".");
  86. s_Sb.Append(fieldName);
  87. s_Sb.Append(" has ");
  88. s_Sb.Append(list.Length);
  89. s_Sb.Append(" callbacks");
  90. if (message != null)
  91. {
  92. s_Sb.Append(" (");
  93. s_Sb.Append(message);
  94. s_Sb.Append(")");
  95. }
  96. s_Sb.Append(":</color>");
  97. for (var i = 0; i < list.Length; i++)
  98. {
  99. s_Sb.Append("\n - ");
  100. s_Sb.Append(list[i].Method.DeclaringType?.Name);
  101. s_Sb.Append(".");
  102. s_Sb.Append(list[i].Method.Name);
  103. }
  104. Debug.Log(s_Sb);
  105. s_Sb.Length = 0;
  106. #endif
  107. }
  108. #if !ENABLE_COFFEE_LOGGER
  109. [Conditional(k_DisableSymbol)]
  110. #endif
  111. private static void AppendTag(StringBuilder sb, object tag)
  112. {
  113. #if ENABLE_COFFEE_LOGGER
  114. try
  115. {
  116. sb.Append("f");
  117. sb.Append(Time.frameCount);
  118. sb.Append(":<color=#");
  119. AppendReadableCode(sb, tag);
  120. sb.Append("><b>[");
  121. switch (tag)
  122. {
  123. case string name:
  124. sb.Append(name);
  125. break;
  126. case Type type:
  127. AppendType(sb, type);
  128. break;
  129. case Object uObject:
  130. AppendType(sb, tag.GetType());
  131. sb.Append(" #");
  132. sb.Append(uObject.name);
  133. break;
  134. default:
  135. AppendType(sb, tag.GetType());
  136. break;
  137. }
  138. sb.Append("]</b></color> ");
  139. }
  140. catch
  141. {
  142. sb.Append("f");
  143. sb.Append(Time.frameCount);
  144. sb.Append(":<b>[");
  145. sb.Append(tag);
  146. sb.Append("]</b> ");
  147. }
  148. #endif
  149. }
  150. #if !ENABLE_COFFEE_LOGGER
  151. [Conditional(k_DisableSymbol)]
  152. #endif
  153. private static void AppendType(StringBuilder sb, Type type)
  154. {
  155. #if ENABLE_COFFEE_LOGGER
  156. if (s_TypeNameCache.TryGetValue(type, out var name))
  157. {
  158. sb.Append(name);
  159. return;
  160. }
  161. // New type found
  162. var start = sb.Length;
  163. if (0 < start && sb[start - 1] == '<' && (type.Name == "Material" || type.Name == "Color"))
  164. {
  165. sb.Append('@');
  166. }
  167. sb.Append(type.Name);
  168. if (type.IsGenericType)
  169. {
  170. sb.Length -= 2;
  171. sb.Append("<");
  172. foreach (var gType in type.GetGenericArguments())
  173. {
  174. AppendType(sb, gType);
  175. sb.Append(", ");
  176. }
  177. sb.Length -= 2;
  178. sb.Append(">");
  179. }
  180. s_TypeNameCache.Add(type, sb.ToString(start, sb.Length - start));
  181. #endif
  182. }
  183. #if !ENABLE_COFFEE_LOGGER
  184. [Conditional(k_DisableSymbol)]
  185. #endif
  186. private static void AppendReadableCode(StringBuilder sb, object tag)
  187. {
  188. #if ENABLE_COFFEE_LOGGER
  189. int hash;
  190. try
  191. {
  192. switch (tag)
  193. {
  194. case string text:
  195. hash = text.GetHashCode();
  196. break;
  197. case Type type:
  198. type = type.IsGenericType ? type.GetGenericTypeDefinition() : type;
  199. hash = type.FullName?.GetHashCode() ?? 0;
  200. break;
  201. default:
  202. hash = tag.GetType().FullName?.GetHashCode() ?? 0;
  203. break;
  204. }
  205. }
  206. catch
  207. {
  208. sb.Append("FFFFFF");
  209. return;
  210. }
  211. hash = hash & (s_Codes.Length - 1);
  212. if (s_Codes[hash] == null)
  213. {
  214. var hue = hash / (float)s_Codes.Length;
  215. var modifier = 1f - Mathf.Clamp01(Mathf.Abs(hue - 0.65f) / 0.2f);
  216. var saturation = 0.7f + modifier * -0.2f;
  217. var value = 0.8f + modifier * 0.3f;
  218. s_Codes[hash] = ColorUtility.ToHtmlStringRGB(Color.HSVToRGB(hue, saturation, value));
  219. }
  220. sb.Append(s_Codes[hash]);
  221. #endif
  222. }
  223. #if ENABLE_COFFEE_LOGGER
  224. private static readonly StringBuilder s_Sb = new StringBuilder();
  225. private static readonly string[] s_Codes = new string[64];
  226. private static readonly Dictionary<Type, string> s_TypeNameCache = new Dictionary<Type, string>();
  227. #endif
  228. }
  229. }