Skip to content

Commit ee9aac1

Browse files
committed
Added NetworkProfiler editor window
1 parent ebfd9c1 commit ee9aac1

File tree

1 file changed

+218
-0
lines changed

1 file changed

+218
-0
lines changed

MLAPI-Editor/MLAPIProfiler.cs

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
using MLAPI.Data.NetworkProfiler;
2+
using System.Collections.Generic;
3+
using UnityEditor;
4+
using UnityEngine;
5+
6+
public class MLAPIProfiler : EditorWindow
7+
{
8+
[MenuItem("Window/MLAPI Profiler")]
9+
public static void ShowWindow()
10+
{
11+
GetWindow<MLAPIProfiler>();
12+
}
13+
14+
GUIStyle wrapStyle
15+
{
16+
get
17+
{
18+
Color color = EditorStyles.label.normal.textColor;
19+
GUIStyle style = EditorStyles.centeredGreyMiniLabel;
20+
style.wordWrap = true;
21+
style.normal.textColor = color;
22+
return style;
23+
}
24+
}
25+
float updateDelay = 1f;
26+
int captureCount = 100;
27+
float showMax = 0;
28+
float showMin = 0;
29+
bool record = false;
30+
AnimationCurve curve = AnimationCurve.Constant(0, 1, 0);
31+
readonly List<ProfilerTick> currentTicks = new List<ProfilerTick>();
32+
float lastDrawn = 0;
33+
struct ProfilerContainer
34+
{
35+
ProfilerTick[] ticks;
36+
}
37+
private void OnGUI()
38+
{
39+
if (!NetworkProfiler.IsRunning && record)
40+
{
41+
if (NetworkProfiler.Ticks != null && NetworkProfiler.Ticks.Count >= 2)
42+
curve = AnimationCurve.Constant(NetworkProfiler.Ticks.ElementAt(0).Frame, NetworkProfiler.Ticks.ElementAt(NetworkProfiler.Ticks.Count - 1).Frame, 0);
43+
else
44+
curve = AnimationCurve.Constant(0, 1, 0);
45+
46+
lastDrawn = 0;
47+
NetworkProfiler.Start(captureCount);
48+
}
49+
//Draw top bar
50+
EditorGUILayout.BeginVertical();
51+
EditorGUILayout.BeginHorizontal();
52+
bool prevRec = record;
53+
record = EditorGUILayout.Toggle("Record", record);
54+
if (GUILayout.Button("Import datafile"))
55+
{
56+
string path = EditorUtility.OpenFilePanel("Choose a NetworkProfilerFile", "", "");
57+
58+
}
59+
EditorGUILayout.EndHorizontal();
60+
float prevHis = captureCount;
61+
captureCount = EditorGUILayout.DelayedIntField("History count", captureCount);
62+
if (captureCount <= 0)
63+
captureCount = 1;
64+
updateDelay = EditorGUILayout.Slider("Refresh delay", updateDelay, 0.1f, 10f);
65+
EditorGUILayout.EndVertical();
66+
67+
if (prevRec != record)
68+
{
69+
if (prevRec)
70+
{
71+
NetworkProfiler.Stop();
72+
}
73+
else
74+
{
75+
if (NetworkProfiler.Ticks != null && NetworkProfiler.Ticks.Count >= 2)
76+
curve = AnimationCurve.Constant(NetworkProfiler.Ticks.ElementAt(0).EventId, NetworkProfiler.Ticks.ElementAt(NetworkProfiler.Ticks.Count - 1).EventId, 0);
77+
else
78+
curve = AnimationCurve.Constant(0, 1, 0);
79+
lastDrawn = 0;
80+
NetworkProfiler.Start(captureCount);
81+
}
82+
}
83+
if (prevHis != captureCount)
84+
{
85+
NetworkProfiler.Stop();
86+
87+
if (NetworkProfiler.Ticks != null && NetworkProfiler.Ticks.Count >= 2)
88+
curve = AnimationCurve.Constant(NetworkProfiler.Ticks.ElementAt(0).EventId, NetworkProfiler.Ticks.ElementAt(NetworkProfiler.Ticks.Count - 1).EventId, 0);
89+
else
90+
curve = AnimationCurve.Constant(0, 1, 0);
91+
92+
lastDrawn = 0;
93+
NetworkProfiler.Start(captureCount);
94+
}
95+
96+
//Cache
97+
if (NetworkProfiler.IsRunning)
98+
{
99+
if (Time.unscaledTime - lastDrawn > updateDelay)
100+
{
101+
lastDrawn = Time.unscaledTime;
102+
currentTicks.Clear();
103+
if (NetworkProfiler.Ticks.Count >= 2)
104+
curve = AnimationCurve.Constant(NetworkProfiler.Ticks.ElementAt(0).EventId, NetworkProfiler.Ticks.ElementAt(NetworkProfiler.Ticks.Count - 1).EventId, 0);
105+
106+
for (int i = 0; i < NetworkProfiler.Ticks.Count; i++)
107+
{
108+
ProfilerTick tick = NetworkProfiler.Ticks.ElementAt(i);
109+
currentTicks.Add(tick);
110+
111+
uint bytes = 0;
112+
if (tick.Events.Count > 0)
113+
{
114+
for (int j = 0; j < tick.Events.Count; j++)
115+
{
116+
TickEvent tickEvent = tick.Events[j];
117+
bytes += tickEvent.Bytes;
118+
}
119+
}
120+
curve.AddKey(tick.EventId, bytes);
121+
}
122+
}
123+
}
124+
125+
126+
//Draw Animation curve and slider
127+
curve = EditorGUILayout.CurveField(curve);
128+
EditorGUILayout.MinMaxSlider(ref showMin, ref showMax, 0, currentTicks.Count);
129+
//Verify slider values
130+
if (showMin < 0)
131+
showMin = 0;
132+
if (showMax > currentTicks.Count)
133+
showMax = currentTicks.Count;
134+
if (showMin <= 0 && showMax <= 0)
135+
{
136+
showMin = 0;
137+
showMax = currentTicks.Count;
138+
}
139+
140+
//Draw main board
141+
int nonEmptyTicks = 0;
142+
int largestTickCount = 0;
143+
int totalTicks = ((int)showMax - (int)showMin);
144+
145+
for (int i = (int)showMin; i < (int)showMax; i++)
146+
{
147+
if (currentTicks[i].Events.Count > 0) nonEmptyTicks++; //Count non empty ticks
148+
if (currentTicks[i].Events.Count > largestTickCount) largestTickCount = currentTicks[i].Events.Count; //Get how many events the tick with most events has
149+
}
150+
int emptyTicks = totalTicks - nonEmptyTicks;
151+
152+
float equalWidth = position.width / totalTicks;
153+
float propWidth = equalWidth * 0.3f;
154+
float widthPerTick = ((position.width - emptyTicks * propWidth) / nonEmptyTicks);
155+
156+
float currentX = 0;
157+
int emptyStreak = 0;
158+
for (int i = (int)showMin; i < (int)showMax; i++)
159+
{
160+
ProfilerTick tick = currentTicks[i];
161+
if (tick.Events.Count == 0 && i != totalTicks - 1)
162+
{
163+
emptyStreak++;
164+
continue;
165+
}
166+
else if (emptyStreak > 0 || i == totalTicks - 1)
167+
{
168+
Rect dataRect = new Rect(currentX, 100, propWidth * emptyStreak, position.height - 100);
169+
currentX += propWidth * emptyStreak;
170+
EditorGUI.LabelField(new Rect(dataRect.x, dataRect.y, dataRect.width, dataRect.height), emptyStreak.ToString(), wrapStyle);
171+
emptyStreak = 0;
172+
}
173+
174+
if (tick.Events.Count > 0)
175+
{
176+
float heightPerEvent = ((position.height - 100f) - (5f * largestTickCount)) / largestTickCount;
177+
float heightPerTotalBackground = ((position.height - 100f) - (5f * largestTickCount)) / tick.Events.Count;
178+
179+
float currentY = 100;
180+
for (int j = 0; j < tick.Events.Count; j++)
181+
{
182+
TickEvent tickEvent = tick.Events[j];
183+
Rect dataRect = new Rect(currentX, currentY, widthPerTick, heightPerEvent);
184+
if (j == tick.Events.Count - 1)
185+
dataRect.height -= 45f;
186+
EditorGUI.DrawRect(dataRect, TickTypeToColor(tickEvent.EventType));
187+
float heightPerField = heightPerEvent / 12f;
188+
EditorGUI.LabelField(new Rect(dataRect.x, dataRect.y + heightPerField * -3f, dataRect.width, dataRect.height), "EventType: " + tickEvent.EventType.ToString(), wrapStyle);
189+
EditorGUI.LabelField(new Rect(dataRect.x, dataRect.y + heightPerField * -1f, dataRect.width, dataRect.height), "Size: " + tickEvent.Bytes + "B", wrapStyle);
190+
EditorGUI.LabelField(new Rect(dataRect.x, dataRect.y + heightPerField * 1f, dataRect.width, dataRect.height), "Channel: " + tickEvent.ChannelName, wrapStyle);
191+
EditorGUI.LabelField(new Rect(dataRect.x, dataRect.y + heightPerField * 3f, dataRect.width, dataRect.height), "MessageType: " + tickEvent.MessageType, wrapStyle);
192+
193+
currentY += heightPerEvent + 5f;
194+
}
195+
}
196+
EditorGUI.DrawRect(new Rect(currentX, position.height - 40, widthPerTick, 40), TickTypeToColor(tick.Type));
197+
EditorGUI.LabelField(new Rect(currentX, position.height - 40, widthPerTick, 20), "TickType: " + tick.Type.ToString(), wrapStyle);
198+
EditorGUI.LabelField(new Rect(currentX, position.height - 20, widthPerTick, 20), "Frame: " + tick.Frame.ToString(), wrapStyle);
199+
currentX += widthPerTick;
200+
}
201+
202+
Repaint();
203+
}
204+
205+
private static Color TickTypeToColor(TickType type)
206+
{
207+
switch (type)
208+
{
209+
case TickType.Event:
210+
return new Color(0.58f, 0f, 0.56f, 0.37f);
211+
case TickType.Receive:
212+
return new Color(0f, 0.85f, 0.85f, 0.28f);
213+
case TickType.Send:
214+
return new Color(0, 0.55f, 1f, 0.06f);
215+
}
216+
return EditorGUIUtility.isProSkin ? new Color32(70, 70, 70, 255) : new Color32(200, 200, 200, 255);
217+
}
218+
}

0 commit comments

Comments
 (0)