[Project64] Move Watch dir code back to rom browser

This commit is contained in:
zilmar 2016-04-16 06:58:31 +10:00
parent 4b70b1c941
commit 98230eb48a
4 changed files with 197 additions and 204 deletions

View File

@ -139,13 +139,23 @@ private:
void RomList_PopupMenu(uint32_t pnmh);
void RomList_SortList(void);
bool RomDirNeedsRefresh(void); // Called from watch thread
void RomDirChanged(void);
bool GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const std::string & Directory, bool InWatchThread);
void WatchThreadStart(void);
void WatchThreadStop(void);
static void WatchRomDirChanged(CRomBrowser * _this);
static void AddField(ROMBROWSER_FIELDS_LIST & Fields, const char * Name, int32_t Pos, int32_t ID, int32_t Width, LanguageStringID LangID, bool UseDefault);
//Callback
static int CALLBACK SelectRomDirCallBack(HWND hwnd, uint32_t uMsg, uint32_t lp, uint32_t lpData);
static int CALLBACK RomList_CompareItems(uint32_t lParam1, uint32_t lParam2, uint32_t lParamSort);
//Watch Directory Changed function
HANDLE m_WatchThread, m_WatchStopEvent;
DWORD m_WatchThreadID;
HWND & m_MainWindow;
HWND & m_StatusWindow;
@ -159,4 +169,5 @@ private:
static std::wstring m_UnknownGoodName;
HBRUSH_MAP m_Brushes;
std::string m_LastRom;
stdstr m_WatchRomDir;
};

View File

