diff options
Diffstat (limited to 'utils/vmpi/vmpi_job_watch/GraphControl.cpp')
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/GraphControl.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/utils/vmpi/vmpi_job_watch/GraphControl.cpp b/utils/vmpi/vmpi_job_watch/GraphControl.cpp new file mode 100644 index 0000000..44d7e57 --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/GraphControl.cpp @@ -0,0 +1,246 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// GraphControl.cpp : implementation file +// + +#include "stdafx.h" +#include "vmpi_browser_job_watch.h" +#include "GraphControl.h" +#include "mathlib/mathlib.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CGraphControl + +CGraphControl::CGraphControl() +{ +} + +CGraphControl::~CGraphControl() +{ +} + + +BEGIN_MESSAGE_MAP(CGraphControl, CWnd) + //{{AFX_MSG_MAP(CGraphControl) + ON_WM_PAINT() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +void CGraphControl::Clear() +{ + CRect rcClient; + GetClientRect( rcClient ); + + CDC *pDC = GetDC(); + + CBrush brush( RGB( 0, 0, 0 ) ); + CBrush *pOldBrush = pDC->SelectObject( &brush ); + pDC->Rectangle( 0, 0, rcClient.Width(), rcClient.Height() ); + pDC->SelectObject( pOldBrush ); + + ReleaseDC( pDC ); +} + +void CGraphControl::Render( CDC *pDC ) +{ + // Clear the background. + CRect rcClient; + GetClientRect( rcClient ); + + + CBrush brush( RGB( 0, 0, 0 ) ); + CBrush *pOldBrush = pDC->SelectObject( &brush ); + pDC->Rectangle( 0, 0, rcClient.Width(), rcClient.Height() ); + pDC->SelectObject( pOldBrush ); + + + + // Work backwards from the right side to the left. + int nIntervals = rcClient.Width(); + DWORD intervalMS = 500; // one interval per pixel + DWORD startTime = 0xFFFFFFFF, endTime = 0; + + // First, find which order of magnitude to use on the vertical scale by finding the maximum value. + for ( int iEntry=0; iEntry < m_Entries.Count(); iEntry++ ) + { + DWORD msTime = m_Entries[iEntry].m_msTime; + startTime = min( startTime, msTime ); + endTime = max( endTime, msTime ); + } + + int curTime = (int)endTime - nIntervals*intervalMS; + + + + CGraphEntry prevEntry, curEntry; + prevEntry.m_msTime = curEntry.m_msTime = -1; + + CUtlVector<POINT> sentPoints; + CUtlVector<POINT> receivedPoints; + + int iCurEntry = -1; + int nMaxBytesSent = -1, nMaxBytesReceived = -1; + + for ( int x=0; x < nIntervals; x++ ) + { + if ( curTime >= 0 ) + { + // Now find the graph_entry for the time we're at. + while ( prevEntry.m_msTime == -1 || curTime > curEntry.m_msTime ) + { + ++iCurEntry; + if ( iCurEntry >= m_Entries.Count() ) + goto ENDLOOP; + + prevEntry = curEntry; + curEntry = m_Entries[iCurEntry]; + } + + if ( curTime >= prevEntry.m_msTime && curTime <= curEntry.m_msTime ) + { + // Interpolate the bytes sent. + int nBytesSent = (int)RemapVal( + curTime, + prevEntry.m_msTime, curEntry.m_msTime, + prevEntry.m_nBytesSent, curEntry.m_nBytesSent ); + + POINT sentPoint = { x, nBytesSent }; + sentPoints.AddToTail( sentPoint ); + nMaxBytesSent = max( nMaxBytesSent, nBytesSent ); + + + int nBytesReceived = (int)RemapVal( + curTime, + prevEntry.m_msTime, curEntry.m_msTime, + prevEntry.m_nBytesReceived, curEntry.m_nBytesReceived ); + + POINT receivedPoint = { x, nBytesReceived }; + receivedPoints.AddToTail( receivedPoint ); + nMaxBytesReceived = max( nMaxBytesReceived, nBytesReceived ); + } + } + + curTime += intervalMS; + } + + ENDLOOP:; + + + // Now normalize all the values. + int largest = max( nMaxBytesSent, nMaxBytesReceived ); + int topValue = (largest*11) / 10; +/* + DWORD nZeros; + for( nZeros = 1; nZeros < 20; nZeros++ ) + { + if ( largest < pow( 10, nZeros ) ) + break; + } + + // Now find the value at the top of the graph. We choose the smallest enclosing tenth of the + // order of magnitude we're at (so if we were at 1,000,000, and our max value was 350,000, we'd choose 400,000). + int iTenth; + int topValue; + for ( iTenth=1; iTenth <= 10; iTenth++ ) + { + topValue = (DWORD)( pow( 10, nZeros-1 ) * iTenth ); + if ( topValue >= largest ) + break; + } +*/ + + for ( int iSample=0; iSample < sentPoints.Count(); iSample++ ) + { + double flHeight; + + flHeight = ((double)sentPoints[iSample].y / topValue) * (rcClient.Height() - 1); + sentPoints[iSample].y = (int)( rcClient.Height() - flHeight ); + + flHeight = ((double)receivedPoints[iSample].y / topValue) * (rcClient.Height() - 1); + receivedPoints[iSample].y = (int)( rcClient.Height() - flHeight ); + } + + + // Draw some horizontal lines dividing the space. + int nLines = 10; + for ( int iLine=0; iLine <= nLines; iLine++ ) + { + CPen penLine; + COLORREF color; + if ( iLine == 0 || iLine == nLines/2 ) + color = RGB( 0, 220, 0 ); + else + color = RGB( 0, 100, 0 ); + + penLine.CreatePen( PS_SOLID, 1, color ); + CPen *pOldPen = pDC->SelectObject( &penLine ); + + int y = (iLine * rcClient.Height()) / nLines; + pDC->MoveTo( 0, y ); + pDC->LineTo( rcClient.Width(), y ); + + pDC->SelectObject( pOldPen ); + } + + + // Now draw the lines for the data. + CPen penSent( PS_SOLID, 1, RGB( 0, 255, 0 ) ); + CPen *pOldPen = pDC->SelectObject( &penSent ); + pDC->Polyline( sentPoints.Base(), sentPoints.Count() ); + pDC->SelectObject( pOldPen ); + + CPen penReceived( PS_SOLID, 1, RGB( 255, 255, 0 ) ); + pOldPen = pDC->SelectObject( &penReceived ); + pDC->Polyline( receivedPoints.Base(), receivedPoints.Count() ); + pDC->SelectObject( pOldPen ); + + + + // Draw text labels. + pDC->SetTextColor( RGB( 200, 200, 200 ) ); + pDC->SetBkColor( 0 ); + + CString str; + str.Format( "%dk", (topValue+511) / 1024 ); + pDC->ExtTextOut( 0, 1, 0, NULL, str, NULL ); + + str.Format( "%dk", (topValue+511) / 1024 / 2 ); + pDC->ExtTextOut( 0, rcClient.Height()/2 + 1, 0, NULL, str, NULL ); +} + + +void CGraphControl::Fill( CUtlVector<CGraphEntry> &entries ) +{ + CDC *pDC = GetDC(); + if ( !pDC ) + return; + + m_Entries = entries; + + Render( pDC ); + + ReleaseDC( pDC ); +} + + +///////////////////////////////////////////////////////////////////////////// +// CGraphControl message handlers + +void CGraphControl::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + Render( &dc ); +} |