// PerforceClientService.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "PerforceClientService.h" #include "PerforceClientServiceDlg.h" #include "FileSystemEvent.h" #include "MyClientUser.h" #include "DirectoryList.h" #include <afxmt.h> #include <assert.h> #include <stdio.h> #include <deque> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif namespace CPerforceClientServiceAppNamespace { typedef std::deque<FileSystemEvent *>(FileSystemEvents); bool shouldUpdatePerforce(char const * fileName) { char buffer[MAX_PATH]; { char * b = buffer; while (*fileName) { *b = static_cast<char>(tolower(*fileName)); ++b; ++fileName; } *b = '\0'; fileName = buffer; } // see if the file ends in .tmp char const * dot = strrchr(fileName, '.'); if (dot && strcmp(dot, ".tmp") == 0) return false; // see if the file contains \compile\, assuming it was created by msvc if (strstr(fileName, "\\compile\\")) return false; return true; } HANDLE ms_semaphore; CRITICAL_SECTION ms_criticalSection; FileSystemEvents ms_fileSystemEvents; } using namespace CPerforceClientServiceAppNamespace; char const * CPerforceClientServiceApp::getRegistryKey() { return "Software\\JeffGrills\\PerforceClientService"; } ///////////////////////////////////////////////////////////////////////////// // CPerforceClientServiceApp BEGIN_MESSAGE_MAP(CPerforceClientServiceApp, CWinApp) //{{AFX_MSG_MAP(CPerforceClientServiceApp) // 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() ///////////////////////////////////////////////////////////////////////////// // CPerforceClientServiceApp construction CPerforceClientServiceApp::CPerforceClientServiceApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////////// // The one and only CPerforceClientServiceApp object CPerforceClientServiceApp theApp; ///////////////////////////////////////////////////////////////////////////// // CPerforceClientServiceApp initialization BOOL CPerforceClientServiceApp::InitInstance() { // 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. #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #endif if (!MyClientUser::install()) return FALSE; InitializeCriticalSection(&ms_criticalSection); ms_semaphore = CreateSemaphore(NULL, 0, INT_MAX, NULL); assert(ms_semaphore != NULL); CWinThread * thread = AfxBeginThread(threadProc, NULL); CPerforceClientServiceDlg 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 } DirectoryList::remove(); // Signal the semaphore again to let the thread die ReleaseSemaphore(ms_semaphore, 1, NULL); WaitForSingleObject(thread->m_hThread, INFINITE); // Close connection MyClientUser::remove(); // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; } void CPerforceClientServiceApp::enqueueFileSystemEvent(FileSystemEvent * event) { EnterCriticalSection(&ms_criticalSection); ms_fileSystemEvents.push_back(event); LeaveCriticalSection(&ms_criticalSection); ReleaseSemaphore(ms_semaphore, 1, NULL); } UINT CPerforceClientServiceApp::threadProc(LPVOID) { for (;;) { DWORD result = WaitForSingleObject(ms_semaphore, INFINITE); assert(result == WAIT_OBJECT_0); FileSystemEvent * event = NULL; EnterCriticalSection(&ms_criticalSection); if (!ms_fileSystemEvents.empty()) { event = ms_fileSystemEvents.front(); ms_fileSystemEvents.pop_front(); } LeaveCriticalSection(&ms_criticalSection); if (!event) return 0; switch (event->m_type) { case FileSystemEvent::T_add: if (shouldUpdatePerforce(event->m_path)) { MyClientUser myClientUser(MyClientUser::FA_add, event->m_path); myClientUser.UpdatePerforce(); } break; case FileSystemEvent::T_delete: if (shouldUpdatePerforce(event->m_path)) { MyClientUser myClientUser(MyClientUser::FA_delete, event->m_path); myClientUser.UpdatePerforce(); } break; case FileSystemEvent::T_rename: if (shouldUpdatePerforce(event->m_path)) { MyClientUser myClientUser(MyClientUser::FA_delete, event->m_path); myClientUser.UpdatePerforce(); } if (shouldUpdatePerforce(event->m_newPath)) { MyClientUser myClientUser(MyClientUser::FA_add, event->m_newPath); myClientUser.UpdatePerforce(); } break; case FileSystemEvent::T_modify: if (shouldUpdatePerforce(event->m_path)) { MyClientUser myClientUser(MyClientUser::FA_modify, event->m_path); myClientUser.UpdatePerforce(); } break; } delete event; } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#5 | 7201 | Jeff Grills | Upgrade to VS2005 and the 2008.2 p4api | ||
#4 | 4963 | Jeff Grills |
Major clean up and code reorganization. Add new dialog to control the directories that are watched. Persist the watched directories in the windows registry. Restore the watched directories when the application is run again. Handle login correctly. Change the way error messages are examined to make them significantly more robust. Issue an "info" command at startup to make sure we can communicate with the server and get logged in. Change the icon to the standard P4 icon. Allow the dialog to be minimized to the systray. Clicking on the systray icon will show the dialog again. |
||
#3 | 4962 | Jeff Grills |
Remove comments that indicated current test status. Hook up renaming so that syncing works (but is ugly) |
||
#2 | 4961 | Jeff Grills |
Add the p4 headers to the DSP so that WorkspaceWhiz can open them, Rework the perforce update engine to be significantly more simple. Add MyFileSys class that prevents any disk updates when doing reverts. |
||
#1 | 4896 | Jeff Grills |
First drop of the PerforceClientService. This version is only barely functional, supporting adds, edits, and deletes. It does not handle multiple operations on the same file gracefully. |