|
|
|
|
|
|
// Compile with: csc CRefTest.cs -doc:Results.xml
|
|
|
|
using System; |
|
|
|
using UnityEngine; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.IO; |
|
|
|
|
|
|
/// </summary>
|
|
|
|
[DataMember(Name = "children", Order = 999)] |
|
|
|
Dictionary<string, TimerNode> m_Children; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gauge Nodes to measure arbitrary values.
|
|
|
|
/// </summary>
|
|
|
|
[DataMember(Name = "gauges", EmitDefaultValue = false)] |
|
|
|
Dictionary<string, GaugeNode> m_Gauges; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Custom sampler used to add timings to the profiler.
|
|
|
|
|
|
|
var currentTicks = m_TotalTicks; |
|
|
|
if (m_TickStart != 0) |
|
|
|
{ |
|
|
|
currentTicks += (System.DateTime.Now.Ticks - m_TickStart); |
|
|
|
currentTicks += (DateTime.Now.Ticks - m_TickStart); |
|
|
|
} |
|
|
|
|
|
|
|
return currentTicks; |
|
|
|
|
|
|
set {} // Serialization needs this, but unused.
|
|
|
|
} |
|
|
|
|
|
|
|
public Dictionary<string, GaugeNode> Gauges |
|
|
|
{ |
|
|
|
get { return m_Gauges; } |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Total seconds spent in this block, excluding it's children.
|
|
|
|
/// </summary>
|
|
|
|
|
|
|
// have a sensible value for total time (the running time since reset).
|
|
|
|
// The root node doesn't have a sampler since that could interfere with the profiler.
|
|
|
|
m_NumCalls = 1; |
|
|
|
m_TickStart = System.DateTime.Now.Ticks; |
|
|
|
m_TickStart = DateTime.Now.Ticks; |
|
|
|
m_Gauges = new Dictionary<string, GaugeNode>(); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
|
|
|
public void Begin() |
|
|
|
{ |
|
|
|
m_Sampler?.Begin(); |
|
|
|
m_TickStart = System.DateTime.Now.Ticks; |
|
|
|
m_TickStart = DateTime.Now.Ticks; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
{ |
|
|
|
var elapsed = System.DateTime.Now.Ticks - m_TickStart; |
|
|
|
var elapsed = DateTime.Now.Ticks - m_TickStart; |
|
|
|
m_TotalTicks += elapsed; |
|
|
|
m_TickStart = 0; |
|
|
|
m_NumCalls++; |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Tracks the most recent value of a metric. This is analogous to gauges in statsd.
|
|
|
|
/// </summary>
|
|
|
|
[DataContract] |
|
|
|
public class GaugeNode |
|
|
|
{ |
|
|
|
[DataMember] |
|
|
|
public float value; |
|
|
|
[DataMember( Name = "min")] |
|
|
|
public float minValue; |
|
|
|
[DataMember( Name = "max")] |
|
|
|
public float maxValue; |
|
|
|
[DataMember] |
|
|
|
public uint count; |
|
|
|
public GaugeNode(float value) |
|
|
|
{ |
|
|
|
this.value = value; |
|
|
|
minValue = value; |
|
|
|
maxValue = value; |
|
|
|
count = 1; |
|
|
|
} |
|
|
|
|
|
|
|
public void Update(float newValue) |
|
|
|
{ |
|
|
|
minValue = Mathf.Min(minValue, newValue); |
|
|
|
maxValue = Mathf.Max(maxValue, newValue); |
|
|
|
value = newValue; |
|
|
|
++count; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// A "stack" of timers that allows for lightweight hierarchical profiling of long-running processes.
|
|
|
|
/// <example>
|
|
|
|
/// Example usage:
|
|
|
|
|
|
|
/// This implements the Singleton pattern (solution 4) as described in
|
|
|
|
/// https://csharpindepth.com/articles/singleton
|
|
|
|
/// </remarks>
|
|
|
|
public class TimerStack : System.IDisposable |
|
|
|
public class TimerStack : IDisposable |
|
|
|
{ |
|
|
|
static readonly TimerStack k_Instance = new TimerStack(); |
|
|
|
|
|
|
|
|
|
|
public TimerNode RootNode |
|
|
|
{ |
|
|
|
get { return m_RootNode; } |
|
|
|
} |
|
|
|
|
|
|
|
public void SetGauge(string name, float value) |
|
|
|
{ |
|
|
|
if (!float.IsNaN(value)) |
|
|
|
{ |
|
|
|
GaugeNode gauge; |
|
|
|
if (m_RootNode.Gauges.TryGetValue(name, out gauge)) |
|
|
|
{ |
|
|
|
gauge.Update(value); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
m_RootNode.Gauges[name] = new GaugeNode(value); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void Push(string name) |
|
|
|