Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
FileSystemWatcher.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4
5#include "../Foundation/Function.h"
6#include "../Foundation/OpaqueObject.h"
7#include "../Foundation/Result.h"
8#include "../Foundation/StringPath.h"
9
10namespace SC
11{
12
15
18
44
47{
48 private:
49 struct Internal;
50
51 struct InternalDefinition
52 {
53 static constexpr int Windows = 3 * sizeof(void*);
54 static constexpr int Apple = 42 * sizeof(void*);
55 static constexpr int Linux = sizeof(void*) * 4;
56 static constexpr int Default = Linux;
57
58 static constexpr size_t Alignment = alignof(void*);
59
60 using Object = Internal;
61 };
62
63 public:
64 // Must be public to avoid GCC complaining
66
67 private:
68 InternalOpaque internal;
69
70 //...
72 struct ThreadRunnerInternal;
73 struct ThreadRunnerDefinition
74 {
75 static constexpr int MaxWatchablePaths = 1024;
76
77 static constexpr int Windows = (2 * MaxWatchablePaths + 2) * sizeof(void*) + sizeof(uint64_t);
78 static constexpr int Apple = sizeof(void*);
79 static constexpr int Linux = sizeof(void*) * 6;
80 static constexpr int Default = Linux;
81
82 static constexpr size_t Alignment = alignof(void*);
83
84 using Object = ThreadRunnerInternal;
85 };
86
87 struct FolderWatcherInternal;
88 struct FolderWatcherSizes
89 {
90 static constexpr int MaxNumberOfSubdirs = 128; // Max number of subfolders tracked in a watcher
91 static constexpr int MaxChangesBufferSize = 1024;
92
93 static constexpr int Windows = MaxChangesBufferSize + sizeof(void*) + sizeof(void*);
94 static constexpr int Apple = sizeof(void*);
95 static constexpr int Linux = 1056 + 1024 + 8;
96 static constexpr int Default = Linux;
97
98 static constexpr size_t Alignment = alignof(void*);
99
100 using Object = FolderWatcherInternal;
101 };
102
103 public:
106 enum class Operation
107 {
108 Modified,
110 };
111
114 {
118
123
124 private:
125 friend struct Internal;
126#if SC_PLATFORM_APPLE
127 StringSpan fullPath;
128#endif
129 };
130
135 {
140 FolderWatcher(Span<char> subFolderRelativePathsBuffer = {});
141
143
147
149 void setDebugName(const char* debugName);
150
151 private:
152 friend struct FileSystemWatcher;
153 friend struct FileSystemWatcherAsync;
154#if SC_PLATFORM_WINDOWS
155#if SC_ASYNC_ENABLE_LOG
156 AlignedStorage<120> asyncStorage;
157#else
158 AlignedStorage<112> asyncStorage;
159#endif
160#endif
162
163 FileSystemWatcher* parent = nullptr;
164 FolderWatcher* next = nullptr;
165 FolderWatcher* prev = nullptr;
166
167 StringPath path;
168
169#if SC_PLATFORM_LINUX
170 Span<char> subFolderRelativePathsBuffer;
171#endif
172 };
173
176 {
177 virtual ~EventLoopRunner() {}
178
179 protected:
180#if SC_PLATFORM_APPLE
181 virtual Result appleStartWakeUp() = 0;
182 virtual void appleSignalEventObject() = 0;
183 virtual Result appleWakeUpAndWait() = 0;
184
185#elif SC_PLATFORM_LINUX
186 virtual Result linuxStartSharedFilePoll() = 0;
187 virtual Result linuxStopSharedFilePoll() = 0;
188
189 int notifyFd = -1;
190
191#else
192 virtual Result windowsStartFolderFilePoll(FolderWatcher& watcher, void* handle) = 0;
193 virtual Result windowsStopFolderFilePoll(FolderWatcher& watcher) = 0;
194 virtual void* windowsGetOverlapped(FolderWatcher& watcher) = 0;
195#endif
196 friend struct Internal;
197 FileSystemWatcher* fileSystemWatcher = nullptr;
198
199 void internalInit(FileSystemWatcher& fsWatcher, int handle);
200 };
201
204
209
214
218
225
226 void asyncNotify(FolderWatcher* watcher);
227
228 private:
229 friend decltype(internal);
230 friend decltype(FolderWatcher::internal);
231 friend struct EventLoopRunner;
232 // Trimmed duplicate of IntrusiveDoubleLinkedList<T>
233 struct WatcherLinkedList
234 {
235 FolderWatcher* back = nullptr; // has no next
236 FolderWatcher* front = nullptr; // has no prev
237
238 void queueBack(FolderWatcher& watcher);
239 void remove(FolderWatcher& watcher);
240 };
241 WatcherLinkedList watchers;
242};
243
245} // namespace SC
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:42
A buffer of bytes with given alignment.
Definition AlignedStorage.h:29
FileSystemWatcherAsync is an implementation of SC::FileSystemWatcher that uses SC::Async.
Definition FileSystemWatcherAsync.h:30
Abstract class to use event loop notifications (see SC::FileSystemWatcherAsync).
Definition FileSystemWatcher.h:176
Represents a single folder being watched.
Definition FileSystemWatcher.h:135
Function< void(const Notification &)> notifyCallback
Function that will be called on a notification.
Definition FileSystemWatcher.h:142
FolderWatcher(Span< char > subFolderRelativePathsBuffer={})
Constructs a folder watcher.
void setDebugName(const char *debugName)
Sets debug name for AsyncFilePoll used on Windows (used only for debug purposes)
Result stopWatching()
Stop watching this directory.
Notification holding type and path.
Definition FileSystemWatcher.h:114
StringSpan relativePath
Relative path of the file being notified from basePath
Definition FileSystemWatcher.h:116
Operation operation
Notification type.
Definition FileSystemWatcher.h:117
StringSpan basePath
Reference to the watched directory.
Definition FileSystemWatcher.h:115
SC::Result getFullPath(StringPath &path) const
Get the full path of the file being watched.
Notifies about events (add, remove, rename, modified) on files and directories.
Definition FileSystemWatcher.h:47
Result close()
Stops all watchers and frees the ThreadRunner or EventLoopRunner passed in init.
Result init(EventLoopRunner &runner)
Setup watcher to receive async notifications on an event loop.
Result init(ThreadRunner &runner)
Setup watcher to receive notifications from a background thread.
Operation
Specifies the event classes.
Definition FileSystemWatcher.h:107
@ Modified
A file or directory has been modified in its contents and/or timestamp.
@ AddRemoveRename
A file or directory has been added, removed or renamed.
Result watch(FolderWatcher &watcher, StringSpan path)
Starts watching a single directory, calling FolderWatcher::notifyCallback on file events.
Wraps function pointers, member functions and lambdas without ever allocating.
Definition Function.h:19
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition Result.h:12
View over a contiguous sequence of items (pointer + size in elements).
Definition Span.h:29
Pre-sized char array holding enough space to represent a file system path.
Definition StringPath.h:42
An read-only view over a string (to avoid including Strings library when parsing is not needed).
Definition StringSpan.h:37