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
38
41{
42 private:
43 struct Internal;
44
45 struct InternalDefinition
46 {
47 static constexpr int Windows = 3 * sizeof(void*);
48 static constexpr int Apple = 42 * sizeof(void*);
49 static constexpr int Linux = sizeof(void*) * 4;
50 static constexpr int Default = Linux;
51
52 static constexpr size_t Alignment = alignof(void*);
53
54 using Object = Internal;
55 };
56
57 public:
58 // Must be public to avoid GCC complaining
60
61 private:
62 InternalOpaque internal;
63
64 //...
66 struct ThreadRunnerInternal;
67 struct ThreadRunnerDefinition
68 {
69 static constexpr int MaxWatchablePaths = 1024;
70
71 static constexpr int Windows = (2 * MaxWatchablePaths + 2) * sizeof(void*) + sizeof(uint64_t);
72 static constexpr int Apple = sizeof(void*);
73 static constexpr int Linux = sizeof(void*) * 6;
74 static constexpr int Default = Linux;
75
76 static constexpr size_t Alignment = alignof(void*);
77
78 using Object = ThreadRunnerInternal;
79 };
80
81 struct FolderWatcherInternal;
82 struct FolderWatcherSizes
83 {
84 static constexpr int MaxNumberOfSubdirs = 128; // Max number of subfolders tracked in a watcher
85 static constexpr int MaxChangesBufferSize = 1024;
86
87 static constexpr int Windows = MaxChangesBufferSize + sizeof(void*) + sizeof(void*);
88 static constexpr int Apple = sizeof(void*);
89 static constexpr int Linux = 1056 + 1024 + 8;
90 static constexpr int Default = Linux;
91
92 static constexpr size_t Alignment = alignof(void*);
93
94 using Object = FolderWatcherInternal;
95 };
96
97 public:
100 enum class Operation
101 {
102 Modified,
104 };
105
108 {
112
117
118 private:
119 friend struct Internal;
120#if SC_PLATFORM_APPLE
121 StringSpan fullPath;
122#endif
123 };
124
129 {
134 FolderWatcher(Span<char> subFolderRelativePathsBuffer = {});
135
137
141
143 void setDebugName(const char* debugName);
144
145 private:
146 friend struct FileSystemWatcher;
147 friend struct FileSystemWatcherAsync;
148#if SC_PLATFORM_WINDOWS
149#if SC_ASYNC_ENABLE_LOG
150 AlignedStorage<120> asyncStorage;
151#else
152 AlignedStorage<112> asyncStorage;
153#endif
154#endif
156
157 FileSystemWatcher* parent = nullptr;
158 FolderWatcher* next = nullptr;
159 FolderWatcher* prev = nullptr;
160
161 StringPath path;
162
163#if SC_PLATFORM_LINUX
164 Span<char> subFolderRelativePathsBuffer;
165#endif
166 };
167
170 {
171 virtual ~EventLoopRunner() {}
172
173 protected:
174#if SC_PLATFORM_APPLE
175 virtual Result appleStartWakeUp() = 0;
176 virtual void appleSignalEventObject() = 0;
177 virtual Result appleWakeUpAndWait() = 0;
178
179#elif SC_PLATFORM_LINUX
180 virtual Result linuxStartSharedFilePoll() = 0;
181 virtual Result linuxStopSharedFilePoll() = 0;
182
183 int notifyFd = -1;
184
185#else
186 virtual Result windowsStartFolderFilePoll(FolderWatcher& watcher, void* handle) = 0;
187 virtual Result windowsStopFolderFilePoll(FolderWatcher& watcher) = 0;
188 virtual void* windowsGetOverlapped(FolderWatcher& watcher) = 0;
189#endif
190 friend struct Internal;
191 FileSystemWatcher* fileSystemWatcher = nullptr;
192
193 void internalInit(FileSystemWatcher& fsWatcher, int handle);
194 };
195
198
203
208
212
219
220 void asyncNotify(FolderWatcher* watcher);
221
222 private:
223 friend decltype(internal);
224 friend decltype(FolderWatcher::internal);
225 friend struct EventLoopRunner;
226 // Trimmed duplicate of IntrusiveDoubleLinkedList<T>
227 struct WatcherLinkedList
228 {
229 FolderWatcher* back = nullptr; // has no next
230 FolderWatcher* front = nullptr; // has no prev
231
232 void queueBack(FolderWatcher& watcher);
233 void remove(FolderWatcher& watcher);
234 };
235 WatcherLinkedList watchers;
236};
237
239} // 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:170
Represents a single folder being watched.
Definition FileSystemWatcher.h:129
Function< void(const Notification &)> notifyCallback
Function that will be called on a notification.
Definition FileSystemWatcher.h:136
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:108
StringSpan relativePath
Relative path of the file being notified from basePath
Definition FileSystemWatcher.h:110
Operation operation
Notification type.
Definition FileSystemWatcher.h:111
StringSpan basePath
Reference to the watched directory.
Definition FileSystemWatcher.h:109
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:41
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:101
@ 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