UniTaskTrackerWindow.cs 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
  2. using UnityEngine;
  3. using UnityEditor;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Reflection;
  7. using System;
  8. using UnityEditor.IMGUI.Controls;
  9. using Cysharp.Threading.Tasks.Internal;
  10. namespace Cysharp.Threading.Tasks.Editor
  11. {
  12. public class UniTaskTrackerWindow : EditorWindow
  13. {
  14. static int interval;
  15. static UniTaskTrackerWindow window;
  16. [MenuItem("Window/UniTask Tracker")]
  17. public static void OpenWindow()
  18. {
  19. if (window != null)
  20. {
  21. window.Close();
  22. }
  23. // will called OnEnable(singleton instance will be set).
  24. GetWindow<UniTaskTrackerWindow>("UniTask Tracker").Show();
  25. }
  26. static readonly GUILayoutOption[] EmptyLayoutOption = new GUILayoutOption[0];
  27. UniTaskTrackerTreeView treeView;
  28. object splitterState;
  29. void OnEnable()
  30. {
  31. window = this; // set singleton.
  32. splitterState = SplitterGUILayout.CreateSplitterState(new float[] { 75f, 25f }, new int[] { 32, 32 }, null);
  33. treeView = new UniTaskTrackerTreeView();
  34. TaskTracker.EditorEnableState.EnableAutoReload = EditorPrefs.GetBool(TaskTracker.EnableAutoReloadKey, false);
  35. TaskTracker.EditorEnableState.EnableTracking = EditorPrefs.GetBool(TaskTracker.EnableTrackingKey, false);
  36. TaskTracker.EditorEnableState.EnableStackTrace = EditorPrefs.GetBool(TaskTracker.EnableStackTraceKey, false);
  37. }
  38. void OnGUI()
  39. {
  40. // Head
  41. RenderHeadPanel();
  42. // Splittable
  43. SplitterGUILayout.BeginVerticalSplit(this.splitterState, EmptyLayoutOption);
  44. {
  45. // Column Tabble
  46. RenderTable();
  47. // StackTrace details
  48. RenderDetailsPanel();
  49. }
  50. SplitterGUILayout.EndVerticalSplit();
  51. }
  52. #region HeadPanel
  53. public static bool EnableAutoReload => TaskTracker.EditorEnableState.EnableAutoReload;
  54. public static bool EnableTracking => TaskTracker.EditorEnableState.EnableTracking;
  55. public static bool EnableStackTrace => TaskTracker.EditorEnableState.EnableStackTrace;
  56. static readonly GUIContent EnableAutoReloadHeadContent = EditorGUIUtility.TrTextContent("Enable AutoReload", "Reload automatically.", (Texture)null);
  57. static readonly GUIContent ReloadHeadContent = EditorGUIUtility.TrTextContent("Reload", "Reload View.", (Texture)null);
  58. static readonly GUIContent GCHeadContent = EditorGUIUtility.TrTextContent("GC.Collect", "Invoke GC.Collect.", (Texture)null);
  59. static readonly GUIContent EnableTrackingHeadContent = EditorGUIUtility.TrTextContent("Enable Tracking", "Start to track async/await UniTask. Performance impact: low", (Texture)null);
  60. static readonly GUIContent EnableStackTraceHeadContent = EditorGUIUtility.TrTextContent("Enable StackTrace", "Capture StackTrace when task is started. Performance impact: high", (Texture)null);
  61. // [Enable Tracking] | [Enable StackTrace]
  62. void RenderHeadPanel()
  63. {
  64. EditorGUILayout.BeginVertical(EmptyLayoutOption);
  65. EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, EmptyLayoutOption);
  66. if (GUILayout.Toggle(EnableAutoReload, EnableAutoReloadHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableAutoReload)
  67. {
  68. TaskTracker.EditorEnableState.EnableAutoReload = !EnableAutoReload;
  69. }
  70. if (GUILayout.Toggle(EnableTracking, EnableTrackingHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableTracking)
  71. {
  72. TaskTracker.EditorEnableState.EnableTracking = !EnableTracking;
  73. }
  74. if (GUILayout.Toggle(EnableStackTrace, EnableStackTraceHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableStackTrace)
  75. {
  76. TaskTracker.EditorEnableState.EnableStackTrace = !EnableStackTrace;
  77. }
  78. GUILayout.FlexibleSpace();
  79. if (GUILayout.Button(ReloadHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
  80. {
  81. TaskTracker.CheckAndResetDirty();
  82. treeView.ReloadAndSort();
  83. Repaint();
  84. }
  85. if (GUILayout.Button(GCHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
  86. {
  87. GC.Collect(0);
  88. }
  89. EditorGUILayout.EndHorizontal();
  90. EditorGUILayout.EndVertical();
  91. }
  92. #endregion
  93. #region TableColumn
  94. Vector2 tableScroll;
  95. GUIStyle tableListStyle;
  96. void RenderTable()
  97. {
  98. if (tableListStyle == null)
  99. {
  100. tableListStyle = new GUIStyle("CN Box");
  101. tableListStyle.margin.top = 0;
  102. tableListStyle.padding.left = 3;
  103. }
  104. EditorGUILayout.BeginVertical(tableListStyle, EmptyLayoutOption);
  105. this.tableScroll = EditorGUILayout.BeginScrollView(this.tableScroll, new GUILayoutOption[]
  106. {
  107. GUILayout.ExpandWidth(true),
  108. GUILayout.MaxWidth(2000f)
  109. });
  110. var controlRect = EditorGUILayout.GetControlRect(new GUILayoutOption[]
  111. {
  112. GUILayout.ExpandHeight(true),
  113. GUILayout.ExpandWidth(true)
  114. });
  115. treeView?.OnGUI(controlRect);
  116. EditorGUILayout.EndScrollView();
  117. EditorGUILayout.EndVertical();
  118. }
  119. private void Update()
  120. {
  121. if (EnableAutoReload)
  122. {
  123. if (interval++ % 120 == 0)
  124. {
  125. if (TaskTracker.CheckAndResetDirty())
  126. {
  127. treeView.ReloadAndSort();
  128. Repaint();
  129. }
  130. }
  131. }
  132. }
  133. #endregion
  134. #region Details
  135. static GUIStyle detailsStyle;
  136. Vector2 detailsScroll;
  137. void RenderDetailsPanel()
  138. {
  139. if (detailsStyle == null)
  140. {
  141. detailsStyle = new GUIStyle("CN Message");
  142. detailsStyle.wordWrap = false;
  143. detailsStyle.stretchHeight = true;
  144. detailsStyle.margin.right = 15;
  145. }
  146. string message = "";
  147. var selected = treeView.state.selectedIDs;
  148. if (selected.Count > 0)
  149. {
  150. var first = selected[0];
  151. var item = treeView.CurrentBindingItems.FirstOrDefault(x => x.id == first) as UniTaskTrackerViewItem;
  152. if (item != null)
  153. {
  154. message = item.Position;
  155. }
  156. }
  157. detailsScroll = EditorGUILayout.BeginScrollView(this.detailsScroll, EmptyLayoutOption);
  158. var vector = detailsStyle.CalcSize(new GUIContent(message));
  159. EditorGUILayout.SelectableLabel(message, detailsStyle, new GUILayoutOption[]
  160. {
  161. GUILayout.ExpandHeight(true),
  162. GUILayout.ExpandWidth(true),
  163. GUILayout.MinWidth(vector.x),
  164. GUILayout.MinHeight(vector.y)
  165. });
  166. EditorGUILayout.EndScrollView();
  167. }
  168. #endregion
  169. }
  170. }