Commits

Anonymous committed f8d99d0

working solution on windows that can't be interrupted

Comments (0)

Files changed (4)

Win/FileWatcherTaskWin.cpp

+#include <string>
+#include "FileWatcherTaskWin.h"
+#include "variant_list.h"
+
+void FileWatcherTaskWin::Watch(std::string p, FB::JSObjectPtr callback)
+{
+	boost::thread thread = boost::thread(boost::bind(&FileWatcherTaskWin::ListenForFileEvents, this, p, callback));
+	thread.detach();
+}
+
+void FileWatcherTaskWin::ListenForFileEvents(std::string path, FB::JSObjectPtr callback)
+{
+	WCHAR widePathBuf[2048];
+	int wpBufSize = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, widePathBuf, 2048);
+	std::wstring widePath = widePathBuf;
+	
+	handle = CreateFile(widePath.c_str(), 
+								FILE_LIST_DIRECTORY, 
+								FILE_SHARE_READ | FILE_SHARE_WRITE,
+								NULL,
+								OPEN_EXISTING,
+								FILE_FLAG_BACKUP_SEMANTICS,
+								NULL);
+								//FindFirstChangeNotification (widePath.c_str(), TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE);
+	
+	
+	while (handle != INVALID_HANDLE_VALUE && !this->ShouldStop())
+	{
+		char buffer[4096];
+		DWORD bytesInBuf = 0;
+
+		ReadDirectoryChangesW(handle, buffer, 4096, TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE, &bytesInBuf, NULL, NULL);
+		
+		if (bytesInBuf > 0)
+		{
+			BOOL moreToRead = true;
+			char* readFrom = buffer;
+			while(moreToRead)
+			{
+				FILE_NOTIFY_INFORMATION* fni = (FILE_NOTIFY_INFORMATION*)readFrom;
+				std::wstring fileName(fni->FileName, fni->FileNameLength/sizeof(WCHAR));
+				std::wstring wideFinalPath = widePath + L"\\" + fileName;
+
+				char utf8Buf[2048];
+				int pathLength = WideCharToMultiByte(CP_UTF8, 0, wideFinalPath.c_str(), -1, utf8Buf, 2048, NULL, NULL);
+				std::string finalPath = utf8Buf;
+				
+				callback->Invoke("", FB::variant_list_of(finalPath));
+				if (!fni->NextEntryOffset)
+				{
+					moreToRead = false;
+				}
+				else
+				{
+					readFrom += fni->NextEntryOffset;
+				}
+			}
+		}
+	}
+}
+
+void FileWatcherTaskWin::StopWatching()
+{
+	BOOL success = CloseHandle(handle);
+	this->stop = true;
+}
+
+bool FileWatcherTaskWin::ShouldStop()
+{
+	return stop;
+}

Win/FileWatcherTaskWin.h

+#pragma once
+
+#include "JSObject.h"
+#include "windows.h"
+
+class FileWatcherTaskWin
+{
+public:
+	FileWatcherTaskWin(){stop = false;};
+	~FileWatcherTaskWin(){};
+
+	void Watch(std::string path, FB::JSObjectPtr callback);
+	void StopWatching();
+
+private:
+
+	void ListenForFileEvents(std::string path, FB::JSObjectPtr callback);
+	bool ShouldStop();
+	
+	HANDLE handle;
+	bool stop;
+	
+};

Win/FileWatcherWin.cpp

+#include "FileWatcherWin.h"
+
+FileWatcher* FileWatcher::get()
+{
+    static FileWatcherWin inst;
+    return &inst;
+}
+
+void FileWatcherWin::WatchFile(std::string key, std::string path, FB::JSObjectPtr callback)
+{
+	FileWatcherTaskWin* task = watchers[key];
+	if (!task)
+	{
+		boost::filesystem::path p(path);
+		if (is_directory(p))
+		{
+			task = new FileWatcherTaskWin();
+			task->Watch(path, callback);
+			watchers[key] = task;
+		}
+	}
+
+}
+void FileWatcherWin::StopWatching(std::string key)
+{
+	FileWatcherTaskWin* task = watchers[key];
+	if (task)
+	{
+		task->StopWatching();
+		watchers.erase(key);
+		delete task;
+	}
+}

Win/FileWatcherWin.h

+#pragma once
+
+#define BOOST_FILESYSTEM_VERSION 3
+#include <map>
+#include "../FileWatcher.h"
+#include "FileWatcherTaskWin.h"
+#include <boost/filesystem.hpp>
+
+
+class FileWatcherWin : public FileWatcher
+{
+public:
+	void WatchFile(std::string key, std::string path, FB::JSObjectPtr callback);
+    void StopWatching(std::string key);
+
+protected:
+	FileWatcherWin(void){};
+	~FileWatcherWin(void){};
+	friend class FileWatcher;
+private:
+	std::map<std::string,FileWatcherTaskWin*> watchers;
+};