diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/vmpi/vmpi_job_watch | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'utils/vmpi/vmpi_job_watch')
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/GraphControl.cpp | 246 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/GraphControl.h | 86 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/JobWatchDlg.cpp | 648 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/JobWatchDlg.h | 134 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/StdAfx.cpp | 15 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/StdAfx.h | 36 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/res/vmpi_browser_job_watch.ico | bin | 0 -> 1078 bytes | |||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/res/vmpi_browser_job_watch.rc2 | 13 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/resource.h | 32 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.cpp | 75 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.h | 56 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.rc | 183 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_job_watch/vmpi_job_watch.vpc | 80 |
13 files changed, 1604 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 ); +} diff --git a/utils/vmpi/vmpi_job_watch/GraphControl.h b/utils/vmpi/vmpi_job_watch/GraphControl.h new file mode 100644 index 0000000..b8fcb88 --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/GraphControl.h @@ -0,0 +1,86 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#if !defined(AFX_GRAPHCONTROL_H__9B50B827_F24D_4C5A_BA6E_A591A64E404D__INCLUDED_) +#define AFX_GRAPHCONTROL_H__9B50B827_F24D_4C5A_BA6E_A591A64E404D__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// GraphControl.h : header file +// + +#include "utlvector.h" + + +class CGraphEntry +{ +public: + CGraphEntry() : + m_msTime( 0 ), + m_nBytesSent( 0 ), + m_nBytesReceived( 0 ) + { + } + + int m_msTime; + int m_nBytesSent; + int m_nBytesReceived; +}; + + +///////////////////////////////////////////////////////////////////////////// +// CGraphControl window + +class CGraphControl : public CWnd +{ +// Construction +public: + CGraphControl(); + +// Attributes +public: + +// Operations +public: + + void Clear(); + + // This function assumes you've already run the query and the graph_entry's are selected in. + void Fill( CUtlVector<CGraphEntry> &entries ); + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CGraphControl) + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CGraphControl(); + + +protected: + + void Render( CDC *pDC ); + + CUtlVector<CGraphEntry> m_Entries; + + // Generated message map functions +protected: + //{{AFX_MSG(CGraphControl) + afx_msg void OnPaint(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_GRAPHCONTROL_H__9B50B827_F24D_4C5A_BA6E_A591A64E404D__INCLUDED_) diff --git a/utils/vmpi/vmpi_job_watch/JobWatchDlg.cpp b/utils/vmpi/vmpi_job_watch/JobWatchDlg.cpp new file mode 100644 index 0000000..4c7909b --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/JobWatchDlg.cpp @@ -0,0 +1,648 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// JobWatchDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "JobWatchDlg.h" +#include "tier1/strtools.h" +#include "consolewnd.h" +#include "vmpi_browser_helpers.h" + + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + + +#define IMPLEMENT_SORT_NUMBER_FN( FnName, VarName ) \ + static int CALLBACK FnName( LPARAM iItem1, LPARAM iItem2, LPARAM lpParam ) \ + { \ + CWorkerInfo *pInfo1 = (CWorkerInfo*)iItem1; \ + CWorkerInfo *pInfo2 = (CWorkerInfo*)iItem2; \ + return pInfo1->VarName > pInfo2->VarName; \ + } + +static int CALLBACK SortByName( LPARAM iItem1, LPARAM iItem2, LPARAM lpParam ) +{ + CWorkerInfo *pInfo1 = (CWorkerInfo*)iItem1; + CWorkerInfo *pInfo2 = (CWorkerInfo*)iItem2; + + return strcmp( pInfo1->m_ComputerName, pInfo2->m_ComputerName ); +} + +static int CALLBACK SortByCurrentStage( LPARAM iItem1, LPARAM iItem2, LPARAM lpParam ) +{ + CWorkerInfo *pInfo1 = (CWorkerInfo*)iItem1; + CWorkerInfo *pInfo2 = (CWorkerInfo*)iItem2; + + return strcmp( pInfo1->m_CurrentStage, pInfo2->m_CurrentStage ); +} + +IMPLEMENT_SORT_NUMBER_FN( SortByConnected, m_bConnected ) +IMPLEMENT_SORT_NUMBER_FN( SortByWorkUnitsDone, m_nWorkUnitsDone ); +IMPLEMENT_SORT_NUMBER_FN( SortByRunningTime, m_RunningTimeMS ); +IMPLEMENT_SORT_NUMBER_FN( SortByThread0WU, m_ThreadWUs[0] ); +IMPLEMENT_SORT_NUMBER_FN( SortByThread1WU, m_ThreadWUs[1] ); +IMPLEMENT_SORT_NUMBER_FN( SortByThread2WU, m_ThreadWUs[2] ); +IMPLEMENT_SORT_NUMBER_FN( SortByThread3WU, m_ThreadWUs[3] ); + +typedef int (CALLBACK *ServicesSortFn)( LPARAM iItem1, LPARAM iItem2, LPARAM lpParam ); + +struct +{ + char *pText; + int width; + ServicesSortFn sortFn; +} g_ColumnInfos[] = +{ + {"Computer Name", 150, SortByName}, + {"Connected", 70, SortByConnected}, + {"Work Units Done", 100, SortByWorkUnitsDone}, + {"Running Time", 80, SortByRunningTime}, + {"Current Stage", 180, SortByCurrentStage}, + {"Thread 0", 70, SortByThread0WU}, + {"Thread 1", 70, SortByThread1WU}, + {"Thread 2", 70, SortByThread2WU}, + {"Thread 3", 70, SortByThread3WU} +}; + +#define COLUMN_COMPUTER_NAME 0 +#define COLUMN_CONNECTED 1 +#define COLUMN_WORK_UNITS_DONE 2 +#define COLUMN_RUNNING_TIME 3 +#define COLUMN_CURRENT_STAGE 4 +#define COLUMN_THREAD0_WU 5 +#define COLUMN_THREAD1_WU 6 +#define COLUMN_THREAD2_WU 7 +#define COLUMN_THREAD3_WU 8 + +int g_iSortColumn = 0; + + +///////////////////////////////////////////////////////////////////////////// +// CJobWatchDlg dialog + + +CJobWatchDlg::CJobWatchDlg(CWnd* pParent /*=NULL*/) + : CIdleDialog(CJobWatchDlg::IDD, pParent) +{ + m_CurMessageIndex = 0; + m_CurGraphTime = 0; + m_pSQL = NULL; + m_hMySQLDLL = NULL; + m_CurWorkerTextToken = 0; + m_LastQueryTime = 0; + + //{{AFX_DATA_INIT(CJobWatchDlg) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +CJobWatchDlg::~CJobWatchDlg() +{ + if ( m_pSQL ) + { + m_pSQL->Release(); + } + + if ( m_hMySQLDLL ) + { + Sys_UnloadModule( m_hMySQLDLL ); + } +} + + +void CJobWatchDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CJobWatchDlg) + DDX_Control(pDX, IDC_WORKERS, m_Workers); + DDX_Control(pDX, IDC_TEXTOUTPUT, m_TextOutput); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(CJobWatchDlg, CIdleDialog) + //{{AFX_MSG_MAP(CJobWatchDlg) + ON_LBN_SELCHANGE(IDC_WORKERS, OnSelChangeWorkers) + ON_WM_SIZE() + ON_NOTIFY(LVN_ODSTATECHANGED, IDC_WORKERS, OnOdstatechangedWorkers) + ON_NOTIFY(LVN_ITEMCHANGED, IDC_WORKERS, OnItemchangedWorkers) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CJobWatchDlg message handlers + +const char* FindArg( const char *pArgName, const char *pDefault="" ) +{ + for ( int i=1; i < __argc; i++ ) + { + if ( Q_stricmp( pArgName, __argv[i] ) == 0 ) + { + if ( (i+1) < __argc ) + return __argv[i+1]; + else + return pDefault; + } + } + return NULL; +} + + +bool ReadStringFromFile( FILE *fp, char *pStr, int strSize ) +{ + int i=0; + for ( i; i < strSize-2; i++ ) + { + if ( fread( &pStr[i], 1, 1, fp ) != 1 || + pStr[i] == '\n' ) + { + break; + } + } + + pStr[i] = 0; + return i != 0; +} + + +BOOL CJobWatchDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + + + m_Workers.SetExtendedStyle( LVS_EX_FULLROWSELECT ); + + // Setup the headers. + for ( int i=0; i < ARRAYSIZE( g_ColumnInfos ); i++ ) + { + m_Workers.InsertColumn( i, g_ColumnInfos[i].pText, LVCFMT_LEFT, g_ColumnInfos[i].width, i ); + } + + + m_GraphControl.SubclassDlgItem( IDC_GRAPH_AREA, this ); + + + CString str; + + // Get all our startup info from the command line. + const char *pJobID = FindArg( "-JobID", NULL ); + const char *pDBName = FindArg( "-dbname", NULL ); + const char *pHostName = FindArg( "-hostname", NULL ); + const char *pUserName = FindArg( "-username", NULL ); + + if ( !pJobID ) + { + str.Format( "Missing a command line parameter (-JobID or -dbname or -hostname or -username)" ); + MessageBox( str, "Error", MB_OK ); + EndDialog( 1 ); + return FALSE; + } + + char hostName[512], dbName[512], userName[512]; + if ( !pDBName || !pHostName || !pUserName ) + { + char errString[512]; + + // If they don't specify the DB info, get it from where + const char *pFilename = "dbinfo_job_search.txt"; + FILE *fp = fopen( pFilename, "rt" ); + if ( !fp ) + { + Q_snprintf( errString, sizeof( errString ), "Can't open '%s' for database info.", pFilename ); + MessageBox( errString, "Error", MB_OK ); + EndDialog( 0 ); + return FALSE; + } + + if ( !ReadStringFromFile( fp, hostName, sizeof( hostName ) ) || + !ReadStringFromFile( fp, dbName, sizeof( dbName ) ) || + !ReadStringFromFile( fp, userName, sizeof( userName ) ) + ) + { + fclose( fp ); + Q_snprintf( errString, sizeof( errString ), "'%s' has invalid format.", pFilename ); + MessageBox( errString, "Error", MB_OK ); + EndDialog( 0 ); + return FALSE; + } + + pDBName = dbName; + pHostName = hostName; + pUserName = userName; + + fclose( fp ); + } + + m_JobID = atoi( pJobID ); + + // Get the mysql interface. + IMySQL *pSQL; + if ( !Sys_LoadInterface( "mysql_wrapper", MYSQL_WRAPPER_VERSION_NAME, &m_hMySQLDLL, (void**)&pSQL ) ) + return false; + + if ( !pSQL->InitMySQL( pDBName, pHostName, pUserName ) ) + { + pSQL->Release(); + str.Format( "Can't init MYSQL db (db = '%s', host = '%s', user = '%s')", pDBName, pHostName, pUserName ); + MessageBox( str, "Error", MB_OK ); + EndDialog( 0 ); + return FALSE; + } + + m_pSQL = CreateMySQLAsync( pSQL ); + if ( !m_pSQL ) + { + pSQL->Release(); + str.Format( "Can't create IMySQLAsync" ); + MessageBox( str, "Error", MB_OK ); + EndDialog( 0 ); + return FALSE; + } + + + memset( m_bQueriesInProgress, 0, sizeof( m_bQueriesInProgress ) ); + + + // (Init the idle processor so we can update text and graphs). + StartIdleProcessing( 100 ); + + // Fill in the command line control. + char cmdLine[2048]; + Q_snprintf( cmdLine, sizeof( cmdLine ), "vmpi_job_watch -JobID %s -hostname %s -dbname %s -username %s", + pJobID, pHostName, pDBName, pUserName ); + SetDlgItemText( IDC_COMMAND_LINE, cmdLine ); + + // Setup anchors. + m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_WORKERS_PANEL ), ANCHOR_LEFT, ANCHOR_TOP, ANCHOR_WIDTH_PERCENT, ANCHOR_HEIGHT_PERCENT ); + m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_WORKERS ), ANCHOR_LEFT, ANCHOR_TOP, ANCHOR_WIDTH_PERCENT, ANCHOR_HEIGHT_PERCENT ); + + m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_TEXT_OUTPUT_PANEL ), ANCHOR_LEFT, ANCHOR_HEIGHT_PERCENT, ANCHOR_WIDTH_PERCENT, ANCHOR_BOTTOM ); + m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_TEXTOUTPUT ), ANCHOR_LEFT, ANCHOR_HEIGHT_PERCENT, ANCHOR_WIDTH_PERCENT, ANCHOR_BOTTOM ); + + m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_GRAPHS_PANEL ), ANCHOR_WIDTH_PERCENT, ANCHOR_TOP, ANCHOR_RIGHT, ANCHOR_HEIGHT_PERCENT ); + m_AnchorMgr.AddAnchor( this, &m_GraphControl, ANCHOR_WIDTH_PERCENT, ANCHOR_TOP, ANCHOR_RIGHT, ANCHOR_HEIGHT_PERCENT ); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + + +CWorkerInfo* CJobWatchDlg::FindWorkerByID( unsigned long jobWorkerID ) +{ + int nIndex = -1; + while ( ( nIndex = m_Workers.GetNextItem( nIndex, LVNI_ALL ) ) != -1 ) + { + CWorkerInfo *pInfo = (CWorkerInfo*)m_Workers.GetItemData( nIndex ); + if ( pInfo->m_JobWorkerID == jobWorkerID ) + return pInfo; + } + + return NULL; +} + + +CWorkerInfo* CJobWatchDlg::FindWorkerByMachineName( const char *pMachineName ) +{ + int nIndex = -1; + while ( ( nIndex = m_Workers.GetNextItem( nIndex, LVNI_ALL ) ) != -1 ) + { + CWorkerInfo *pInfo = (CWorkerInfo*)m_Workers.GetItemData( nIndex ); + if ( Q_stricmp( pInfo->m_ComputerName, pMachineName ) == 0 ) + return pInfo; + } + + return NULL; +} + + +void CJobWatchDlg::SetWorkerListItemInt( int nIndex, int iColumn, int value ) +{ + char str[512]; + Q_snprintf( str, sizeof( str ), "%d", value ); + m_Workers.SetItemText( nIndex, iColumn, str ); +} + + +void CJobWatchDlg::UpdateWorkersList() +{ + int nIndex = -1; + while ( ( nIndex = m_Workers.GetNextItem( nIndex, LVNI_ALL ) ) != -1 ) + { + CWorkerInfo *pInfo = (CWorkerInfo*)m_Workers.GetItemData( nIndex ); + + char *pConnectedStr = pInfo->m_bConnected ? "yes" : "no"; + m_Workers.SetItemText( nIndex, COLUMN_CONNECTED, pConnectedStr ); + + SetWorkerListItemInt( nIndex, COLUMN_WORK_UNITS_DONE, pInfo->m_nWorkUnitsDone ); + + char timeStr[1024]; + FormatTimeString( pInfo->m_RunningTimeMS / 1000, timeStr, sizeof( timeStr ) ); + m_Workers.SetItemText( nIndex, COLUMN_RUNNING_TIME, timeStr ); + + // Current stage. + SetWorkerListItemInt( nIndex, COLUMN_WORK_UNITS_DONE, pInfo->m_nWorkUnitsDone ); + + m_Workers.SetItemText( nIndex, COLUMN_CURRENT_STAGE, pInfo->m_CurrentStage ); + + SetWorkerListItemInt( nIndex, COLUMN_THREAD0_WU, pInfo->m_ThreadWUs[0] ); + SetWorkerListItemInt( nIndex, COLUMN_THREAD1_WU, pInfo->m_ThreadWUs[1] ); + SetWorkerListItemInt( nIndex, COLUMN_THREAD2_WU, pInfo->m_ThreadWUs[2] ); + SetWorkerListItemInt( nIndex, COLUMN_THREAD3_WU, pInfo->m_ThreadWUs[3] ); + } + + ResortItems(); +} + + +bool CJobWatchDlg::GetCurJobWorkerID( unsigned long &id ) +{ + POSITION pos = m_Workers.GetFirstSelectedItemPosition(); + if ( !pos ) + return false; + + int index = m_Workers.GetNextSelectedItem( pos ); + CWorkerInfo *pInfo = (CWorkerInfo*)m_Workers.GetItemData( index ); + id = pInfo->m_JobWorkerID; + return true; +} + + +void CJobWatchDlg::OnSelChangeWorkers() +{ + // Clear the text output and invalidate any old queries for text. + int nLen = m_TextOutput.SendMessage( EM_GETLIMITTEXT, 0, 0 ); + m_TextOutput.SendMessage( EM_SETSEL, 0, nLen ); + m_TextOutput.SendMessage( EM_REPLACESEL, FALSE, (LPARAM)"" ); + + m_CurMessageIndex = 0; + m_CurWorkerTextToken++; + m_LastQueryTime = 0; // force a query. + + m_GraphControl.Clear(); + m_CurGraphTime = -1; +} + + +void CJobWatchDlg::ResortItems() +{ + m_Workers.SortItems( g_ColumnInfos[g_iSortColumn].sortFn, (LPARAM)this ); +} + + + +void CJobWatchDlg::OnIdle() +{ + // Issue any queries that we need to. + DWORD curTime = GetTickCount(); + if ( curTime - m_LastQueryTime >= 1000 ) + { + m_LastQueryTime = curTime; + char query[2048]; + + unsigned long jobWorkerID; + bool bJobWorkerIDValid = GetCurJobWorkerID( jobWorkerID ); + + if ( !m_bQueriesInProgress[QUERY_TEXT] && bJobWorkerIDValid ) + { + Q_snprintf( query, sizeof( query ), "select * from text_messages where JobWorkerID=%lu and MessageIndex >= %lu", jobWorkerID, m_CurMessageIndex ); + m_pSQL->Execute( query, (void*)(QUERY_TEXT | (m_CurWorkerTextToken << 16)) ); + m_bQueriesInProgress[QUERY_TEXT] = true; + } + + if ( !m_bQueriesInProgress[QUERY_GRAPH] && bJobWorkerIDValid ) + { + Q_snprintf( query, sizeof( query ), "select * from graph_entry where JobWorkerID=%lu", jobWorkerID ); + m_pSQL->Execute( query, (void*)QUERY_GRAPH ); + m_bQueriesInProgress[QUERY_GRAPH] = true; + } + + if ( !m_bQueriesInProgress[QUERY_WORKER_STATS] ) + { + Q_snprintf( query, sizeof( query ), "select JobWorkerID, WorkerState, NumWorkUnits, " + "RunningTimeMS, CurrentStage, Thread0WU, Thread1WU, Thread2WU, Thread3WU, IsMaster, MachineName " + " from job_worker_start where JobID=%lu", m_JobID ); + + m_pSQL->Execute( query, (void*)QUERY_WORKER_STATS ); + m_bQueriesInProgress[QUERY_WORKER_STATS] = true; + } + } + + + // Pickup query results. + CQueryResults results; + while ( m_pSQL->GetNextResults( results ) && results.m_pResults ) + { + int iQueryID = ((int)results.m_pUserData) & 0xFFFF; + int iExtraData = ((int)results.m_pUserData) >> 16; + + if ( results.m_pResults ) + { + if ( iQueryID == QUERY_TEXT ) + { + if ( iExtraData == m_CurWorkerTextToken ) + { + ProcessQueryResults_Text( results.m_pResults ); + } + } + else if ( iQueryID == QUERY_GRAPH ) + { + ProcessQueryResults_Graph( results.m_pResults ); + } + else if ( iQueryID == QUERY_WORKER_STATS ) + { + ProcessQueryResults_WorkerStats( results.m_pResults ); + } + + results.m_pResults->Release(); + } + + m_bQueriesInProgress[iQueryID] = false; + } +} + + +void CJobWatchDlg::ProcessQueryResults_WorkerStats( IMySQLRowSet *pSet ) +{ + bool bChange = false; + while ( pSet->NextRow() ) + { + int iColumn = 0; + int workerID = pSet->GetColumnValue_Int( iColumn++ ); + int workerState = pSet->GetColumnValue_Int( iColumn++ ); + int nWorkUnits = pSet->GetColumnValue_Int( iColumn++ ); + unsigned long runningTimeMS = pSet->GetColumnValue_Int( iColumn++ ); + const char *pCurrentStage = pSet->GetColumnValue_String( iColumn++ ); + int iThread0WU = pSet->GetColumnValue_Int( iColumn++ ); + int iThread1WU = pSet->GetColumnValue_Int( iColumn++ ); + int iThread2WU = pSet->GetColumnValue_Int( iColumn++ ); + int iThread3WU = pSet->GetColumnValue_Int( iColumn++ ); + int bIsMaster = pSet->GetColumnValue_Int( iColumn++ ); + const char *pMachineName = pSet->GetColumnValue_String( iColumn ); + + CWorkerInfo *pInfo = FindWorkerByID( workerID ); + if ( pInfo ) + { + if ( workerState != pInfo->m_bConnected || + nWorkUnits != pInfo->m_nWorkUnitsDone || + runningTimeMS != pInfo->m_RunningTimeMS || + stricmp( pCurrentStage, pInfo->m_CurrentStage ) != 0 || + iThread0WU != pInfo->m_ThreadWUs[0] || + iThread1WU != pInfo->m_ThreadWUs[1] || + iThread2WU != pInfo->m_ThreadWUs[2] || + iThread3WU != pInfo->m_ThreadWUs[3] + ) + { + bChange = true; + pInfo->m_bConnected = workerState; + pInfo->m_nWorkUnitsDone = nWorkUnits; + pInfo->m_RunningTimeMS = runningTimeMS; + pInfo->m_CurrentStage = pCurrentStage; + pInfo->m_ThreadWUs[0] = iThread0WU; + pInfo->m_ThreadWUs[1] = iThread1WU; + pInfo->m_ThreadWUs[2] = iThread2WU; + pInfo->m_ThreadWUs[3] = iThread3WU; + } + } + else + { + // Add a new entry. + CWorkerInfo *pInfo = new CWorkerInfo; + pInfo->m_ComputerName = pMachineName; + pInfo->m_bConnected = false; + pInfo->m_nWorkUnitsDone = 0; + pInfo->m_RunningTimeMS = 0; + pInfo->m_JobWorkerID = workerID; + + int index; + if ( bIsMaster ) + { + char tempStr[512]; + Q_snprintf( tempStr, sizeof( tempStr ), "%s [master]", (const char*)pInfo->m_ComputerName ); + index = m_Workers.InsertItem( COLUMN_COMPUTER_NAME, tempStr, NULL ); + } + else + { + index = m_Workers.InsertItem( COLUMN_COMPUTER_NAME, pInfo->m_ComputerName, NULL ); + } + + m_Workers.SetItemData( index, (DWORD)pInfo ); + bChange = true; + } + } + + if ( bChange ) + { + UpdateWorkersList(); + } +} + + +void CJobWatchDlg::ProcessQueryResults_Text( IMySQLRowSet *pSet ) +{ + CUtlVector<char> text; + + while ( pSet->NextRow() ) + { + const char *pTextStr = pSet->GetColumnValue( "text" ).String(); + int len = strlen( pTextStr ); + text.AddMultipleToTail( len, pTextStr ); + + m_CurMessageIndex = pSet->GetColumnValue( "MessageIndex" ).Int32() + 1; + } + + text.AddToTail( 0 ); + FormatAndSendToEditControl( m_TextOutput.GetSafeHwnd(), text.Base() ); +} + + +void CJobWatchDlg::ProcessQueryResults_Graph( IMySQLRowSet *pSet ) +{ + int iMSTime = pSet->GetColumnIndex( "MSSinceJobStart" ); + int iBytesSent = pSet->GetColumnIndex( "BytesSent" ); + int iBytesReceived = pSet->GetColumnIndex( "BytesReceived" ); + + // See if there's anything new. + CUtlVector<CGraphEntry> entries; + + int highest = m_CurGraphTime; + while ( pSet->NextRow() ) + { + CGraphEntry entry; + entry.m_msTime = pSet->GetColumnValue( iMSTime ).Int32(); + entry.m_nBytesSent = pSet->GetColumnValue( iBytesSent ).Int32(); + entry.m_nBytesReceived = pSet->GetColumnValue( iBytesReceived ).Int32(); + entries.AddToTail( entry ); + + highest = max( highest, entry.m_msTime ); + } + + if ( highest > m_CurGraphTime ) + { + m_CurGraphTime = highest; + + m_GraphControl.Clear(); + m_GraphControl.Fill( entries ); + } +} + + +void CJobWatchDlg::OnSize(UINT nType, int cx, int cy) +{ + CIdleDialog::OnSize(nType, cx, cy); + + m_AnchorMgr.UpdateAnchors( this ); +} + + +BOOL CJobWatchDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) +{ + NMHDR *pHdr = (NMHDR*)lParam; + if ( pHdr->idFrom == IDC_WORKERS ) + { + if ( pHdr->code == LVN_COLUMNCLICK ) + { + LPNMLISTVIEW pListView = (LPNMLISTVIEW)lParam; + + // Now sort by this column. + g_iSortColumn = max( 0, min( pListView->iSubItem, (int)ARRAYSIZE( g_ColumnInfos ) - 1 ) ); + ResortItems(); + } + } + + return CIdleDialog::OnNotify(wParam, lParam, pResult); +} + +void CJobWatchDlg::OnOdstatechangedWorkers(NMHDR* pNMHDR, LRESULT* pResult) +{ + NMLVODSTATECHANGE* pStateChanged = (NMLVODSTATECHANGE*)pNMHDR; + + if ( !( pStateChanged->uOldState & LVIS_SELECTED ) && ( pStateChanged->uNewState & LVIS_SELECTED ) ) + { + OnSelChangeWorkers(); + } + + *pResult = 0; +} + +void CJobWatchDlg::OnItemchangedWorkers(NMHDR* pNMHDR, LRESULT* pResult) +{ + NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; + + if ( !( pNMListView->uOldState & LVIS_SELECTED ) && ( pNMListView->uNewState & LVIS_SELECTED ) ) + { + OnSelChangeWorkers(); + } + + *pResult = 0; +} diff --git a/utils/vmpi/vmpi_job_watch/JobWatchDlg.h b/utils/vmpi/vmpi_job_watch/JobWatchDlg.h new file mode 100644 index 0000000..6bec50b --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/JobWatchDlg.h @@ -0,0 +1,134 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#if !defined(AFX_JOBWATCHDLG_H__761BDEEF_D549_4F10_817C_1C1FAF9FCA47__INCLUDED_) +#define AFX_JOBWATCHDLG_H__761BDEEF_D549_4F10_817C_1C1FAF9FCA47__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// JobWatchDlg.h : header file +// + + +#include "idle_dialog.h" +#include "resource.h" +#include "utlvector.h" +#include "imysqlwrapper.h" +#include "GraphControl.h" +#include "window_anchor_mgr.h" +#include "mysql_async.h" + + +class CWorkerInfo +{ +public: + CWorkerInfo() + { + m_bConnected = false; + m_nWorkUnitsDone = 0; + m_JobWorkerID = 0xFFFFFFFF; + m_RunningTimeMS = 0; + m_ThreadWUs[0] = m_ThreadWUs[1] = m_ThreadWUs[2] = m_ThreadWUs[3] = -1; + } + + CString m_ComputerName; + int m_bConnected; + int m_nWorkUnitsDone; + unsigned long m_JobWorkerID; + unsigned long m_RunningTimeMS; + CString m_CurrentStage; + int m_ThreadWUs[4]; +}; + + + +///////////////////////////////////////////////////////////////////////////// +// CJobWatchDlg dialog + +class CJobWatchDlg : public CIdleDialog +{ +// Construction +public: + CJobWatchDlg( CWnd* pParent = NULL); // standard constructor + virtual ~CJobWatchDlg(); + +// Dialog Data + //{{AFX_DATA(CJobWatchDlg) + enum { IDD = IDD_JOB_WATCH }; + CListCtrl m_Workers; + CEdit m_TextOutput; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CJobWatchDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult); + //}}AFX_VIRTUAL + +// Implementation +protected: + + virtual void OnIdle(); + void RefreshWorkerStats(); + CWorkerInfo* FindWorkerByID( unsigned long jobWorkerID ); + CWorkerInfo* FindWorkerByMachineName( const char *pMachineName ); + void SetWorkerListItemInt( int nIndex, int iColumn, int value ); + void UpdateWorkersList(); + void ResortItems(); + + // Query IDs. + enum + { + QUERY_TEXT=0, + QUERY_GRAPH, + QUERY_WORKER_STATS, + NUM_QUERIES + }; + + void ProcessQueryResults_Graph( IMySQLRowSet *pSet ); + void ProcessQueryResults_Text( IMySQLRowSet *pSet ); + void ProcessQueryResults_WorkerStats( IMySQLRowSet *pSet ); + + bool m_bQueriesInProgress[NUM_QUERIES]; + + // This is our connection to the mysql database. + IMySQLAsync *m_pSQL; + CSysModule *m_hMySQLDLL; + + CWindowAnchorMgr m_AnchorMgr; + + + bool GetCurJobWorkerID( unsigned long &id ); + + CGraphControl m_GraphControl; + unsigned long m_JobID; + int m_CurGraphTime; + + int m_CurMessageIndex; + int m_CurWorkerTextToken; // used to let it ignore old text in the thread's queue + + DWORD m_LastQueryTime; // Last time we made a query. + + // Generated message map functions + //{{AFX_MSG(CJobWatchDlg) + virtual BOOL OnInitDialog(); + afx_msg void OnSelChangeWorkers(); + afx_msg void OnSize(UINT nType, int cx, int cy); + afx_msg void OnOdstatechangedWorkers(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnItemchangedWorkers(NMHDR* pNMHDR, LRESULT* pResult); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_JOBWATCHDLG_H__761BDEEF_D549_4F10_817C_1C1FAF9FCA47__INCLUDED_) diff --git a/utils/vmpi/vmpi_job_watch/StdAfx.cpp b/utils/vmpi/vmpi_job_watch/StdAfx.cpp new file mode 100644 index 0000000..86ac49b --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/StdAfx.cpp @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// stdafx.cpp : source file that includes just the standard includes +// vmpi_browser_job_watch.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + + diff --git a/utils/vmpi/vmpi_job_watch/StdAfx.h b/utils/vmpi/vmpi_job_watch/StdAfx.h new file mode 100644 index 0000000..3c1d23e --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/StdAfx.h @@ -0,0 +1,36 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__E8FBDA6A_CE57_4416_8329_90155CD6CEC3__INCLUDED_) +#define AFX_STDAFX_H__E8FBDA6A_CE57_4416_8329_90155CD6CEC3__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include "tier0/basetypes.h" + +#include <afxwin.h> // MFC core and standard components +#include <afxext.h> // MFC extensions +#include <afxdisp.h> // MFC Automation classes +#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include <afxcmn.h> // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__E8FBDA6A_CE57_4416_8329_90155CD6CEC3__INCLUDED_) diff --git a/utils/vmpi/vmpi_job_watch/res/vmpi_browser_job_watch.ico b/utils/vmpi/vmpi_job_watch/res/vmpi_browser_job_watch.ico Binary files differnew file mode 100644 index 0000000..7eef0bc --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/res/vmpi_browser_job_watch.ico diff --git a/utils/vmpi/vmpi_job_watch/res/vmpi_browser_job_watch.rc2 b/utils/vmpi/vmpi_job_watch/res/vmpi_browser_job_watch.rc2 new file mode 100644 index 0000000..6e93fd0 --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/res/vmpi_browser_job_watch.rc2 @@ -0,0 +1,13 @@ +// +// VMPI_BROWSER_JOB_WATCH.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/utils/vmpi/vmpi_job_watch/resource.h b/utils/vmpi/vmpi_job_watch/resource.h new file mode 100644 index 0000000..c81a23e --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/resource.h @@ -0,0 +1,32 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by vmpi_browser_job_watch.rc +// +#define IDD_VMPI_BROWSER_JOB_WATCH_DIALOG 102 +#define IDR_MAINFRAME 128 +#define IDD_JOB_WATCH 135 +#define IDC_WORKERS 1001 +#define IDC_GRAPH_AREA 1002 +#define IDC_TEXTOUTPUT 1005 +#define IDC_WORKERS_PANEL 1006 +#define IDC_TEXT_OUTPUT_PANEL 1007 +#define IDC_GRAPHS_PANEL 1008 +#define IDC_COMMAND_LINE 1009 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1010 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.cpp b/utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.cpp new file mode 100644 index 0000000..efdf515 --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.cpp @@ -0,0 +1,75 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// vmpi_browser_job_watch.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "vmpi_browser_job_watch.h" +#include "JobWatchDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CVMPIBrowserJobWatchApp + +BEGIN_MESSAGE_MAP(CVMPIBrowserJobWatchApp, CWinApp) + //{{AFX_MSG_MAP(CVMPIBrowserJobWatchApp) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG + ON_COMMAND(ID_HELP, CWinApp::OnHelp) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CVMPIBrowserJobWatchApp construction + +CVMPIBrowserJobWatchApp::CVMPIBrowserJobWatchApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CVMPIBrowserJobWatchApp object + +CVMPIBrowserJobWatchApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CVMPIBrowserJobWatchApp initialization + +BOOL CVMPIBrowserJobWatchApp::InitInstance() +{ + AfxEnableControlContainer(); + + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + + CJobWatchDlg dlg; + m_pMainWnd = &dlg; + int nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO: Place code here to handle when the dialog is + // dismissed with OK + } + else if (nResponse == IDCANCEL) + { + // TODO: Place code here to handle when the dialog is + // dismissed with Cancel + } + + // Since the dialog has been closed, return FALSE so that we exit the + // application, rather than start the application's message pump. + return FALSE; +} diff --git a/utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.h b/utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.h new file mode 100644 index 0000000..bd55384 --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.h @@ -0,0 +1,56 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// vmpi_browser_job_watch.h : main header file for the VMPI_BROWSER_JOB_WATCH application +// + +#if !defined(AFX_VMPI_BROWSER_JOB_WATCH_H__1DF22047_F615_4799_913A_222E3701BE5E__INCLUDED_) +#define AFX_VMPI_BROWSER_JOB_WATCH_H__1DF22047_F615_4799_913A_222E3701BE5E__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CVMPIBrowserJobWatchApp: +// See vmpi_browser_job_watch.cpp for the implementation of this class +// + +class CVMPIBrowserJobWatchApp : public CWinApp +{ +public: + CVMPIBrowserJobWatchApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CVMPIBrowserJobWatchApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CVMPIBrowserJobWatchApp) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_VMPI_BROWSER_JOB_WATCH_H__1DF22047_F615_4799_913A_222E3701BE5E__INCLUDED_) diff --git a/utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.rc b/utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.rc new file mode 100644 index 0000000..56c3fc7 --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/vmpi_browser_job_watch.rc @@ -0,0 +1,183 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif //_WIN32\r\n" + "#include ""res\\vmpi_browser_job_watch.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON DISCARDABLE "res\\vmpi_browser_job_watch.ico" + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "\0" + VALUE "FileDescription", "vmpi_browser_job_watch MFC Application\0" + VALUE "FileVersion", "1, 0, 0, 1\0" + VALUE "InternalName", "vmpi_browser_job_watch\0" + VALUE "LegalCopyright", "Copyright (C) 2003\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "vmpi_browser_job_watch.EXE\0" + VALUE "ProductName", "vmpi_browser_job_watch Application\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_JOB_WATCH DIALOG DISCARDABLE 0, 0, 592, 366 +STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU | WS_THICKFRAME +CAPTION "Job Watch" +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_TEXTOUTPUT,13,177,291,179,ES_MULTILINE | ES_READONLY | + WS_VSCROLL | WS_HSCROLL + GROUPBOX "Workers",IDC_WORKERS_PANEL,7,32,578,132 + GROUPBOX "Text Output",IDC_TEXT_OUTPUT_PANEL,7,164,303,195 + GROUPBOX "Graphs",IDC_GRAPHS_PANEL,318,164,267,195 + CONTROL "",IDC_GRAPH_AREA,"Static",SS_BLACKFRAME,323,176,255,179 + CONTROL "List1",IDC_WORKERS,"SysListView32",LVS_REPORT | + LVS_SORTASCENDING | WS_BORDER | WS_TABSTOP,13,41,564,118 + LTEXT "Command Line:",IDC_STATIC,7,9,50,8 + EDITTEXT IDC_COMMAND_LINE,60,7,364,14,ES_AUTOHSCROLL | + ES_READONLY +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_JOB_WATCH, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 585 + TOPMARGIN, 7 + BOTTOMMARGIN, 359 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 +#include "res\vmpi_browser_job_watch.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/utils/vmpi/vmpi_job_watch/vmpi_job_watch.vpc b/utils/vmpi/vmpi_job_watch/vmpi_job_watch.vpc new file mode 100644 index 0000000..9d8f372 --- /dev/null +++ b/utils/vmpi/vmpi_job_watch/vmpi_job_watch.vpc @@ -0,0 +1,80 @@ +//----------------------------------------------------------------------------- +// vmpi_job_watch.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\..\.." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" +$Macro OUTBINNAME "vmpi_job_watch" + +$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,.\,..\,..\..\common,..\mysql\include" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;WINVER=0x501;NO_WARN_MBCS_MFC_DEPRECATION" + $EnableC++Exceptions "Yes (/EHsc)" + } +} + +$Configuration "Debug" +{ + $Linker + { + // Deprecated MBCS MFC libraries for VS 2013 (nafxcw.lib and nafxcwd.lib) can be downloaded from http://go.microsoft.com/?linkid=9832071 + $AdditionalDependencies "$BASE nafxcwd.lib" + $IgnoreSpecificLibrary "nafxcw.lib libcmt.lib" + } +} + +$Configuration "Release" +{ + $Linker + { + // Deprecated MBCS MFC libraries for VS 2013 (nafxcw.lib and nafxcwd.lib) can be downloaded from http://go.microsoft.com/?linkid=9832071 + $AdditionalDependencies "$BASE nafxcw.lib libcmt.lib" + $IgnoreSpecificLibrary "nafxcwd.lib libcmtd.lib" + } +} + +$Project "vmpi_job_watch" +{ + $Folder "Source Files" + { + -$File "$SRCDIR\public\tier0\memoverride.cpp" + + $File "..\..\common\consolewnd.cpp" + $File "GraphControl.cpp" + $File "..\idle_dialog.cpp" + $File "JobWatchDlg.cpp" + $File "..\mysql_async.cpp" + $File "..\vmpi_browser_helpers.cpp" + $File "vmpi_browser_job_watch.cpp" + $File "vmpi_browser_job_watch.rc" + $File "..\win_idle.cpp" + $File "..\window_anchor_mgr.cpp" + } + + $Folder "Header Files" + { + $File "..\..\common\consolewnd.h" + $File "GraphControl.h" + $File "..\idle_dialog.h" + $File "JobWatchDlg.h" + $File "..\mysql_async.h" + $File "..\mysql_wrapper.h" + $File "Resource.h" + $File "StdAfx.h" + $File "vmpi_browser_job_watch.h" + $File "..\win_idle.h" + } + + $Folder "Resource Files" + { + $File "res\vmpi_browser_job_watch.ico" + $File "res\vmpi_browser_job_watch.rc2" + } +} |