@ -20,7 +20,10 @@ CRomBrowser::CRomBrowser(HWND & MainWindow, HWND & StatusWindow) :
m_MainWindow(MainWindow),
m_StatusWindow(StatusWindow),
m_ShowingRomBrowser(false),
m_AllowSelectionLastRom(true)
m_AllowSelectionLastRom(true),
m_WatchThreadID(0),
m_WatchThread(NULL),
m_WatchStopEvent(NULL)
{
m_hRomList = 0;
m_Visible = false;
@ -31,6 +34,7 @@ CRomBrowser::CRomBrowser(HWND & MainWindow, HWND & StatusWindow) :
CRomBrowser::~CRomBrowser(void)
{
WatchThreadStop();
DeallocateBrushs();
}
@ -285,6 +289,15 @@ void CRomBrowser::RomListReset(void)
Sleep(100);
WriteTrace(TraceUserInterface, TraceDebug, "3");
m_LastRom = UISettingsLoadStringIndex(File_RecentGameFileIndex, 0);
if (m_WatchRomDir != g_Settings->LoadStringVal(RomList_GameDir))
{
WriteTrace(TraceUserInterface, TraceDebug, "4");
WatchThreadStop();
WriteTrace(TraceUserInterface, TraceDebug, "5");
WatchThreadStart();
WriteTrace(TraceUserInterface, TraceDebug, "6");
}
}
void CRomBrowser::CreateRomListControl(void)
@ -1084,3 +1097,171 @@ void CRomBrowser::HideRomList(void)
PostMessage(m_MainWindow, WM_MAKE_FOCUS, 0, 0);
}
bool CRomBrowser::RomDirNeedsRefresh(void)
{
bool InWatchThread = (m_WatchThreadID == GetCurrentThreadId());
//Get Old MD5 of file names
stdstr FileName = g_Settings->LoadStringVal(RomList_RomListCache);
HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
//if file does not exist then refresh the data
return true;
}
DWORD dwRead;
unsigned char CurrentFileMD5[16];
ReadFile(hFile, &CurrentFileMD5, sizeof(CurrentFileMD5), &dwRead, NULL);
CloseHandle(hFile);
//Get Current MD5 of file names
strlist FileNames;
if (!GetRomFileNames(FileNames, CPath(g_Settings->LoadStringVal(RomList_GameDir)), stdstr(""), InWatchThread))
{
return false;
}
FileNames.sort();
MD5 NewMd5 = RomListHash(FileNames);
if (memcmp(NewMd5.raw_digest(), CurrentFileMD5, sizeof(CurrentFileMD5)) != 0)
{
return true;
}
return false;
}
void CRomBrowser::WatchRomDirChanged(CRomBrowser * _this)
{
try
{
WriteTrace(TraceUserInterface, TraceDebug, "1");
_this->m_WatchRomDir = g_Settings->LoadStringVal(RomList_GameDir);
WriteTrace(TraceUserInterface, TraceDebug, "2");
if (_this->RomDirNeedsRefresh())
{
WriteTrace(TraceUserInterface, TraceDebug, "2a");
_this->RomDirChanged();
}
WriteTrace(TraceUserInterface, TraceDebug, "3");
HANDLE hChange[] =
{
_this->m_WatchStopEvent,
FindFirstChangeNotification(_this->m_WatchRomDir.c_str(), g_Settings->LoadBool(RomList_GameDirRecursive), FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE),
};
WriteTrace(TraceUserInterface, TraceDebug, "4");
for (;;)
{
WriteTrace(TraceUserInterface, TraceDebug, "5");
if (WaitForMultipleObjects(sizeof(hChange) / sizeof(hChange[0]), hChange, false, INFINITE) == WAIT_OBJECT_0)
{
WriteTrace(TraceUserInterface, TraceDebug, "5a");
FindCloseChangeNotification(hChange[1]);
return;
}
WriteTrace(TraceUserInterface, TraceDebug, "5b");
if (_this->RomDirNeedsRefresh())
{
_this->RomDirChanged();
}
WriteTrace(TraceUserInterface, TraceDebug, "5c");
if (!FindNextChangeNotification(hChange[1]))
{
FindCloseChangeNotification(hChange[1]);
return;
}
WriteTrace(TraceUserInterface, TraceDebug, "5d");
}
}
catch (...)
{
WriteTrace(TraceUserInterface, TraceError, __FUNCTION__ ": Unhandled Exception");
}
}
void CRomBrowser::WatchThreadStart(void)
{
WriteTrace(TraceUserInterface, TraceDebug, "1");
WatchThreadStop();
WriteTrace(TraceUserInterface, TraceDebug, "2");
if (m_WatchStopEvent == NULL)
{
m_WatchStopEvent = CreateEvent(NULL, true, false, NULL);
}
WriteTrace(TraceUserInterface, TraceDebug, "3");
m_WatchThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WatchRomDirChanged, this, 0, &m_WatchThreadID);
WriteTrace(TraceUserInterface, TraceDebug, "4");
}
void CRomBrowser::WatchThreadStop(void)
{
if (m_WatchThread == NULL)
{
return;
}
WriteTrace(TraceUserInterface, TraceDebug, "1");
SetEvent(m_WatchStopEvent);
DWORD ExitCode = 0;
for (int32_t count = 0; count < 20; count++)
{
WriteTrace(TraceUserInterface, TraceDebug, "2");
GetExitCodeThread(m_WatchThread, &ExitCode);
if (ExitCode != STILL_ACTIVE)
{
break;
}
Sleep(200);
}
WriteTrace(TraceUserInterface, TraceDebug, "3");
if (ExitCode == STILL_ACTIVE)
{
WriteTrace(TraceUserInterface, TraceDebug, "3a");
TerminateThread(m_WatchThread, 0);
}
WriteTrace(TraceUserInterface, TraceDebug, "4");
CloseHandle(m_WatchThread);
CloseHandle(m_WatchStopEvent);
m_WatchStopEvent = NULL;
m_WatchThread = NULL;
m_WatchThreadID = 0;
WriteTrace(TraceUserInterface, TraceDebug, "5");
}
bool CRomBrowser::GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const std::string & Directory, bool InWatchThread)
{
if (!BaseDirectory.DirectoryExists())
{
return false;
}
CPath SearchPath(BaseDirectory, "*.*");
SearchPath.AppendDirectory(Directory.c_str());
if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES))
{
return false;
}
do
{
if (InWatchThread && WaitForSingleObject(m_WatchStopEvent, 0) != WAIT_TIMEOUT)
{
return false;
}
if (SearchPath.IsDirectory())
{
if (g_Settings->LoadBool(RomList_GameDirRecursive))
{
CPath CurrentDir(Directory);
CurrentDir.AppendDirectory(SearchPath.GetLastDirectory().c_str());
GetRomFileNames(FileList, BaseDirectory, CurrentDir, InWatchThread);
}
}
else
{
AddFileNameToList(FileList, Directory, SearchPath);
}
} while (SearchPath.FindNext());
return true;
}

View File

