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.

EngineProfilerInspector.cs 9.4KB

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