222 lines
6.2 KiB
C#
222 lines
6.2 KiB
C#
#if UNITY_EDITOR
|
|
using System.Diagnostics;
|
|
using FIMSpace.FEditor;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
#endif
|
|
|
|
namespace FIMSpace
|
|
{
|
|
/// <summary> Simple class for performance measurement.
|
|
/// After making build, all body of this class disappears to make it weightless.
|
|
/// It's not inside editor directory to give possibility to use it in main assembly. </summary>
|
|
public class FDebug_PerformanceTest
|
|
{
|
|
#if UNITY_EDITOR
|
|
Stopwatch watch = null;
|
|
GameObject parent;
|
|
|
|
long lastTicks = 0;
|
|
long lastMS = 0;
|
|
|
|
long dispTicks = 0;
|
|
double dispMS = 0;
|
|
|
|
public long LastMinTicks { get; private set; }
|
|
public long LastMaxTicks { get; private set; }
|
|
#endif
|
|
|
|
public FDebug_PerformanceTest()
|
|
{
|
|
#if UNITY_EDITOR
|
|
_foldout = false;
|
|
ResetMinMax();
|
|
#endif
|
|
}
|
|
|
|
public void ResetMinMax()
|
|
{
|
|
#if UNITY_EDITOR
|
|
LastMinTicks = long.MaxValue;
|
|
LastMaxTicks = long.MinValue;
|
|
#endif
|
|
}
|
|
|
|
public void Start(UnityEngine.GameObject owner, bool onlyIfSelected = true)
|
|
{
|
|
#if UNITY_EDITOR
|
|
|
|
//if (_foldout == false) return;
|
|
if (watch == null) watch = new Stopwatch();
|
|
parent = owner;
|
|
|
|
|
|
if (owner != null) if (onlyIfSelected) if (Selection.activeGameObject != parent) return;
|
|
watch.Reset();
|
|
watch.Start();
|
|
#endif
|
|
}
|
|
|
|
public void Pause()
|
|
{
|
|
#if UNITY_EDITOR
|
|
//if (_foldout == false) return;
|
|
if (watch.IsRunning) watch.Stop();
|
|
#endif
|
|
}
|
|
|
|
public void Continue()
|
|
{
|
|
#if UNITY_EDITOR
|
|
//if (_foldout == false) return;
|
|
if (!watch.IsRunning) watch.Start();
|
|
#endif
|
|
}
|
|
|
|
|
|
public void Finish(bool onlyIfSelected = true)
|
|
{
|
|
#if UNITY_EDITOR
|
|
//if (_foldout == false) return;
|
|
if (watch.IsRunning == false) return;
|
|
if (onlyIfSelected) if (Selection.activeGameObject != parent) return;
|
|
watch.Stop();
|
|
lastTicks = watch.ElapsedTicks;
|
|
lastMS = watch.ElapsedMilliseconds;
|
|
AddCurrentToAverage();
|
|
|
|
long avr = AverageTicks;
|
|
if (avr < LastMinTicks) LastMinTicks = avr;
|
|
if (avr > LastMaxTicks) LastMaxTicks = avr;
|
|
#endif
|
|
}
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
const int AVERAGES_COUNT = 16;
|
|
int currId = 0;
|
|
long[] averageTicks = new long[AVERAGES_COUNT];
|
|
|
|
void AddCurrentToAverage()
|
|
{
|
|
averageTicks[currId] = watch.ElapsedTicks;
|
|
currId += 1;
|
|
if (currId >= AVERAGES_COUNT) currId = 0;
|
|
}
|
|
|
|
long GetAverage(long[] list)
|
|
{
|
|
long averageSum = 0;
|
|
int averageReads = 0;
|
|
long max = long.MinValue; // remembering max value
|
|
|
|
for (int i = 0; i < list.Length; i++)
|
|
{
|
|
if (list[i] <= 0) continue;
|
|
averageSum += list[i];
|
|
averageReads += 1;
|
|
if (list[i] > max) { max = list[i]; }
|
|
}
|
|
|
|
averageSum -= max; // Remove extremum value to avoid processor peak values
|
|
averageReads -= 1;
|
|
|
|
if (averageReads <= 0) return 0;
|
|
|
|
return averageSum / (long)averageReads;
|
|
}
|
|
|
|
public bool _foldout { get; private set; }
|
|
|
|
public long AverageTicks { get { return GetAverage(averageTicks); } }
|
|
|
|
public double TicksToMs(long ticks)
|
|
{
|
|
if (ticks <= 0) return 0;
|
|
return 1000.0 * (double)ticks / Stopwatch.Frequency;
|
|
}
|
|
|
|
public double AverageMS { get { return TicksToMs(AverageTicks); } }
|
|
|
|
#endif
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
public void Editor_DisplayFoldoutButton(float yOffset = -20f, float xOffset = 4f)
|
|
{
|
|
var rct = GUILayoutUtility.GetLastRect();
|
|
rct.width = 12;
|
|
rct.height = 12;
|
|
rct.position = new Vector2(rct.position.x + xOffset, rct.position.y + yOffset);
|
|
|
|
Color preC = GUI.color;
|
|
GUI.color = new Color(1f, 1f, 1f, 0.7f);
|
|
if (GUI.Button(rct, FGUI_Resources.Tex_Debug, EditorStyles.label)) { _foldout = true; }
|
|
GUI.color = preC;
|
|
}
|
|
|
|
public void Editor_Display(string prefix = "", bool onlyPlaymode = true, bool drawAverages = true, float buttonYOffset = -20f, float buttonXOffset = 4f, float displayRate = 10f)
|
|
{
|
|
if (onlyPlaymode) if (!Application.isPlaying) return;
|
|
|
|
if (!_foldout)
|
|
{
|
|
Editor_DisplayFoldoutButton(buttonYOffset, buttonXOffset);
|
|
return;
|
|
}
|
|
|
|
Editor_DisplayAlways(prefix, false, drawAverages, displayRate);
|
|
}
|
|
|
|
float lastDisplayTime = -100f;
|
|
public bool Editor_DisplayAlways(string prefix = "", bool onlyPlaymode = true, bool drawAverages = true, float displayRate = 10f)
|
|
{
|
|
if (onlyPlaymode) if (!Application.isPlaying) return false;
|
|
|
|
#region Display Rate Implementation
|
|
|
|
float dispTime = Application.isPlaying ? Time.unscaledTime : (float)EditorApplication.timeSinceStartup;
|
|
|
|
bool updateDisp = false;
|
|
if (displayRate < 0.1f) updateDisp = true;
|
|
if (dispTime - lastDisplayTime > 1f / displayRate)
|
|
{
|
|
updateDisp = true;
|
|
lastDisplayTime = dispTime;
|
|
}
|
|
|
|
if (updateDisp)
|
|
{
|
|
if (!drawAverages)
|
|
{
|
|
dispTicks = lastTicks;
|
|
dispMS = TicksToMs(lastTicks);
|
|
}
|
|
else
|
|
{
|
|
dispTicks = AverageTicks;
|
|
dispMS = AverageMS;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
|
|
|
EditorGUILayout.LabelField(prefix + "Elapsed Ticks: " + dispTicks + " " + dispMS + "ms");
|
|
|
|
EditorGUILayout.EndVertical();
|
|
var rect = GUILayoutUtility.GetLastRect();
|
|
if (GUI.Button(rect, GUIContent.none, EditorStyles.label)) { _foldout = false; }
|
|
|
|
return updateDisp;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
}
|