@ -34,10 +34,7 @@ CRomList::CRomList() :
#ifdef _WIN32
m_ZipIniFile(NULL),
#endif
m_RomIniFile(NULL),
m_WatchThreadID(0),
m_WatchThread(NULL),
m_WatchStopEvent(NULL)
m_RomIniFile(NULL)
{
if (g_Settings)
{
@ -52,7 +49,6 @@ CRomList::CRomList() :
CRomList::~CRomList()
{
WatchThreadStop();
m_StopRefresh = true;
if (m_NotesIniFile)
{
@ -101,15 +97,6 @@ void CRomList::RefreshRomListThread(void)
RomListReset();
m_RomInfo.clear();
if (m_WatchRomDir != g_Settings->LoadStringVal(RomList_GameDir))
{
WriteTrace(TraceUserInterface, TraceDebug, "4");
WatchThreadStop();
WriteTrace(TraceUserInterface, TraceDebug, "5");
WatchThreadStart();
WriteTrace(TraceUserInterface, TraceDebug, "6");
}
WriteTrace(TraceUserInterface, TraceDebug, "7");
stdstr RomDir = g_Settings->LoadStringVal(RomList_GameDir);
stdstr LastRom = UISettingsLoadStringIndex(File_RecentGameFileIndex, 0);
@ -182,12 +169,6 @@ void CRomList::FillRomList(strlist & FileList, const CPath & BaseDirectory, cons
continue;
}
WriteTrace(TraceRomList, TraceVerbose, "File has matching extension: \"%s\"", ROM_extensions[i]);
if (FileList.size() <= 3000)
{
stdstr file = stdstr(Directory + SearchPath.GetNameExtension()).ToLower();
WriteTrace(TraceRomList, TraceVerbose, "Adding: \"%s\" to FileList", file.c_str());
FileList.push_back(file);
}
if (Extension != "7z")
{
AddRomToList(SearchPath);
@ -637,137 +618,6 @@ void CRomList::SaveRomList(strlist & FileList)
file.Close();
}
void CRomList::WatchRomDirChanged(CRomList * _this)
{
try
{
WriteTrace(TraceUserInterface, TraceDebug, "1");
_this->m_WatchRomDir = g_Settings->LoadStringVal(RomList_GameDir);
WriteTrace(TraceUserInterface, TraceDebug, "2");
if (_this->RomDirNeedsRefresh())
{
WriteTrace(TraceUserInterface, TraceDebug, "2a");
_this->RomDirChanged();
}
WriteTrace(TraceUserInterface, TraceDebug, "3");
HANDLE hChange[] =
{
_this->m_WatchStopEvent,
FindFirstChangeNotification(_this->m_WatchRomDir.c_str(), g_Settings->LoadBool(RomList_GameDirRecursive), FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE),
};
WriteTrace(TraceUserInterface, TraceDebug, "4");
for (;;)
{
WriteTrace(TraceUserInterface, TraceDebug, "5");
if (WaitForMultipleObjects(sizeof(hChange) / sizeof(hChange[0]), hChange, false, INFINITE) == WAIT_OBJECT_0)
{
WriteTrace(TraceUserInterface, TraceDebug, "5a");
FindCloseChangeNotification(hChange[1]);
return;
}
WriteTrace(TraceUserInterface, TraceDebug, "5b");
if (_this->RomDirNeedsRefresh())
{
_this->RomDirChanged();
}
WriteTrace(TraceUserInterface, TraceDebug, "5c");
if (!FindNextChangeNotification(hChange[1]))
{
FindCloseChangeNotification(hChange[1]);
return;
}
WriteTrace(TraceUserInterface, TraceDebug, "5d");
}
}
catch (...)
{
WriteTrace(TraceUserInterface, TraceError, __FUNCTION__ ": Unhandled Exception");
}
}
bool CRomList::RomDirNeedsRefresh(void)
{
bool InWatchThread = (m_WatchThreadID == GetCurrentThreadId());
//Get Old MD5 of file names
stdstr FileName = g_Settings->LoadStringVal(RomList_RomListCache);
HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
//if file does not exist then refresh the data
return true;
}
DWORD dwRead;
unsigned char CurrentFileMD5[16];
ReadFile(hFile, &CurrentFileMD5, sizeof(CurrentFileMD5), &dwRead, NULL);
CloseHandle(hFile);
//Get Current MD5 of file names
strlist FileNames;
if (!GetRomFileNames(FileNames, CPath(g_Settings->LoadStringVal(RomList_GameDir)), stdstr(""), InWatchThread))
{
return false;
}
FileNames.sort();
MD5 NewMd5 = RomListHash(FileNames);
if (memcmp(NewMd5.raw_digest(), CurrentFileMD5, sizeof(CurrentFileMD5)) != 0)
{
return true;
}
return false;
}
void CRomList::WatchThreadStart(void)
{
WriteTrace(TraceUserInterface, TraceDebug, "1");
WatchThreadStop();
WriteTrace(TraceUserInterface, TraceDebug, "2");
if (m_WatchStopEvent == NULL)
{
m_WatchStopEvent = CreateEvent(NULL, true, false, NULL);
}
WriteTrace(TraceUserInterface, TraceDebug, "3");
m_WatchThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WatchRomDirChanged, this, 0, &m_WatchThreadID);
WriteTrace(TraceUserInterface, TraceDebug, "4");
}
void CRomList::WatchThreadStop(void)
{
if (m_WatchThread == NULL)
{
return;
}
WriteTrace(TraceUserInterface, TraceDebug, "1");
SetEvent(m_WatchStopEvent);
DWORD ExitCode = 0;
for (int32_t count = 0; count < 20; count++)
{
WriteTrace(TraceUserInterface, TraceDebug, "2");
GetExitCodeThread(m_WatchThread, &ExitCode);
if (ExitCode != STILL_ACTIVE)
{
break;
}
Sleep(200);
}
WriteTrace(TraceUserInterface, TraceDebug, "3");
if (ExitCode == STILL_ACTIVE)
{
WriteTrace(TraceUserInterface, TraceDebug, "3a");
TerminateThread(m_WatchThread, 0);
}
WriteTrace(TraceUserInterface, TraceDebug, "4");
CloseHandle(m_WatchThread);
CloseHandle(m_WatchStopEvent);
m_WatchStopEvent = NULL;
m_WatchThread = NULL;
m_WatchThreadID = 0;
WriteTrace(TraceUserInterface, TraceDebug, "5");
}
MD5 CRomList::RomListHash(strlist & FileList)
{
stdstr NewFileNames;
@ -798,7 +648,7 @@ void CRomList::AddFileNameToList(strlist & FileList, const stdstr & Directory, C
{
if (Extension == ROM_extensions[i])
{
stdstr FileName = Directory + Name + Extension;
stdstr FileName = Directory + Name + "." + Extension;
FileName.ToLower();
FileList.push_back(FileName);
break;
@ -806,40 +656,3 @@ void CRomList::AddFileNameToList(strlist & FileList, const stdstr & Directory, C
}
}
bool CRomList::GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const std::string & Directory, bool InWatchThread)
{
if (!BaseDirectory.DirectoryExists())
{
return false;
}
CPath SearchPath(BaseDirectory, "*.*");
SearchPath.AppendDirectory(Directory.c_str());
if (!SearchPath.FindFirst(CPath::FIND_ATTRIBUTE_ALLFILES))
{
return false;
}
do
{
if (InWatchThread && WaitForSingleObject(m_WatchStopEvent, 0) != WAIT_TIMEOUT)
{
return false;
}
if (SearchPath.IsDirectory())
{
if (g_Settings->LoadBool(RomList_GameDirRecursive))
{
CPath CurrentDir(Directory);
CurrentDir.AppendDirectory(SearchPath.GetLastDirectory().c_str());
GetRomFileNames(FileList, BaseDirectory, CurrentDir, InWatchThread);
}
}
else
{
AddFileNameToList(FileList, Directory, SearchPath);
}
} while (SearchPath.FindNext());
return true;
}

View File

@ -61,9 +61,8 @@ protected:
virtual void RomListLoaded(void) {}
virtual void RomDirChanged(void) {}
void WatchThreadStart(void);
void WatchThreadStop(void);
MD5 RomListHash(strlist & FileList);
void AddFileNameToList(strlist & FileList, const stdstr & Directory, CPath & File);
ROMINFO_LIST m_RomInfo;
bool m_StopRefresh;
@ -73,19 +72,10 @@ private:
bool FillRomInfo(ROM_INFO * pRomInfo);
void FillRomExtensionInfo(ROM_INFO * pRomInfo);
bool LoadDataFromRomFile(const char * FileName, uint8_t * Data, int32_t DataLen, int32_t * RomSize, FILE_FORMAT & FileFormat);
void AddFileNameToList(strlist & FileList, const stdstr & Directory, CPath & File);
void SaveRomList(strlist & FileList);
void RefreshRomListThread(void);
bool GetRomFileNames(strlist & FileList, const CPath & BaseDirectory, const std::string & Directory, bool InWatchThread);
MD5 RomListHash(strlist & FileList);
//Watch Directory Changed function
HANDLE m_WatchThread, m_WatchStopEvent;
DWORD m_WatchThreadID;
bool RomDirNeedsRefresh(void); // Called from watch thread
static void NotificationCB(const char * Status, CRomList * _this);
static void WatchRomDirChanged(CRomList * _this);
static void RefreshRomListStatic(CRomList * _this);
static void ByteSwapRomData(uint8_t * Data, int DataLen);
@ -96,6 +86,4 @@ private:
CIniFile * m_ZipIniFile;
#endif
HANDLE m_RefreshThread;
stdstr m_WatchRomDir;
};