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.3KB

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