using System; using System.Collections.Generic; using UnityEditor.AddressableAssets.Settings; using UnityEngine; using UnityEngine.ResourceManagement.Diagnostics; using UnityEngine.ResourceManagement; using UnityEditor.IMGUI.Controls; namespace UnityEditor.AddressableAssets.Diagnostics { /* * ResourceManager specific implementation of an EventViewerWindow */ class ResourceManagerCacheWindow : EditorWindow { // [MenuItem("Window/Asset Management/Resource Manager Cache", priority = 2051)] static void ShowWindow() { var window = GetWindow(); window.titleContent = new GUIContent("Resource Manager Cache", "Resource Manager Cache"); window.Show(); } class CacheDataTree : TreeView { ResourceManagerCacheWindow m_Window; static int Compare(TreeViewItem a, TreeViewItem b) { return ((EventTreeViewItem)b).m_state.ReferenceCount - ((EventTreeViewItem)a).m_state.ReferenceCount; } class EventTreeViewItem : TreeViewItem { internal OperationState m_state; public EventTreeViewItem(Dictionary states, OperationState e, int depth) : base(e.ObjectId, depth, string.Format("{0}\t{1}", e.ReferenceCount, e.DisplayName)) { m_state = e; if (e.Dependencies != null && e.Dependencies.Length > 0) { children = new List(e.Dependencies.Length); foreach (var d in e.Dependencies) AddChild(new EventTreeViewItem(states, states[d], depth + 1)); children.Sort(Compare); } } } public CacheDataTree(ResourceManagerCacheWindow rmcw, TreeViewState tvs) : base(tvs) { m_Window = rmcw; } protected override TreeViewItem BuildRoot() { TreeViewItem root = new TreeViewItem(-1, -1); root.children = new List(m_Window.m_OpStates.Count); foreach (var l in m_Window.m_OpStates) root.AddChild(new EventTreeViewItem(m_Window.m_OpStates, l.Value, 0)); root.children.Sort(Compare); return root; } } void OnEnable() { if (m_EventListTreeViewState == null) m_EventListTreeViewState = new TreeViewState(); m_OpStates = new Dictionary(); m_cacheTree = new CacheDataTree(this, m_EventListTreeViewState); m_cacheTree.Reload(); EditorApplication.playModeStateChanged += OnEditorPlayModeChanged; if (ProjectConfigData.PostProfilerEvents) DiagnosticEventCollectorSingleton.RegisterEventHandler(OnEvent, true, false); } private void OnDisable() { if (ProjectConfigData.PostProfilerEvents) DiagnosticEventCollectorSingleton.RegisterEventHandler(OnEvent, false, false); EditorApplication.playModeStateChanged -= OnEditorPlayModeChanged; } class OperationState { public int ObjectId; public string DisplayName; public int ReferenceCount; public int[] Dependencies; } Dictionary m_OpStates = new Dictionary(); int m_lastRepaintedFrame = -1; public void OnEvent(DiagnosticEvent evt) { var hash = evt.ObjectId; if (evt.Stream == (int)ResourceManager.DiagnosticEventType.AsyncOperationDestroy) { m_OpStates.Remove(hash); m_cacheTree.Reload(); Repaint(); return; } OperationState op; if (!m_OpStates.TryGetValue(hash, out op)) { if (evt.Stream != (int)ResourceManager.DiagnosticEventType.AsyncOperationCreate) { Debug.LogWarningFormat("Unable to find op info for id {0} - {1}, stream={2}", hash, evt.DisplayName, evt.Stream); } m_OpStates.Add(hash, op = new OperationState() { ObjectId = evt.ObjectId, DisplayName = evt.DisplayName, Dependencies = evt.Dependencies, ReferenceCount = 0 }); } if (evt.Stream == (int)ResourceManager.DiagnosticEventType.AsyncOperationReferenceCount) op.ReferenceCount = evt.Value; if (evt.Frame != m_lastRepaintedFrame) { m_lastRepaintedFrame = evt.Frame; m_cacheTree.Reload(); Repaint(); } } void OnEditorPlayModeChanged(PlayModeStateChange state) { if (ProjectConfigData.PostProfilerEvents) { if (state == PlayModeStateChange.EnteredPlayMode) DiagnosticEventCollectorSingleton.RegisterEventHandler(OnEvent, true, false); else if (state == PlayModeStateChange.EnteredEditMode) DiagnosticEventCollectorSingleton.RegisterEventHandler(OnEvent, false, false); } } TreeViewState m_EventListTreeViewState; CacheDataTree m_cacheTree; private void OnGUI() { var r = EditorGUILayout.GetControlRect(); Rect contentRect = new Rect(r.x, r.y, r.width, position.height - (r.y + r.x)); m_cacheTree.OnGUI(contentRect); } } }