1 #pragma once 2 3 4 #include <utility> 5 #include <string> 6 #include <memory> 7 #include <chrono> 8 #include <uv.h> 9 #include "handle.hpp" 10 #include "util.hpp" 11 #include "loop.hpp" 12 13 14 namespace uvw { 15 16 17 /** 18 * @brief FsPollEvent event. 19 * 20 * It will be emitted by FsPollHandle according with its functionalities. 21 */ 22 struct FsPollEvent { FsPollEventuvw::FsPollEvent23 explicit FsPollEvent(Stat previous, Stat current) noexcept 24 : prev{std::move(previous)}, curr{std::move(current)} 25 {} 26 27 Stat prev; /*!< The old Stat struct. */ 28 Stat curr; /*!< The new Stat struct. */ 29 }; 30 31 32 /** 33 * @brief The FsPollHandle handle. 34 * 35 * It allows the user to monitor a given path for changes. Unlike FsEventHandle 36 * handles, FsPollHandle handles use stat to detect when a file has changed so 37 * they can work on file systems where FsEventHandle handles can’t. 38 * 39 * To create a `FsPollHandle` through a `Loop`, no arguments are required. 40 */ 41 class FsPollHandle final: public Handle<FsPollHandle, uv_fs_poll_t> { startCallback(uv_fs_poll_t * handle,int status,const uv_stat_t * prev,const uv_stat_t * curr)42 static void startCallback(uv_fs_poll_t *handle, int status, const uv_stat_t *prev, const uv_stat_t *curr) { 43 FsPollHandle &fsPoll = *(static_cast<FsPollHandle*>(handle->data)); 44 if(status) { fsPoll.publish(ErrorEvent{status}); } 45 else { fsPoll.publish(FsPollEvent{ *prev, *curr }); } 46 } 47 48 public: 49 using Time = std::chrono::duration<unsigned int, std::milli>; 50 51 using Handle::Handle; 52 53 /** 54 * @brief Initializes the handle. 55 * @return True in case of success, false otherwise. 56 */ init()57 bool init() { 58 return initialize(&uv_fs_poll_init); 59 } 60 61 /** 62 * @brief Starts the handle. 63 * 64 * The handle will start emitting FsPollEvent when needed. 65 * 66 * @param file The path to the file to be checked. 67 * @param interval Milliseconds between successive checks. 68 */ start(std::string file,Time interval)69 void start(std::string file, Time interval) { 70 invoke(&uv_fs_poll_start, get(), &startCallback, file.data(), interval.count()); 71 } 72 73 /** 74 * @brief Stops the handle. 75 */ stop()76 void stop() { 77 invoke(&uv_fs_poll_stop, get()); 78 } 79 80 /** 81 * @brief Gets the path being monitored by the handle. 82 * @return The path being monitored by the handle, an empty string in case 83 * of errors. 84 */ path()85 std::string path() noexcept { 86 return details::tryRead(&uv_fs_poll_getpath, get()); 87 } 88 }; 89 90 91 } 92