Skip to content

Commit 9519b06

Browse files
committed
[3/3] Generic File Watcher
1 parent 1882e0d commit 9519b06

File tree

3 files changed

+63
-32
lines changed

3 files changed

+63
-32
lines changed

Include/Pipe/Files/Paths.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ namespace p
153153
explicit operator bool() const noexcept;
154154
PathIterator& operator++() noexcept;
155155
PathIterator& operator--() noexcept;
156+
bool operator==(const PathIterator& other) const noexcept;
157+
bool operator!=(const PathIterator& other) const noexcept;
156158

157159
bool AtEnd() const noexcept;
158160
bool InRootDir() const noexcept;

Src/Files/Paths.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -795,6 +795,24 @@ namespace p
795795
return *this;
796796
}
797797

798+
bool PathIterator::operator==(const PathIterator& other) const noexcept
799+
{
800+
if (path == other.path && state == other.state)
801+
{
802+
if (state == State::InRootName || state == State::InFilenames)
803+
{
804+
return rawEntry == other.rawEntry;
805+
}
806+
return true;
807+
}
808+
return false;
809+
}
810+
811+
bool PathIterator::operator!=(const PathIterator& other) const noexcept
812+
{
813+
return !operator==(other);
814+
}
815+
798816
bool PathIterator::AtEnd() const noexcept
799817
{
800818
return state == State::AtEnd;

Src/PipeFiles.cpp

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
#include "Pipe/Extern/portable-file-dialogs.h"
1010
#include "Pipe/Files/Paths.h"
1111

12-
#include <efsw/efsw.hpp>
1312
#include <shared_mutex>
1413

1514

@@ -273,6 +272,7 @@ namespace p
273272
}
274273

275274
void Init(StringView path);
275+
void SetPath(StringView newPath);
276276
bool Exists();
277277
void Scan(DirectorySnapshotDiff& diff);
278278
FileStatusMap::Iterator NodeInFiles(FileStatus& fi);
@@ -286,11 +286,36 @@ namespace p
286286
void DeleteAll(DirectorySnapshotDiff& diff);
287287
};
288288

289+
void DirectorySnapshotDiff::Clear()
290+
{
291+
filesCreated.Clear();
292+
filesModified.Clear();
293+
filesMoved.Clear();
294+
filesDeleted.Clear();
295+
dirsCreated.Clear();
296+
dirsModified.Clear();
297+
dirsMoved.Clear();
298+
dirsDeleted.Clear();
299+
}
300+
301+
bool DirectorySnapshotDiff::Changed()
302+
{
303+
return !filesCreated.IsEmpty() || !filesModified.IsEmpty() || !filesMoved.IsEmpty()
304+
|| !filesDeleted.IsEmpty() || !dirsCreated.IsEmpty() || !dirsModified.IsEmpty()
305+
|| !dirsMoved.IsEmpty() || !dirsDeleted.IsEmpty();
306+
}
307+
308+
289309
void DirectorySnapshot::Init(StringView newPath)
310+
{
311+
SetPath(newPath);
312+
InitFiles();
313+
}
314+
315+
void DirectorySnapshot::SetPath(StringView newPath)
290316
{
291317
path = String{newPath};
292318
pathFileState = GetFileStatus(path);
293-
InitFiles();
294319
}
295320

296321
bool DirectorySnapshot::Exists()
@@ -720,9 +745,8 @@ namespace p
720745
/// Is this a recursive watch?
721746
if (watch->path != path)
722747
{
723-
if (!(path.size()
724-
&& (path.at(0) == FileSystem::getOSSlash()
725-
|| path.at(path.size() - 1) == FileSystem::getOSSlash())))
748+
if (path.empty()
749+
|| (!IsSeparator(path.at(0)) && !IsSeparator(path.at(path.size() - 1))))
726750
{
727751
/// Get the real directory
728752
if (parent)
@@ -736,7 +760,7 @@ namespace p
736760
}
737761
}
738762

739-
dirSnap.SetDirectoryInfo(pathTmp);
763+
dirSnap.SetPath(pathTmp);
740764
}
741765

742766
void GenericDirWatch::HandleAction(
@@ -783,7 +807,8 @@ namespace p
783807
}
784808
else
785809
{
786-
dir = link;
810+
path = link;
811+
dir = Tag{link};
787812
}
788813
}
789814
else
@@ -898,36 +923,22 @@ namespace p
898923
path = path.substr(dirSnap.path.size() - 1);
899924
}
900925

901-
if (path.size() == 1)
902-
{
903-
P_Check(path[0] == FileSystem::getOSSlash());
904-
return this;
905-
}
906-
907-
size_t level = 0;
908-
std::vector<String> dirv = String::split(path, FileSystem::getOSSlash(), false);
909-
910926
GenericDirWatch* dirWatcher = this;
911-
912-
while (level < dirv.size())
927+
const PathIterator dirEnd = PathIterator::CreateEnd(path);
928+
for (auto dirIt = PathIterator::CreateBegin(path); dirIt != dirEnd; ++dirIt)
913929
{
914930
// search the dir level in the current watcher
915-
auto it = dirWatcher->directories.FindIt(Tag{dirv[level]});
931+
auto it = dirWatcher->directories.FindIt(Tag{*dirIt});
916932

917-
// found? continue with the next level
918-
if (it != dirWatcher->directories.end())
919-
{
920-
dirWatcher = it->second;
921-
++level;
922-
}
923-
else
933+
if (it == dirWatcher->directories.end())
924934
{
925935
// couldn't found the folder level?
926936
// directory not watched
927937
return nullptr;
928938
}
939+
// found? continue with the next level
940+
dirWatcher = it->second;
929941
}
930-
931942
return dirWatcher;
932943
}
933944

@@ -1271,7 +1282,7 @@ namespace p
12711282
else
12721283
{
12731284
fileWatcher = MakeOwned<DefaultFileWatcher>(this);
1274-
if (!fileWatcher.Get<BaseFileWatcher>()
1285+
if (!fileWatcher.GetUnsafe<BaseFileWatcher>()
12751286
->IsInitialized()) // Fallback to generic file watcher
12761287
{
12771288
p::Warning("Initialization of OS file watcher failed. Fallback to generic.");
@@ -1286,22 +1297,22 @@ namespace p
12861297

12871298
void FileWatcher::StartWatchingAsync()
12881299
{
1289-
fileWatcher.Get<BaseFileWatcher>()->Watch();
1300+
fileWatcher.GetUnsafe<BaseFileWatcher>()->Watch();
12901301
}
12911302

12921303
FileWatchId FileWatcher::ListenPath(StringView path, bool recursive, FileWatchCallback callback)
12931304
{
1294-
return fileWatcher.Get<BaseFileWatcher>()->AddWatch(path, Move(callback), recursive);
1305+
return fileWatcher.GetUnsafe<BaseFileWatcher>()->AddWatch(path, Move(callback), recursive);
12951306
}
12961307

12971308
void FileWatcher::StopListening(FileWatchId id)
12981309
{
1299-
fileWatcher.Get<BaseFileWatcher>()->RemoveWatch(id);
1310+
fileWatcher.GetUnsafe<BaseFileWatcher>()->RemoveWatch(id);
13001311
}
13011312

13021313
void FileWatcher::Reset()
13031314
{
1304-
fileWatcher.Get<BaseFileWatcher>()->RemoveAllWatches();
1315+
fileWatcher.GetUnsafe<BaseFileWatcher>()->RemoveAllWatches();
13051316
}
13061317
#pragma endregion FileWatch
13071318
} // namespace p

0 commit comments

Comments
 (0)