Newer
Older
Simple-Multiplayer-Unity3D / Multiplayer Project / Library / PackageCache / com.unity.performance.profile-analyzer@1.2.2 / Editor / Units.cs
  1. using System;
  2. using System.Globalization;
  3. using UnityEngine.Assertions;
  4. using UnityEngine;
  5. namespace UnityEditor.Performance.ProfileAnalyzer
  6. {
  7. /// <summary>Unit type identifier</summary>
  8. internal enum Units
  9. {
  10. /// <summary>Time in milliseconds</summary>
  11. Milliseconds,
  12. /// <summary>Time in microseconds</summary>
  13. Microseconds,
  14. /// <summary>Count of number of instances</summary>
  15. Count,
  16. };
  17. internal class DisplayUnits
  18. {
  19. public static readonly string[] UnitNames =
  20. {
  21. "Milliseconds",
  22. "Microseconds",
  23. "Count",
  24. };
  25. public static readonly int[] UnitValues = (int[])Enum.GetValues(typeof(Units));
  26. public readonly Units Units;
  27. const bool kShowFullValueWhenBelowZero = true;
  28. const int kTooltipDigitsNumber = 7;
  29. public DisplayUnits(Units units)
  30. {
  31. Assert.AreEqual(UnitNames.Length, UnitValues.Length, "Number of UnitNames should match number of enum values UnitValues: You probably forgot to update one of them.");
  32. Units = units;
  33. }
  34. public string Postfix()
  35. {
  36. switch (Units)
  37. {
  38. default:
  39. case Units.Milliseconds:
  40. return "ms";
  41. case Units.Microseconds:
  42. return "us";
  43. case Units.Count:
  44. return "";
  45. }
  46. }
  47. int ClampToRange(int value, int min, int max)
  48. {
  49. if (value < min)
  50. value = min;
  51. if (value > max)
  52. value = max;
  53. return value;
  54. }
  55. string RemoveTrailingZeros(string numberStr, int minNumberStringLength)
  56. {
  57. // Find out string length without trailing zeroes.
  58. var strLenWithoutTrailingZeros = numberStr.Length;
  59. while (strLenWithoutTrailingZeros > minNumberStringLength && numberStr[strLenWithoutTrailingZeros - 1] == '0')
  60. strLenWithoutTrailingZeros--;
  61. // Remove hanging '.' in case all zeroes can be omitted.
  62. if (strLenWithoutTrailingZeros > 0 && numberStr[strLenWithoutTrailingZeros - 1] == '.')
  63. strLenWithoutTrailingZeros--;
  64. return strLenWithoutTrailingZeros == numberStr.Length ? numberStr : numberStr.Substring(0, strLenWithoutTrailingZeros);
  65. }
  66. public string ToString(float ms, bool showUnits, int limitToNDigits, bool showFullValueWhenBelowZero = false)
  67. {
  68. float value = ms;
  69. int unitPower = -3;
  70. int minNumberStringLength = -1;
  71. int maxDecimalPlaces = 0;
  72. float minValueShownWhenUsingLimitedDecimalPlaces = 1f;
  73. switch (Units)
  74. {
  75. default:
  76. case Units.Milliseconds:
  77. maxDecimalPlaces = 2;
  78. minValueShownWhenUsingLimitedDecimalPlaces = 0.01f;
  79. break;
  80. case Units.Microseconds:
  81. value *= 1000f;
  82. unitPower -= 3;
  83. if (value < 100)
  84. {
  85. maxDecimalPlaces = 1;
  86. minValueShownWhenUsingLimitedDecimalPlaces = 0.1f;
  87. }
  88. else
  89. {
  90. maxDecimalPlaces = 0;
  91. minValueShownWhenUsingLimitedDecimalPlaces = 1f;
  92. }
  93. break;
  94. case Units.Count:
  95. showUnits = false;
  96. break;
  97. }
  98. int sgn = Math.Sign(value);
  99. if (value < 0)
  100. value = -value;
  101. int numberOfDecimalPlaces = maxDecimalPlaces;
  102. int unitsTextLength = showUnits ? 2 : 0;
  103. int signTextLength = sgn == -1 ? 1 : 0;
  104. if (limitToNDigits > 0 && value > float.Epsilon)
  105. {
  106. int numberOfSignificantFigures = limitToNDigits;
  107. if (!showFullValueWhenBelowZero)
  108. numberOfSignificantFigures -= unitsTextLength + signTextLength;
  109. int valueExp = (int)Math.Log10(value);
  110. // Less than 1 values needs exponent correction as (int) rounds to the upper negative.
  111. if (value < 1)
  112. valueExp -= 1;
  113. int originalUnitPower = unitPower;
  114. float limitRange = (float)Math.Pow(10, numberOfSignificantFigures);
  115. if (limitRange > 0)
  116. {
  117. if (value >= limitRange)
  118. {
  119. while (value >= 1000f && unitPower < 9)
  120. {
  121. value /= 1000f;
  122. unitPower += 3;
  123. valueExp -= 3;
  124. }
  125. }
  126. else if (showFullValueWhenBelowZero) // Only upscale and change unit type if we want to see exact number.
  127. {
  128. while (value < 0.01f && unitPower > -9)
  129. {
  130. value *= 1000f;
  131. unitPower -= 3;
  132. valueExp += 3;
  133. }
  134. }
  135. }
  136. if (unitPower != originalUnitPower)
  137. {
  138. showUnits = true;
  139. unitsTextLength = 2;
  140. numberOfSignificantFigures = limitToNDigits;
  141. if (!showFullValueWhenBelowZero)
  142. numberOfSignificantFigures -= unitsTextLength + signTextLength;
  143. }
  144. // Use all allowed digits to display significant digits if we have any beyond maxDecimalPlaces
  145. int numberOfDigitsBeforeDecimalPoint = 1 + Math.Max(0, valueExp);
  146. if (showFullValueWhenBelowZero)
  147. {
  148. numberOfDecimalPlaces = numberOfSignificantFigures - numberOfDigitsBeforeDecimalPoint;
  149. minNumberStringLength = numberOfDigitsBeforeDecimalPoint + signTextLength + maxDecimalPlaces + 1;
  150. }
  151. else
  152. numberOfDecimalPlaces = ClampToRange(numberOfSignificantFigures - numberOfDigitsBeforeDecimalPoint, 0, maxDecimalPlaces);
  153. }
  154. value *= sgn;
  155. string numberStr;
  156. if (value < minValueShownWhenUsingLimitedDecimalPlaces && showFullValueWhenBelowZero)
  157. {
  158. numberStr = string.Format(CultureInfo.InvariantCulture, "{0}", value);
  159. }
  160. else
  161. {
  162. string formatString = string.Concat("{0:f", numberOfDecimalPlaces, "}");
  163. numberStr = string.Format(CultureInfo.InvariantCulture, formatString, value);
  164. }
  165. // Remove trailing 0 if any from string
  166. if (minNumberStringLength > 0 && numberStr.Length > 0)
  167. numberStr = RemoveTrailingZeros(numberStr, minNumberStringLength);
  168. if (!showUnits)
  169. return numberStr;
  170. string siUnitString = GetSIUnitString(unitPower) + "s";
  171. return string.Concat(numberStr, siUnitString);
  172. }
  173. public static string GetSIUnitString(int unitPower)
  174. {
  175. // https://en.wikipedia.org/wiki/Metric_prefix
  176. switch (unitPower)
  177. {
  178. case -9:
  179. return "n";
  180. case -6:
  181. return "u";
  182. case -3:
  183. return "m";
  184. case 0:
  185. return "";
  186. case 3:
  187. return "k";
  188. case 6:
  189. return "M";
  190. case 9:
  191. return "G";
  192. }
  193. return "?";
  194. }
  195. public string ToTooltipString(double ms, bool showUnits, int frameIndex = -1)
  196. {
  197. if (frameIndex >= 0)
  198. return string.Format("{0} on frame {1}", ToString((float)ms, showUnits, kTooltipDigitsNumber, kShowFullValueWhenBelowZero), frameIndex);
  199. return ToString((float)ms, showUnits, kTooltipDigitsNumber, kShowFullValueWhenBelowZero);
  200. }
  201. public GUIContent ToGUIContentWithTooltips(float ms, bool showUnits = false, int limitToNDigits = 5, int frameIndex = -1)
  202. {
  203. return new GUIContent(ToString(ms, showUnits, limitToNDigits), ToTooltipString(ms, true, frameIndex));
  204. }
  205. }
  206. }