|
|
|
|
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
|
|
|
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System;
|
|
|
|
|
using UnityEditor.IMGUI.Controls;
|
|
|
|
|
using Cysharp.Threading.Tasks.Internal;
|
|
|
|
|
|
|
|
|
|
namespace Cysharp.Threading.Tasks.Editor
|
|
|
|
|
{
|
|
|
|
|
public class UniTaskTrackerWindow : EditorWindow
|
|
|
|
|
{
|
|
|
|
|
static int interval;
|
|
|
|
|
|
|
|
|
|
static UniTaskTrackerWindow window;
|
|
|
|
|
|
|
|
|
|
[MenuItem("Window/UniTask Tracker")]
|
|
|
|
|
public static void OpenWindow()
|
|
|
|
|
{
|
|
|
|
|
if (window != null)
|
|
|
|
|
{
|
|
|
|
|
window.Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// will called OnEnable(singleton instance will be set).
|
|
|
|
|
GetWindow<UniTaskTrackerWindow>("UniTask Tracker").Show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static readonly GUILayoutOption[] EmptyLayoutOption = new GUILayoutOption[0];
|
|
|
|
|
|
|
|
|
|
UniTaskTrackerTreeView treeView;
|
|
|
|
|
object splitterState;
|
|
|
|
|
|
|
|
|
|
void OnEnable()
|
|
|
|
|
{
|
|
|
|
|
window = this; // set singleton.
|
|
|
|
|
splitterState = SplitterGUILayout.CreateSplitterState(new float[] { 75f, 25f }, new int[] { 32, 32 }, null);
|
|
|
|
|
treeView = new UniTaskTrackerTreeView();
|
|
|
|
|
TaskTracker.EditorEnableState.EnableAutoReload = EditorPrefs.GetBool(TaskTracker.EnableAutoReloadKey, false);
|
|
|
|
|
TaskTracker.EditorEnableState.EnableTracking = EditorPrefs.GetBool(TaskTracker.EnableTrackingKey, false);
|
|
|
|
|
TaskTracker.EditorEnableState.EnableStackTrace = EditorPrefs.GetBool(TaskTracker.EnableStackTraceKey, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OnGUI()
|
|
|
|
|
{
|
|
|
|
|
// Head
|
|
|
|
|
RenderHeadPanel();
|
|
|
|
|
|
|
|
|
|
// Splittable
|
|
|
|
|
SplitterGUILayout.BeginVerticalSplit(this.splitterState, EmptyLayoutOption);
|
|
|
|
|
{
|
|
|
|
|
// Column Tabble
|
|
|
|
|
RenderTable();
|
|
|
|
|
|
|
|
|
|
// StackTrace details
|
|
|
|
|
RenderDetailsPanel();
|
|
|
|
|
}
|
|
|
|
|
SplitterGUILayout.EndVerticalSplit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region HeadPanel
|
|
|
|
|
|
|
|
|
|
public static bool EnableAutoReload => TaskTracker.EditorEnableState.EnableAutoReload;
|
|
|
|
|
public static bool EnableTracking => TaskTracker.EditorEnableState.EnableTracking;
|
|
|
|
|
public static bool EnableStackTrace => TaskTracker.EditorEnableState.EnableStackTrace;
|
|
|
|
|
static readonly GUIContent EnableAutoReloadHeadContent = EditorGUIUtility.TrTextContent("Enable AutoReload", "Reload automatically.", (Texture)null);
|
|
|
|
|
static readonly GUIContent ReloadHeadContent = EditorGUIUtility.TrTextContent("Reload", "Reload View.", (Texture)null);
|
|
|
|
|
static readonly GUIContent GCHeadContent = EditorGUIUtility.TrTextContent("GC.Collect", "Invoke GC.Collect.", (Texture)null);
|
|
|
|
|
static readonly GUIContent EnableTrackingHeadContent = EditorGUIUtility.TrTextContent("Enable Tracking", "Start to track async/await UniTask. Performance impact: low", (Texture)null);
|
|
|
|
|
static readonly GUIContent EnableStackTraceHeadContent = EditorGUIUtility.TrTextContent("Enable StackTrace", "Capture StackTrace when task is started. Performance impact: high", (Texture)null);
|
|
|
|
|
|
|
|
|
|
// [Enable Tracking] | [Enable StackTrace]
|
|
|
|
|
void RenderHeadPanel()
|
|
|
|
|
{
|
|
|
|
|
EditorGUILayout.BeginVertical(EmptyLayoutOption);
|
|
|
|
|
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar, EmptyLayoutOption);
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Toggle(EnableAutoReload, EnableAutoReloadHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableAutoReload)
|
|
|
|
|
{
|
|
|
|
|
TaskTracker.EditorEnableState.EnableAutoReload = !EnableAutoReload;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Toggle(EnableTracking, EnableTrackingHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableTracking)
|
|
|
|
|
{
|
|
|
|
|
TaskTracker.EditorEnableState.EnableTracking = !EnableTracking;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Toggle(EnableStackTrace, EnableStackTraceHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption) != EnableStackTrace)
|
|
|
|
|
{
|
|
|
|
|
TaskTracker.EditorEnableState.EnableStackTrace = !EnableStackTrace;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GUILayout.FlexibleSpace();
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button(ReloadHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
|
|
|
|
|
{
|
|
|
|
|
TaskTracker.CheckAndResetDirty();
|
|
|
|
|
treeView.ReloadAndSort();
|
|
|
|
|
Repaint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GUILayout.Button(GCHeadContent, EditorStyles.toolbarButton, EmptyLayoutOption))
|
|
|
|
|
{
|
|
|
|
|
GC.Collect(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
EditorGUILayout.EndVertical();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region TableColumn
|
|
|
|
|
|
|
|
|
|
Vector2 tableScroll;
|
|
|
|
|
GUIStyle tableListStyle;
|
|
|
|
|
|
|
|
|
|
void RenderTable()
|
|
|
|
|
{
|
|
|
|
|
if (tableListStyle == null)
|
|
|
|
|
{
|
|
|
|
|
tableListStyle = new GUIStyle("CN Box");
|
|
|
|
|
tableListStyle.margin.top = 0;
|
|
|
|
|
tableListStyle.padding.left = 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.BeginVertical(tableListStyle, EmptyLayoutOption);
|
|
|
|
|
|
|
|
|
|
this.tableScroll = EditorGUILayout.BeginScrollView(this.tableScroll, new GUILayoutOption[]
|
|
|
|
|
{
|
|
|
|
|
GUILayout.ExpandWidth(true),
|
|
|
|
|
GUILayout.MaxWidth(2000f)
|
|
|
|
|
});
|
|
|
|
|
var controlRect = EditorGUILayout.GetControlRect(new GUILayoutOption[]
|
|
|
|
|
{
|
|
|
|
|
GUILayout.ExpandHeight(true),
|
|
|
|
|
GUILayout.ExpandWidth(true)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
treeView?.OnGUI(controlRect);
|
|
|
|
|
|
|
|
|
|
EditorGUILayout.EndScrollView();
|
|
|
|
|
EditorGUILayout.EndVertical();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Update()
|
|
|
|
|
{
|
|
|
|
|
if (EnableAutoReload)
|
|
|
|
|
{
|
|
|
|
|
if (interval++ % 120 == 0)
|
|
|
|
|
{
|
|
|
|
|
if (TaskTracker.CheckAndResetDirty())
|
|
|
|
|
{
|
|
|
|
|
treeView.ReloadAndSort();
|
|
|
|
|
Repaint();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Details
|
|
|
|
|
|
|
|
|
|
static GUIStyle detailsStyle;
|
|
|
|
|
Vector2 detailsScroll;
|
|
|
|
|
|
|
|
|
|
void RenderDetailsPanel()
|
|
|
|
|
{
|
|
|
|
|
if (detailsStyle == null)
|
|
|
|
|
{
|
|
|
|
|
detailsStyle = new GUIStyle("CN Message");
|
|
|
|
|
detailsStyle.wordWrap = false;
|
|
|
|
|
detailsStyle.stretchHeight = true;
|
|
|
|
|
detailsStyle.margin.right = 15;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string message = "";
|
|
|
|
|
var selected = treeView.state.selectedIDs;
|
|
|
|
|
if (selected.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var first = selected[0];
|
|
|
|
|
var item = treeView.CurrentBindingItems.FirstOrDefault(x => x.id == first) as UniTaskTrackerViewItem;
|
|
|
|
|
if (item != null)
|
|
|
|
|
{
|
|
|
|
|
message = item.Position;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
detailsScroll = EditorGUILayout.BeginScrollView(this.detailsScroll, EmptyLayoutOption);
|
|
|
|
|
var vector = detailsStyle.CalcSize(new GUIContent(message));
|
|
|
|
|
EditorGUILayout.SelectableLabel(message, detailsStyle, new GUILayoutOption[]
|
|
|
|
|
{
|
|
|
|
|
GUILayout.ExpandHeight(true),
|
|
|
|
|
GUILayout.ExpandWidth(true),
|
|
|
|
|
GUILayout.MinWidth(vector.x),
|
|
|
|
|
GUILayout.MinHeight(vector.y)
|
|
|
|
|
});
|
|
|
|
|
EditorGUILayout.EndScrollView();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|