home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / system / source / filewatcher.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  2.7 KB  |  118 lines

  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include <vd2/system/filesys.h>
  4. #include <vd2/system/filewatcher.h>
  5. #include <vd2/system/thunk.h>
  6. #include <vd2/system/w32assist.h>
  7.  
  8. VDFileWatcher::VDFileWatcher()
  9.     : mChangeHandle(INVALID_HANDLE_VALUE)
  10.     , mLastWriteTime(0)
  11.     , mbRepeatRequested(false)
  12.     , mbThunksInited(false)
  13.     , mpThunk(NULL)
  14.     , mTimerId(0)
  15. {
  16. }
  17.  
  18. VDFileWatcher::~VDFileWatcher() {
  19.     Shutdown();
  20. }
  21.  
  22. bool VDFileWatcher::IsActive() const {
  23.     return mChangeHandle != INVALID_HANDLE_VALUE;
  24. }
  25.  
  26. void VDFileWatcher::Init(const wchar_t *file, IVDFileWatcherCallback *callback) {
  27.     Shutdown();
  28.  
  29.     const wchar_t *pathEnd = VDFileSplitPath(file);
  30.  
  31.     VDStringW basePath(file, pathEnd);
  32.  
  33.     if (basePath.empty())
  34.         basePath = L".";
  35.  
  36.     if (VDIsWindowsNT())
  37.         mChangeHandle = FindFirstChangeNotificationW(basePath.c_str(), FALSE, FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE);
  38.     else
  39.         mChangeHandle = FindFirstChangeNotificationA(VDTextWToA(basePath).c_str(), FALSE, FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE);
  40.  
  41.     if (mChangeHandle == INVALID_HANDLE_VALUE)
  42.         throw MyError("Unable to monitor file: %ls", file);
  43.  
  44.     mPath = file;
  45.     mLastWriteTime = VDFileGetLastWriteTime(mPath.c_str());
  46.     mpCB = callback;
  47.     mbRepeatRequested = false;
  48.  
  49.     if (callback) {
  50.         if (!mbThunksInited)
  51.             mbThunksInited = VDInitThunkAllocator();
  52.  
  53.         if (mbThunksInited) {
  54.             mpThunk = VDCreateFunctionThunkFromMethod(this, &VDFileWatcher::StaticTimerCallback, true);
  55.  
  56.             if (mpThunk) {
  57.                 mTimerId = SetTimer(NULL, 0, 1000, (TIMERPROC)mpThunk);
  58.             }
  59.         }
  60.     }
  61. }
  62.  
  63. void VDFileWatcher::Shutdown() {
  64.     if (mChangeHandle != INVALID_HANDLE_VALUE) {
  65.         FindCloseChangeNotification(mChangeHandle);
  66.         mChangeHandle = INVALID_HANDLE_VALUE;
  67.     }
  68.  
  69.     if (mTimerId) {
  70.         KillTimer(NULL, mTimerId);
  71.         mTimerId = 0;
  72.     }
  73.  
  74.     if (mpThunk) {
  75.         VDDestroyFunctionThunk(mpThunk);
  76.         mpThunk = NULL;
  77.     }
  78.  
  79.     if (mbThunksInited) {
  80.         mbThunksInited = false;
  81.  
  82.         VDShutdownThunkAllocator();
  83.     }
  84. }
  85.  
  86. bool VDFileWatcher::Wait(uint32 delay) {
  87.     if (mChangeHandle == INVALID_HANDLE_VALUE)
  88.         return false;
  89.  
  90.     if (WAIT_OBJECT_0 != WaitForSingleObject(mChangeHandle, delay))
  91.         return false;
  92.  
  93.     FindNextChangeNotification(mChangeHandle);
  94.  
  95.     uint64 t = VDFileGetLastWriteTime(mPath.c_str());
  96.  
  97.     if (mLastWriteTime == t)
  98.         return false;
  99.  
  100.     mLastWriteTime = t;
  101.     return true;
  102. }
  103.  
  104. void VDFileWatcher::StaticTimerCallback(void *, unsigned, unsigned, unsigned long) {
  105.     if (mbRepeatRequested) {
  106.         if (mpCB)
  107.             mbRepeatRequested = !mpCB->OnFileUpdated(mPath.c_str());
  108.         else
  109.             mbRepeatRequested = false;
  110.         return;
  111.     }
  112.  
  113.     if (Wait(0)) {
  114.         if (mpCB)
  115.             mbRepeatRequested = !mpCB->OnFileUpdated(mPath.c_str());
  116.     }
  117. }
  118.