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