1616#include < mmsystem.h>
1717
1818#include < ConsoleHost.h>
19+
1920#include < imgui.h>
21+ #include < imguivariouscontrols.h>
2022
2123const int g_netOverlayOffsetX = -30 ;
2224const int g_netOverlayOffsetY = -60 ;
@@ -124,7 +126,7 @@ class NetOverlayMetricSink : public INetMetricSink
124126 }
125127 }
126128
127- CRGBA GetColorIndex (int i);
129+ ImColor GetColorIndex (int i);
128130
129131 void UpdateMetrics ();
130132
@@ -146,20 +148,42 @@ NetOverlayMetricSink::NetOverlayMetricSink()
146148
147149 static ConVar<bool > conVar (" netgraph" , ConVar_Archive, false , &m_enabled);
148150
149- OnPostFrontendRender .Connect ([=] ( )
151+ ConHost::OnShouldDrawGui .Connect ([this ]( bool * should )
150152 {
151- // update metrics
152- UpdateMetrics ( );
153+ *should = *should || m_enabled;
154+ } );
153155
154- // if enabled, render
155- if (m_enabled)
156+ ConHost::OnDrawGui.Connect ([this ]()
157+ {
158+ if (!m_enabled)
156159 {
157- // draw the base metrics
158- DrawBaseMetrics ();
160+ return ;
161+ }
159162
163+ auto & io = ImGui::GetIO ();
164+
165+ ImGui::SetNextWindowBgAlpha (0 .0f );
166+ ImGui::SetNextWindowPos (ImVec2 (io.DisplaySize .x + g_netOverlayOffsetX, io.DisplaySize .y + g_netOverlayOffsetY), ImGuiCond_Once, ImVec2 (1 .0f , 1 .0f ));
167+ ImGui::SetNextWindowSize (ImVec2 (g_netOverlayWidth, g_netOverlayHeight));
168+ ImGui::PushStyleVar (ImGuiStyleVar_WindowBorderSize, 0 .0f );
169+
170+ if (ImGui::Begin (" NetGraph" , nullptr , ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize))
171+ {
160172 // draw the graph
161173 DrawGraph ();
174+
175+ // draw the base metrics
176+ DrawBaseMetrics ();
162177 }
178+
179+ ImGui::PopStyleVar ();
180+ ImGui::End ();
181+ });
182+
183+ OnPostFrontendRender.Connect ([=] ()
184+ {
185+ // update metrics
186+ UpdateMetrics ();
163187 }, 50 );
164188
165189 static ConVar<bool > commandVar (" net_showCommands" , ConVar_Archive, false , &m_enabledCommands);
@@ -379,50 +403,46 @@ void NetOverlayMetricSink::UpdateMetrics()
379403
380404void NetOverlayMetricSink::DrawGraph ()
381405{
382- // calculate maximum height for this data subset
383- float maxHeight = 0 ;
384-
385- for (int i = 0 ; i < _countof (m_metrics); i++)
406+ static const char * names[NET_PACKET_SUB_MAX] =
386407 {
387- auto metric = m_metrics[i];
388- auto totalSize = metric.GetTotalSize ();
389-
390- if (totalSize > maxHeight)
391- {
392- maxHeight = totalSize;
393- }
394- }
395-
396- // calculate per-sample size
397- int perSampleSize = (g_netOverlayWidth / g_netOverlaySampleCount);
408+ " Routed Messages" ,
409+ " Reliables" ,
410+ " Misc"
411+ };
398412
399- for ( int i = 0 ; i < _countof (m_metrics) - 1 ; i++) // the last entry is transient, so ignore that
413+ static const ImColor colors[NET_PACKET_SUB_MAX] =
400414 {
401- auto metric = m_metrics[i];
415+ GetColorIndex (0 ),
416+ GetColorIndex (1 ),
417+ GetColorIndex (2 )
418+ };
402419
403- // base X/Y for this metric
404- int x = GetOverlayLeft () + (perSampleSize * i);
405- int y = GetOverlayTop () + (g_netOverlayHeight - 100 );
420+ struct DataContext
421+ {
422+ NetPacketMetrics* metrics;
423+ NetPacketSubComponent index;
424+ };
406425
407- for (int j = 0 ; j < NET_PACKET_SUB_MAX; j++)
408- {
409- // get Y for this submetric
410- float y1 = ceilf (y - ((metric.GetElementSize ((NetPacketSubComponent)j) / maxHeight) * (g_netOverlayHeight - 100 )));
411- float y2 = y;
426+ auto data0 = DataContext{ m_metrics, NET_PACKET_SUB_ROUTED_MESSAGES };
427+ auto data1 = DataContext{ m_metrics, NET_PACKET_SUB_RELIABLES };
428+ auto data2 = DataContext{ m_metrics, NET_PACKET_SUB_MISC };
412429
413- // set a rectangle
414- CRect rect (x, y1 , x + perSampleSize, y2);
415- CRGBA color = GetColorIndex (j);
430+ const void * datas[NET_PACKET_SUB_MAX] =
431+ {
432+ &data0,
433+ &data1,
434+ &data2
435+ };
416436
417- TheFonts->DrawRectangle (rect, color);
437+ ImGui::PlotMultiLines (" Net Bw" , NET_PACKET_SUB_MAX, names, colors, [](const void * cxt, int idx) -> float
438+ {
439+ auto dataContext = (DataContext*)cxt;
418440
419- // the next one starts where this one left off
420- y = y1 ;
421- }
422- }
441+ return dataContext->metrics [idx].GetElementSize (dataContext->index );
442+ }, datas, _countof (m_metrics) - 1 , FLT_MAX, FLT_MAX, ImVec2 (g_netOverlayWidth, g_netOverlayHeight - 100 ));
423443}
424444
425- CRGBA NetOverlayMetricSink::GetColorIndex (int index)
445+ ImColor NetOverlayMetricSink::GetColorIndex (int index)
426446{
427447 static CRGBA colorTable[] = {
428448 CRGBA (0x00 , 0x00 , 0xAA ),
@@ -439,7 +459,9 @@ CRGBA NetOverlayMetricSink::GetColorIndex(int index)
439459 CRGBA (0xFF , 0xFF , 0x55 )
440460 };
441461
442- return colorTable[index % _countof (colorTable)];
462+ auto thisColor = colorTable[index % _countof (colorTable)];
463+
464+ return ImColor{ thisColor.red , thisColor.green , thisColor.blue , thisColor.alpha };
443465}
444466
445467void NetOverlayMetricSink::DrawBaseMetrics ()
@@ -459,7 +481,9 @@ void NetOverlayMetricSink::DrawBaseMetrics()
459481 int outRoutePackets = m_lastOutRoutePackets;
460482
461483 // drawing
462- TheFonts->DrawText (va (L" ping: %dms\n in: %d/s\n out: %d/s\n rt: %d/%d/s" , ping, inPackets, outPackets, inRoutePackets, outRoutePackets), rect, color, 22 .0f , 1 .0f , " Lucida Console" );
484+ ImGui::Columns (2 );
485+ ImGui::Text (" %s" , va (" ping: %dms\n in: %d/s\n out: %d/s\n rt: %d/%d/s" , ping, inPackets, outPackets, inRoutePackets, outRoutePackets));
486+ ImGui::NextColumn ();
463487
464488 //
465489 // second column
@@ -475,7 +499,8 @@ void NetOverlayMetricSink::DrawBaseMetrics()
475499 int inRouteDelayMax = m_inRouteDelayMax;
476500
477501 // drawing
478- TheFonts->DrawText (va (L" \n in: %d b/s\n out: %d b/s\n rd: %d~%dms" , inBytes, outBytes, inRouteDelay, inRouteDelayMax), rect, color, 22 .0f , 1 .0f , " Lucida Console" );
502+ ImGui::Text (" %s" , va (" \n in: %d b/s\n out: %d b/s\n rd: %d~%dms" , inBytes, outBytes, inRouteDelay, inRouteDelayMax));
503+ ImGui::Columns (1 );
479504}
480505
481506static InitFunction initFunction ([] ()
0 commit comments