Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
9.3KB

  1. #if asdUNITY_EDITOR
  2. using System;
  3. using System.Collections.Generic;
  4. using UnityEditor;
  5. using UnityEngine;
  6. //This profiler is based on the Entitas Visual Debugging tool
  7. //https://github.com/sschmid/Entitas-CSharp
  8. namespace Svelto.ECS.Profiler
  9. {
  10. [CustomEditor(typeof (EngineProfilerBehaviour))]
  11. public class EngineProfilerInspector : Editor
  12. {
  13. enum SORTING_OPTIONS
  14. {
  15. AVERAGE,
  16. MIN,
  17. MAX,
  18. NAME,
  19. NONE
  20. }
  21. static bool _hideEmptyEngines = true;
  22. static bool _showAddEngines;
  23. static bool _showRemoveEngines;
  24. static string _systemNameSearchTerm = string.Empty;
  25. string minTitle = "Min".PadRight(15, ' ');
  26. string maxTitle = "Max".PadRight(15, ' ');
  27. string avgTitle = "Avg".PadRight(15, ' ');
  28. SORTING_OPTIONS _sortingOption = SORTING_OPTIONS.AVERAGE;
  29. public override void OnInspectorGUI()
  30. {
  31. var engineProfilerBehaviour = (EngineProfilerBehaviour) target;
  32. EngineInfo[] engines = new EngineInfo[engineProfilerBehaviour.engines.Count];
  33. engineProfilerBehaviour.engines.CopyTo(engines, 0);
  34. DrawEngineList(engineProfilerBehaviour, engines);
  35. EditorUtility.SetDirty(target);
  36. }
  37. void DrawEngineList(EngineProfilerBehaviour engineProfilerBehaviour, EngineInfo[] engines)
  38. {
  39. ProfilerEditorLayout.BeginVerticalBox();
  40. {
  41. ProfilerEditorLayout.BeginHorizontal();
  42. {
  43. if (GUILayout.Button("Reset Durations", GUILayout.Width(120), GUILayout.Height(14)))
  44. {
  45. engineProfilerBehaviour.ResetDurations();
  46. }
  47. }
  48. ProfilerEditorLayout.EndHorizontal();
  49. _sortingOption = (SORTING_OPTIONS) EditorGUILayout.EnumPopup("Sort By:", _sortingOption);
  50. _hideEmptyEngines = EditorGUILayout.Toggle("Hide empty systems", _hideEmptyEngines);
  51. EditorGUILayout.Space();
  52. ProfilerEditorLayout.BeginHorizontal();
  53. {
  54. _systemNameSearchTerm = EditorGUILayout.TextField("Search", _systemNameSearchTerm);
  55. const string clearButtonControlName = "Clear Button";
  56. GUI.SetNextControlName(clearButtonControlName);
  57. if (GUILayout.Button("x", GUILayout.Width(19), GUILayout.Height(14)))
  58. {
  59. _systemNameSearchTerm = string.Empty;
  60. GUI.FocusControl(clearButtonControlName);
  61. }
  62. }
  63. ProfilerEditorLayout.EndHorizontal();
  64. _showAddEngines = EditorGUILayout.Foldout(_showAddEngines, "Engines Add");
  65. if (_showAddEngines && ShouldShowSystems(engines))
  66. {
  67. ProfilerEditorLayout.BeginVerticalBox();
  68. {
  69. var systemsDrawn = DrawAddEngineInfos(engines);
  70. if (systemsDrawn == 0)
  71. {
  72. EditorGUILayout.LabelField(string.Empty);
  73. }
  74. }
  75. ProfilerEditorLayout.EndVertical();
  76. }
  77. _showRemoveEngines = EditorGUILayout.Foldout(_showRemoveEngines, "Engines Remove");
  78. if (_showRemoveEngines && ShouldShowSystems(engines))
  79. {
  80. ProfilerEditorLayout.BeginVerticalBox();
  81. {
  82. var systemsDrawn = DrawRemoveEngineInfos(engines);
  83. if (systemsDrawn == 0)
  84. {
  85. EditorGUILayout.LabelField(string.Empty);
  86. }
  87. }
  88. ProfilerEditorLayout.EndVertical();
  89. }
  90. }
  91. ProfilerEditorLayout.EndVertical();
  92. }
  93. int DrawAddEngineInfos(EngineInfo[] engines)
  94. {
  95. if (_sortingOption != SORTING_OPTIONS.NONE)
  96. {
  97. SortAddEngines(engines);
  98. }
  99. string title = avgTitle.FastConcat(minTitle).FastConcat(maxTitle);
  100. EditorGUILayout.LabelField("Engine Name", title, EditorStyles.boldLabel);
  101. int enginesDrawn = 0;
  102. for (int i = 0; i < engines.Length; i++)
  103. {
  104. EngineInfo engineInfo = engines[i];
  105. if (engineInfo.engineName.ToLower().Contains(_systemNameSearchTerm.ToLower()) &&
  106. !engineInfo.minAddDuration.Equals(0) && !engineInfo.maxAddDuration.Equals(0))
  107. {
  108. ProfilerEditorLayout.BeginHorizontal();
  109. {
  110. var avg = string.Format("{0:0.000}", engineInfo.averageAddDuration).PadRight(15);
  111. var min = string.Format("{0:0.000}", engineInfo.minAddDuration).PadRight(15);
  112. var max = string.Format("{0:0.000}", engineInfo.maxAddDuration);
  113. string output = avg.FastConcat(min).FastConcat(max);
  114. EditorGUILayout.LabelField(engineInfo.engineName, output, GetEngineStyle());
  115. }
  116. ProfilerEditorLayout.EndHorizontal();
  117. enginesDrawn += 1;
  118. }
  119. }
  120. return enginesDrawn;
  121. }
  122. int DrawRemoveEngineInfos(EngineInfo[] engines)
  123. {
  124. if (_sortingOption != SORTING_OPTIONS.NONE)
  125. {
  126. SortRemoveEngines(engines);
  127. }
  128. string title = avgTitle.FastConcat(minTitle).FastConcat(maxTitle);
  129. EditorGUILayout.LabelField("Engine Name", title, EditorStyles.boldLabel);
  130. int enginesDrawn = 0;
  131. for (int i = 0; i < engines.Length; i++)
  132. {
  133. EngineInfo engineInfo = engines[i];
  134. if (engineInfo.engineName.ToLower().Contains(_systemNameSearchTerm.ToLower()) &&
  135. !engineInfo.minRemoveDuration.Equals(0) && !engineInfo.maxRemoveDuration.Equals(0))
  136. {
  137. ProfilerEditorLayout.BeginHorizontal();
  138. {
  139. var avg = string.Format("{0:0.000}", engineInfo.averageRemoveDuration).PadRight(15);
  140. var min = string.Format("{0:0.000}", engineInfo.minRemoveDuration).PadRight(15);
  141. var max = string.Format("{0:0.000}", engineInfo.maxRemoveDuration);
  142. string output = avg.FastConcat(min).FastConcat(max);
  143. EditorGUILayout.LabelField(engineInfo.engineName, output, GetEngineStyle());
  144. }
  145. ProfilerEditorLayout.EndHorizontal();
  146. enginesDrawn += 1;
  147. }
  148. }
  149. return enginesDrawn;
  150. }
  151. static GUIStyle GetEngineStyle()
  152. {
  153. var style = new GUIStyle(GUI.skin.label);
  154. var color = EditorGUIUtility.isProSkin ? Color.white : style.normal.textColor;
  155. style.normal.textColor = color;
  156. return style;
  157. }
  158. static bool ShouldShowSystems(EngineInfo[] engines)
  159. {
  160. return engines.Length > 0;
  161. }
  162. #region Sorting Engines
  163. void SortAddEngines(EngineInfo[] engines)
  164. {
  165. switch (_sortingOption)
  166. {
  167. case SORTING_OPTIONS.AVERAGE:
  168. Array.Sort(engines,
  169. (engine1, engine2) => engine2.averageAddDuration.CompareTo(engine1.averageAddDuration));
  170. break;
  171. case SORTING_OPTIONS.MIN:
  172. Array.Sort(engines,
  173. (engine1, engine2) => engine2.minAddDuration.CompareTo(engine1.minAddDuration));
  174. break;
  175. case SORTING_OPTIONS.MAX:
  176. Array.Sort(engines,
  177. (engine1, engine2) => engine2.maxAddDuration.CompareTo(engine1.maxAddDuration));
  178. break;
  179. case SORTING_OPTIONS.NAME:
  180. Array.Sort(engines,
  181. (engine1, engine2) => String.Compare(engine1.engineName, engine2.engineName, StringComparison.Ordinal));
  182. break;
  183. }
  184. }
  185. void SortRemoveEngines(EngineInfo[] engines)
  186. {
  187. switch (_sortingOption)
  188. {
  189. case SORTING_OPTIONS.AVERAGE:
  190. Array.Sort(engines,
  191. (engine1, engine2) => engine2.averageRemoveDuration.CompareTo(engine1.averageRemoveDuration));
  192. break;
  193. case SORTING_OPTIONS.MIN:
  194. Array.Sort(engines,
  195. (engine1, engine2) => engine2.minRemoveDuration.CompareTo(engine1.minRemoveDuration));
  196. break;
  197. case SORTING_OPTIONS.MAX:
  198. Array.Sort(engines,
  199. (engine1, engine2) => engine2.maxRemoveDuration.CompareTo(engine1.maxRemoveDuration));
  200. break;
  201. case SORTING_OPTIONS.NAME:
  202. Array.Sort(engines,
  203. (engine1, engine2) => String.Compare(engine1.engineName, engine2.engineName, StringComparison.Ordinal));
  204. break;
  205. }
  206. }
  207. }
  208. #endregion
  209. }
  210. #endif