#ifndef WATCHER_H #define WATCHER_H #include #include #include #include #include "Glob.hh" #include "Event.hh" #include "Debounce.hh" #include "DirTree.hh" #include "Signal.hh" using namespace Napi; struct Watcher; using WatcherRef = std::shared_ptr; struct Callback { Napi::ThreadSafeFunction tsfn; Napi::FunctionReference ref; std::thread::id threadId; }; class WatcherState { public: virtual ~WatcherState() = default; }; struct Watcher { std::string mDir; std::unordered_set mIgnorePaths; std::unordered_set mIgnoreGlobs; EventList mEvents; std::shared_ptr state; Watcher(std::string dir, std::unordered_set ignorePaths, std::unordered_set ignoreGlobs); ~Watcher(); bool operator==(const Watcher &other) const { return mDir == other.mDir && mIgnorePaths == other.mIgnorePaths && mIgnoreGlobs == other.mIgnoreGlobs; } void wait(); void notify(); void notifyError(std::exception &err); bool watch(Function callback); bool unwatch(Function callback); void unref(); bool isIgnored(std::string path); void destroy(); static WatcherRef getShared(std::string dir, std::unordered_set ignorePaths, std::unordered_set ignoreGlobs); private: std::mutex mMutex; std::condition_variable mCond; std::vector mCallbacks; std::shared_ptr mDebounce; std::vector::iterator findCallback(Function callback); void clearCallbacks(); void triggerCallbacks(); }; class WatcherError : public std::runtime_error { public: WatcherRef mWatcher; WatcherError(std::string msg, WatcherRef watcher) : std::runtime_error(msg), mWatcher(watcher) {} WatcherError(const char *msg, WatcherRef watcher) : std::runtime_error(msg), mWatcher(watcher) {} }; #endif