#include #include #include #include #include "Core/Util/Logging.h" namespace std { template<> struct hash < boost::filesystem::path > { size_t operator()(const boost::filesystem::path& p) const { return boost::filesystem::hash_value(p); } }; } namespace dd { class FileWatcher { public: enum class FileEventFlags; typedef std::function FileEventCallback_t; FileWatcher(); FileWatcher(std::string rootPath); ~FileWatcher(); std::string RootPath() const { return m_RootPath.string(); } void AddWatch(std::string path, FileEventCallback_t callback); void Start(); bool IsRunning() const { return m_IsRunning; } void Stop(); void Check(); private: class Worker; boost::filesystem::path m_RootPath; boost::thread m_Thread; Worker* m_Worker = nullptr; bool m_IsRunning = false; }; enum class FileWatcher::FileEventFlags { Nothing = 0, Created = 1 << 0, SizeChanged = 1 << 1, TimestampChanged = 1 << 2, Deleted = 1 << 3 }; inline FileWatcher::FileEventFlags operator|(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return static_cast(static_cast(a) | static_cast(b)); } inline bool operator&(FileWatcher::FileEventFlags a, FileWatcher::FileEventFlags b) { return static_cast(a)& static_cast(b); } class FileWatcher::Worker { public: void operator()(); void AddWatch(std::string path, FileEventCallback_t callback); void Check(); private: struct FileInfo { int Size; std::time_t Timestamp; }; std::unordered_map m_FileCallbacks; std::unordered_map m_FileInfo; boost::mutex m_Mutex; FileInfo GetFileInfo(boost::filesystem::path path); FileEventFlags UpdateFileInfo(boost::filesystem::path path); }; }