annotate src/core/filesystem.cc @ 398:650a9159a0e7

filesystem: implement win32 watchers These are really nice :)
author Paper <paper@tflc.us>
date Fri, 07 Nov 2025 14:32:11 -0500
parents 963047512d34
children a0bc3ae5164a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
36
2743011a6042 *: mass update
Paper <mrpapersonic@gmail.com>
parents: 18
diff changeset
1 #include "core/filesystem.h"
15
cde8f67a7c7d *: update, megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 11
diff changeset
2 #include "core/config.h"
62
4c6dd5999b39 *: update
Paper <mrpapersonic@gmail.com>
parents: 61
diff changeset
3 #include "core/strings.h"
250
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
4
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
5 #include <QStandardPaths>
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
6
135
0a458cb26ff4 filesystem: move to using std::filesystem after C++17 switch
Paper <mrpapersonic@gmail.com>
parents: 134
diff changeset
7 #include <filesystem>
2
Paper <mrpapersonic@gmail.com>
parents: 1
diff changeset
8
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
9 #ifdef WIN32
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
10 # include <windows.h>
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
11 #endif
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
12
11
fc1bf97c528b *: use C++11 standard
Paper <mrpapersonic@gmail.com>
parents: 9
diff changeset
13 namespace Filesystem {
fc1bf97c528b *: use C++11 standard
Paper <mrpapersonic@gmail.com>
parents: 9
diff changeset
14
135
0a458cb26ff4 filesystem: move to using std::filesystem after C++17 switch
Paper <mrpapersonic@gmail.com>
parents: 134
diff changeset
15 /* this runs fs::create_directories() on the
0a458cb26ff4 filesystem: move to using std::filesystem after C++17 switch
Paper <mrpapersonic@gmail.com>
parents: 134
diff changeset
16 PARENT directory. */
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
17 void CreateDirectories(const std::filesystem::path &path)
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
18 {
158
80d6b28eb29f dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents: 138
diff changeset
19 if (path.empty())
80d6b28eb29f dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents: 138
diff changeset
20 return;
80d6b28eb29f dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents: 138
diff changeset
21
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
22 const auto &parent = path.parent_path();
158
80d6b28eb29f dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents: 138
diff changeset
23 if (!std::filesystem::exists(parent))
80d6b28eb29f dep/animia: fix most X11 stuff
Paper <mrpapersonic@gmail.com>
parents: 138
diff changeset
24 std::filesystem::create_directories(parent);
11
fc1bf97c528b *: use C++11 standard
Paper <mrpapersonic@gmail.com>
parents: 9
diff changeset
25 }
fc1bf97c528b *: use C++11 standard
Paper <mrpapersonic@gmail.com>
parents: 9
diff changeset
26
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
27 std::filesystem::path GetDotPath()
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
28 {
250
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
29 /*
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
30 * Windows: ~/AppData/Roaming/Minori
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
31 * macOS: ~/Library/Application Support/Minori
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
32 * ...: ~/.config/minori
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
33 *
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
34 * FIXME: are windows and mac properly cased?
258
862d0d8619f6 *: HUUUGE changes
Paper <paper@paper.us.eu.org>
parents: 250
diff changeset
35 */
9
5c0397762b53 INCOMPLETE: megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 7
diff changeset
36 #ifdef WIN32
250
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
37 return Strings::ToUtf8String(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
38 #else
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
39 return Strings::ToUtf8String(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation));
c130f47f6f48 *: many many changes
Paper <paper@paper.us.eu.org>
parents: 230
diff changeset
40 #endif
45
4b05bc7668eb filesystem: split config path into dotpath and config, add anime db path
Paper <mrpapersonic@gmail.com>
parents: 44
diff changeset
41 }
4b05bc7668eb filesystem: split config path into dotpath and config, add anime db path
Paper <mrpapersonic@gmail.com>
parents: 44
diff changeset
42
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
43 std::filesystem::path GetConfigPath()
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
44 {
135
0a458cb26ff4 filesystem: move to using std::filesystem after C++17 switch
Paper <mrpapersonic@gmail.com>
parents: 134
diff changeset
45 return GetDotPath() / CONFIG_NAME;
118
39521c47c7a3 *: another huge megacommit, SORRY
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
46 }
39521c47c7a3 *: another huge megacommit, SORRY
Paper <mrpapersonic@gmail.com>
parents: 106
diff changeset
47
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
48 std::filesystem::path GetAnimeDBPath()
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
49 {
135
0a458cb26ff4 filesystem: move to using std::filesystem after C++17 switch
Paper <mrpapersonic@gmail.com>
parents: 134
diff changeset
50 return GetDotPath() / "anime" / "db.json";
45
4b05bc7668eb filesystem: split config path into dotpath and config, add anime db path
Paper <mrpapersonic@gmail.com>
parents: 44
diff changeset
51 }
4b05bc7668eb filesystem: split config path into dotpath and config, add anime db path
Paper <mrpapersonic@gmail.com>
parents: 44
diff changeset
52
369
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
53 std::filesystem::path GetTorrentsPath()
47c9f8502269 *: clang-format all the things
Paper <paper@tflc.us>
parents: 258
diff changeset
54 {
230
2f5a9247e501 torrents: implement download button
Paper <paper@paper.us.eu.org>
parents: 221
diff changeset
55 return GetDotPath() / "torrents";
2f5a9247e501 torrents: implement download button
Paper <paper@paper.us.eu.org>
parents: 221
diff changeset
56 }
2f5a9247e501 torrents: implement download button
Paper <paper@paper.us.eu.org>
parents: 221
diff changeset
57
378
5912dafc6e28 anime: add poster cache
Paper <paper@tflc.us>
parents: 369
diff changeset
58 std::filesystem::path GetAnimePostersPath()
5912dafc6e28 anime: add poster cache
Paper <paper@tflc.us>
parents: 369
diff changeset
59 {
5912dafc6e28 anime: add poster cache
Paper <paper@tflc.us>
parents: 369
diff changeset
60 return GetDotPath() / "anime" / "posters";
5912dafc6e28 anime: add poster cache
Paper <paper@tflc.us>
parents: 369
diff changeset
61 }
5912dafc6e28 anime: add poster cache
Paper <paper@tflc.us>
parents: 369
diff changeset
62
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
63 /* ------------------------------------------------------------------------ */
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
64 /* Ehhhhh */
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
65
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
66 class Watcher : public IWatcher {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
67 public:
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
68 Watcher(void *opaque, const std::filesystem::path &path, EventHandler handler)
393
963047512d34 *: clang-format
Paper <paper@tflc.us>
parents: 391
diff changeset
69 : path_(path), handler_(handler), opaque_(opaque)
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
70 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
71 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
72
393
963047512d34 *: clang-format
Paper <paper@tflc.us>
parents: 391
diff changeset
73 virtual ~Watcher() override {}
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
74
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
75 protected:
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
76 std::filesystem::path path_;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
77 EventHandler handler_;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
78 void *opaque_;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
79 };
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
80
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
81 /* ------------------------------------------------------------------------ */
391
c3f717b7321b filesystem: only iterate over the list once when erasing deleted files
Paper <paper@tflc.us>
parents: 382
diff changeset
82 /* Filesystem watcher.
c3f717b7321b filesystem: only iterate over the list once when erasing deleted files
Paper <paper@tflc.us>
parents: 382
diff changeset
83 * This is the portable version for non-Windows (of which the Windows
c3f717b7321b filesystem: only iterate over the list once when erasing deleted files
Paper <paper@tflc.us>
parents: 382
diff changeset
84 * specific version hasn't been written yet... TODO) */
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
85
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
86 /*
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
87 We can't use std::recursive_directory_iterator!
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
88 Why? Well, to put it blunt, it sucks. The main reason
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
89 being is that if it finds a single directory it cannot
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
90 recurse into, instead of safely recovering, it just
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
91 completely stops. I am dumbfounded at this behavior, but
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
92 nevertheless it means we simply can't use it, and must
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
93 resort to old-fashioned recursion. --paper
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
94 */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
95 static void IterateDirectory(const std::filesystem::path &path, bool recursive,
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
96 std::function<void(const std::filesystem::path &path)> func)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
97 {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
98 std::error_code ec;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
99 static const std::filesystem::directory_iterator end;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
100
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
101 for (std::filesystem::directory_iterator item(path, ec); item != end; item.increment(ec)) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
102 if (ec)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
103 continue;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
104
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
105 std::filesystem::path p = item->path();
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
106
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
107 /* Hand the path off to the listener */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
108 func(p);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
109
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
110 /* If we're dealing with another directory, recurse into it. */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
111 if (recursive && item->is_directory())
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
112 IterateDirectory(p, true, func);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
113 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
114 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
115
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
116 class StdFilesystemWatcher : public Watcher {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
117 public:
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
118 StdFilesystemWatcher(void *opaque, const std::filesystem::path &path, EventHandler handler, bool recursive)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
119 : Watcher(opaque, path, handler), recursive_(recursive)
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
120 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
121 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
122
393
963047512d34 *: clang-format
Paper <paper@tflc.us>
parents: 391
diff changeset
123 virtual ~StdFilesystemWatcher() override {}
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
124
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
125 virtual void Process() override
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
126 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
127 /* Untoggle all paths. This allows us to only ever
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
128 * iterate over the directory ONCE. */
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
129 UntoggleAllPaths();
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
130
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
131 /* Start iterating directories. If we're recursive, this
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
132 * will go through the whole tree. */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
133 IterateDirectory(path_, recursive_, [this](const std::filesystem::path &p) {
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
134 if (FindAndTogglePath(p))
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
135 return;
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
136
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
137 handler_(opaque_, p, Event::Created);
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
138 paths_.insert({p, true});
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
139 });
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
140
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
141 DeleteUntoggledPaths();
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
142 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
143
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
144 protected:
391
c3f717b7321b filesystem: only iterate over the list once when erasing deleted files
Paper <paper@tflc.us>
parents: 382
diff changeset
145 bool FindAndTogglePath(const std::filesystem::path &p)
c3f717b7321b filesystem: only iterate over the list once when erasing deleted files
Paper <paper@tflc.us>
parents: 382
diff changeset
146 {
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
147 auto it = paths_.find(p);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
148 if (it == paths_.end())
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
149 return false;
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
150
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
151 it->second = true;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
152 return true;
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
153 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
154
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
155 void UntoggleAllPaths()
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
156 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
157 for (auto &pp : paths_)
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
158 pp.second = false;
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
159 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
160
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
161 void DeleteUntoggledPaths()
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
162 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
163 auto it = paths_.begin();
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
164
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
165 while (it != paths_.end()) {
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
166 if (!it->second) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
167 handler_(opaque_, it->first, Event::Deleted);
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
168 it = paths_.erase(it);
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
169 } else {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
170 it++;
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
171 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
172 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
173 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
174
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
175 /* unordered hashmap, path[found] */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
176 std::unordered_map<std::filesystem::path, bool> paths_;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
177 bool recursive_;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
178 };
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
179
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
180 #ifdef WIN32
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
181 /* On Windows, we can ask the OS whether the folder has changed or not.
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
182 * This is great for us! */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
183 class Win32Watcher : public StdFilesystemWatcher {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
184 public:
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
185 Win32Watcher(void *opaque, const std::filesystem::path &path, IWatcher::EventHandler handler, bool recursive)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
186 : StdFilesystemWatcher(opaque, path, handler, recursive), dirwatcher_(INVALID_HANDLE_VALUE), first_(true)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
187 {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
188 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
189
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
190 virtual ~Win32Watcher() override
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
191 {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
192 // delete handle
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
193 if (dirwatcher_ != INVALID_HANDLE_VALUE)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
194 FindCloseChangeNotification(dirwatcher_);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
195 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
196
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
197 virtual void Process() override
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
198 {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
199 if (first_ || dirwatcher_ == INVALID_HANDLE_VALUE) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
200 /* We want to create this right before iteration so
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
201 * we minimize possible race conditions while also
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
202 * reducing unnecessary processing */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
203 TryCreateDirWatcher();
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
204 StdFilesystemWatcher::Process();
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
205 first_ = false;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
206 return;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
207 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
208
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
209 /* We have a valid handle */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
210 if (WaitForSingleObject(dirwatcher_, 0) != WAIT_OBJECT_0)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
211 return;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
212
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
213 StdFilesystemWatcher::Process();
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
214 FindNextChangeNotification(dirwatcher_);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
215 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
216
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
217 protected:
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
218 bool TryCreateDirWatcher()
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
219 {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
220 dirwatcher_ = FindFirstChangeNotificationW(Watcher::path_.wstring().c_str(), recursive_,
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
221 FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
222
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
223 return (dirwatcher_ != INVALID_HANDLE_VALUE);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
224 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
225
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
226 /* variables */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
227 HANDLE dirwatcher_;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
228 bool first_;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
229 };
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
230
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
231 class Win32WatcherVista : public Win32Watcher {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
232 public:
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
233 Win32WatcherVista(void *opaque, const std::filesystem::path &path, IWatcher::EventHandler handler, bool recursive)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
234 : Win32Watcher(opaque, path, handler, recursive), dirhandle_(INVALID_HANDLE_VALUE)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
235 {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
236 overlapped_.hEvent = nullptr;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
237 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
238
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
239 virtual ~Win32WatcherVista() override
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
240 {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
241 if (dirhandle_ != INVALID_HANDLE_VALUE)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
242 CloseHandle(dirhandle_);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
243
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
244 if (overlapped_.hEvent != nullptr)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
245 CloseHandle(overlapped_.hEvent);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
246 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
247
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
248 virtual void Process() override
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
249 {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
250 if (first_) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
251 if (TryCreateHandles()) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
252 /* Queue a directory read asynchronously. On the next run, this will
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
253 * be waited on. */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
254 QueueDirectoryRead();
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
255
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
256 /* Avoid running Win32Watcher::Process, as it will read the whole
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
257 * directory tree into memory. Instead, iterate through the directory
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
258 * ourselves. */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
259 IterateDirectory(path_, recursive_,
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
260 [this](const std::filesystem::path &p) { handler_(opaque_, p, Event::Created); });
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
261 } else {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
262 /* Uh oh; we might have to fall back to Win32Watcher. Call into it to
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
263 * load the tree into memory. */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
264 Win32Watcher::Process();
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
265 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
266
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
267 first_ = false;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
268 return;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
269 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
270
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
271 if (!HandlesAreValid()) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
272 /* If we're here, we already fell back into Win32Watcher, so just
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
273 * call back into again. On the slim chance TryCreateHandles() might
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
274 * succeed, call it as well... */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
275 if (TryCreateHandles())
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
276 QueueDirectoryRead();
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
277 Win32Watcher::Process();
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
278 return;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
279 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
280
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
281 if (WaitForSingleObject(overlapped_.hEvent, 0) != WAIT_OBJECT_0)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
282 return;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
283
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
284 FILE_NOTIFY_INFORMATION *ev = reinterpret_cast<FILE_NOTIFY_INFORMATION *>(change_buf_);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
285
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
286 for (;;) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
287 /* Tack on the file name to the end of our path */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
288 std::filesystem::path p = Watcher::path_ / std::wstring(ev->FileName, ev->FileNameLength / sizeof(WCHAR));
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
289
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
290 switch (ev->Action) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
291 case FILE_ACTION_ADDED:
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
292 case FILE_ACTION_RENAMED_NEW_NAME:
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
293 /* File was added */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
294 handler_(opaque_, p, Event::Created);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
295 break;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
296 case FILE_ACTION_REMOVED:
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
297 case FILE_ACTION_RENAMED_OLD_NAME:
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
298 /* File was removed */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
299 handler_(opaque_, p, Event::Deleted);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
300 break;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
301 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
302
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
303 if (ev->NextEntryOffset) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
304 /* ugh ugh ugh ugh */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
305 ev = reinterpret_cast<FILE_NOTIFY_INFORMATION *>(reinterpret_cast<char *>(ev) + ev->NextEntryOffset);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
306 } else {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
307 break;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
308 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
309 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
310
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
311 /* Queue a directory read for the next call */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
312 QueueDirectoryRead();
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
313 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
314
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
315 protected:
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
316 bool HandlesAreValid() { return (overlapped_.hEvent && dirhandle_ != INVALID_HANDLE_VALUE); }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
317
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
318 bool TryCreateHandles()
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
319 {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
320 if (!overlapped_.hEvent) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
321 overlapped_.hEvent = CreateEventW(nullptr, FALSE, 0, nullptr);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
322 if (!overlapped_.hEvent)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
323 return false;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
324 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
325
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
326 if (dirhandle_ == INVALID_HANDLE_VALUE) {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
327 dirhandle_ =
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
328 CreateFileW(Watcher::path_.wstring().c_str(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE,
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
329 nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, nullptr);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
330 if (dirhandle_ == INVALID_HANDLE_VALUE)
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
331 return false;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
332 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
333
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
334 /* We're done here */
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
335 return true;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
336 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
337
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
338 bool QueueDirectoryRead()
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
339 {
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
340 return ReadDirectoryChangesW(dirhandle_, change_buf_, sizeof(change_buf_), TRUE,
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
341 FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME, nullptr, &overlapped_,
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
342 nullptr);
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
343 }
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
344
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
345 HANDLE dirhandle_;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
346 OVERLAPPED overlapped_;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
347 alignas(FILE_NOTIFY_INFORMATION) char change_buf_[4096];
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
348 };
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
349
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
350 using DefaultWatcher = Win32WatcherVista;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
351 #else
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
352 using DefaultWatcher = StdFilesystemWatcher;
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
353 #endif
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
354
393
963047512d34 *: clang-format
Paper <paper@tflc.us>
parents: 391
diff changeset
355 IWatcher *GetRecursiveFilesystemWatcher(void *opaque, const std::filesystem::path &path, IWatcher::EventHandler handler)
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
356 {
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
357 /* .... :) */
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
358 return new DefaultWatcher(opaque, path, handler, true);
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
359 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
360
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
361 IWatcher *GetFilesystemWatcher(void *opaque, const std::filesystem::path &path, IWatcher::EventHandler handler)
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
362 {
398
650a9159a0e7 filesystem: implement win32 watchers
Paper <paper@tflc.us>
parents: 393
diff changeset
363 return new DefaultWatcher(opaque, path, handler, false);
382
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
364 }
0265e125f680 filesystem: implement filesystem watcher
Paper <paper@tflc.us>
parents: 378
diff changeset
365
15
cde8f67a7c7d *: update, megacommit :)
Paper <mrpapersonic@gmail.com>
parents: 11
diff changeset
366 } // namespace Filesystem