You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
648 lines
17 KiB
648 lines
17 KiB
//========= 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; |
|
}
|
|
|