Skip to content

Commit c16e8a8

Browse files
authored
Merge pull request #37 from PipeRift/feature/custom-file-watching
Custom File Watchers
2 parents 89a62f8 + 641e492 commit c16e8a8

File tree

13 files changed

+1867
-576
lines changed

13 files changed

+1867
-576
lines changed

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
[submodule "Extern/Bandit"]
22
path = Extern/Bandit
33
url = https://github.com/banditcpp/bandit.git
4-
[submodule "Extern/efsw"]
5-
path = Extern/efsw
6-
url = https://github.com/SpartanJ/efsw.git

CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ file(GLOB_RECURSE PIPE_SOURCE_FILES CONFIGURE_DEPENDS Src/*.cpp Src/*.h)
6767
target_sources(Pipe PRIVATE ${PIPE_SOURCE_FILES})
6868
target_compile_definitions(Pipe PRIVATE NOMINMAX)
6969

70-
target_link_libraries(Pipe PRIVATE
71-
efsw
72-
)
73-
7470
if(PIPE_ENABLE_ALLOCATION_STACKS)
7571
target_compile_definitions(Pipe PUBLIC P_ENABLE_ALLOCATION_STACKS=0)
7672
endif()

Extern/CMakeLists.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,3 @@ set(EFSW_INSTALL OFF)
55

66
add_library(Bandit INTERFACE)
77
target_include_directories(Bandit INTERFACE Bandit)
8-
9-
add_subdirectory(efsw)
10-
pipe_target_disable_all_warnings(efsw PRIVATE)
11-
if(PLATFORM_LINUX)
12-
set_target_properties(efsw PROPERTIES POSITION_INDEPENDENT_CODE ON)
13-
endif()

Extern/efsw

Lines changed: 0 additions & 1 deletion
This file was deleted.

Include/Pipe/Core/MacPlatform.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ namespace p
3131
} // namespace p
3232

3333
#if __is_target_arch(arm64) || __is_target_arch(arm64e)
34-
#define P_PLATFORM_MAC_ARM64 1
35-
#define P_PLATFORM_MAC_X86 0
34+
#define P_PLATFORM_MACOS_ARM64 1
35+
#define P_PLATFORM_MACOS_X86 0
3636
#else
37-
#define P_PLATFORM_MAC_ARM64 0
38-
#define P_PLATFORM_MAC_X86 1
37+
#define P_PLATFORM_MACOS_ARM64 0
38+
#define P_PLATFORM_MACOS_X86 1
3939
#endif
4040

4141

@@ -46,7 +46,7 @@ namespace p
4646
#endif
4747
#define P_NOINLINE __attribute__((noinline))
4848

49-
#if P_PLATFORM_MAC_X86
49+
#if P_PLATFORM_MACOS_X86
5050
#define P_PLATFORM_BREAK() __asm__("int $3")
5151
#else
5252
#define P_PLATFORM_BREAK() __builtin_debugtrap()

Include/Pipe/Core/Platform.h

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
#pragma once
44

55
#ifndef P_PLATFORM_WINDOWS
6-
#if defined(_WIN64)
7-
#define P_PLATFORM_WINDOWS 1
8-
#elif defined(_WIN32)
6+
#if defined(_WIN64) || defined(_WIN32)
97
#define P_PLATFORM_WINDOWS 1
108
#else
119
#define P_PLATFORM_WINDOWS 0
@@ -14,18 +12,40 @@
1412
#ifndef P_PLATFORM_LINUX
1513
#if defined(__linux__)
1614
#define P_PLATFORM_LINUX 1
15+
#if defined(__ANDROID__) || defined(ANDROID)
16+
#define P_PLATFORM_ANDROID 1
17+
#endif
1718
#else
1819
#define P_PLATFORM_LINUX 0
20+
#define P_PLATFORM_ANDROID 0
1921
#endif
2022
#endif
21-
#ifndef P_PLATFORM_MACOS
22-
#if defined(__APPLE__)
23-
#define P_PLATFORM_MACOS 1
23+
#ifndef P_PLATFORM_APPLE
24+
#if defined(__APPLE__) || defined(__APPLE_CC__)
25+
#define P_PLATFORM_APPLE 1
26+
#if defined(__IPHONE__) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) \
27+
|| (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR)
28+
#define P_PLATFORM_IOS 1
29+
#define P_PLATFORM_MACOS 0
30+
#else
31+
#define P_PLATFORM_MACOS 1
32+
#define P_PLATFORM_IOS 0
33+
#endif
2434
#else
35+
#define P_PLATFORM_APPLE 0
2536
#define P_PLATFORM_MACOS 0
37+
#define P_PLATFORM_IOS 0
2638
#endif
2739
#endif
2840

41+
#ifndef P_PLATFORM_BSD
42+
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
43+
|| defined(__DragonFly__)
44+
#define P_PLATFORM_BSD 1
45+
#else
46+
#define P_PLATFORM_BSD 0
47+
#endif
48+
#endif
2949

3050
#if P_PLATFORM_WINDOWS
3151
#include "Pipe/Core/WindowsPlatform.h"

Include/Pipe/Files/LambdaFileIterator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace p
88
{
9-
template<typename Iterator = PathIterator>
9+
template<typename Iterator = DirectoryIterator>
1010
class LambdaFileIterator
1111
{
1212
public:

Include/Pipe/Files/Paths.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ namespace p
6464

6565
PIPE_API bool IsAbsolutePath(StringView path);
6666
PIPE_API bool IsRelativePath(StringView path);
67+
PIPE_API bool IsRemotePath(StringView path);
6768
PIPE_API bool Exists(StringView path);
6869

6970
PIPE_API String JoinPaths(StringView base, StringView relative);
@@ -108,4 +109,75 @@ namespace p
108109

109110
PIPE_API String ToString(const Path& path);
110111
PIPE_API std::filesystem::path ToSTDPath(StringView pathStr);
112+
113+
114+
#pragma region PathIterator
115+
struct PathIterator
116+
{
117+
enum class State : u8
118+
{
119+
// Zero is a special sentinel value used by default constructed iterators.
120+
BeforeBegin,
121+
InRootName,
122+
InRootDir,
123+
InFilenames,
124+
InTrailingSep,
125+
AtEnd
126+
};
127+
128+
const StringView path;
129+
StringView rawEntry;
130+
State state;
131+
132+
private:
133+
PathIterator(StringView path, State state) noexcept : path(path), state(state) {}
134+
135+
public:
136+
PathIterator(StringView path, StringView entry, State state)
137+
: path(path), rawEntry(entry), state(state)
138+
{
139+
// S cannot be '0' or BeforeBegin.
140+
}
141+
142+
static PathIterator CreateBegin(StringView p) noexcept;
143+
static PathIterator CreateEnd(StringView p) noexcept;
144+
145+
const TChar* Peek() const noexcept;
146+
void Increment() noexcept;
147+
void Decrement() noexcept;
148+
149+
/** @return a view with the "preferred representation" of the current
150+
* element. For example trailing separators are represented as a '.'
151+
*/
152+
StringView operator*() const noexcept;
153+
explicit operator bool() const noexcept;
154+
PathIterator& operator++() noexcept;
155+
PathIterator& operator--() noexcept;
156+
bool operator==(const PathIterator& other) const noexcept;
157+
bool operator!=(const PathIterator& other) const noexcept;
158+
159+
bool AtEnd() const noexcept;
160+
bool InRootDir() const noexcept;
161+
bool InRootName() const noexcept;
162+
bool InRootPath() const noexcept;
163+
164+
private:
165+
void MakeState(State newState, const TChar* start, const TChar* end) noexcept;
166+
void MakeState(State newState) noexcept;
167+
const TChar* GetAfterBack() const noexcept;
168+
const TChar* GetBeforeFront() const noexcept;
169+
/// @return a pointer to the first character after the currently lexed element.
170+
const TChar* GetNextTokenStartPos() const noexcept;
171+
/// @return a pointer to the first character in the currently lexed element.
172+
const TChar* GetCurrentTokenStartPos() const noexcept;
173+
// Consume all consecutive separators
174+
const TChar* ConsumeAllSeparators(const TChar* p, const TChar* end) const noexcept;
175+
// Consume exactly N separators, or return nullptr.
176+
const TChar* ConsumeNSeparators(const TChar* p, const TChar* end, int N) const noexcept;
177+
const TChar* ConsumeName(const TChar* p, const TChar* end) const noexcept;
178+
const TChar* ConsumeDriveLetter(const TChar* p, const TChar* end) const noexcept;
179+
const TChar* ConsumeNetworkRoot(const TChar* p, const TChar* end) const noexcept;
180+
const TChar* ConsumeRootName(const TChar* p, const TChar* end) const noexcept;
181+
};
182+
#pragma endregion PathIterator
111183
} // namespace p

Include/Pipe/Files/STDFileSystem.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ namespace p
1919
using Path = fs::path;
2020
using PathView = TStringView<Path::value_type>;
2121

22-
using PathIterator = fs::directory_iterator;
23-
using RecursivePathIterator = fs::recursive_directory_iterator;
24-
using SpaceInfo = fs::space_info;
22+
using DirectoryIterator = fs::directory_iterator;
23+
using RecursiveDirectoryIterator = fs::recursive_directory_iterator;
24+
using SpaceInfo = fs::space_info;
2525

2626
enum class CopyOptions
2727
{
@@ -54,6 +54,6 @@ namespace p
5454
PIPE_API void Read(p::Reader& ct, p::Path& value);
5555
PIPE_API void Write(p::Writer& ct, const p::Path& value);
5656

57-
PIPE_API PathIterator CreatePathIterator(StringView path);
58-
PIPE_API RecursivePathIterator CreateRecursivePathIterator(StringView path);
57+
PIPE_API DirectoryIterator CreateDirIterator(StringView path);
58+
PIPE_API RecursiveDirectoryIterator CreateRecursiveDirIterator(StringView path);
5959
} // namespace p

Include/PipeFiles.h

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,6 @@
1010

1111
namespace p
1212
{
13-
#pragma region FileWatch
14-
enum class FileWatchAction : p::u8
15-
{
16-
Add = 1,
17-
Delete = 2,
18-
Modified = 3,
19-
Moved = 4
20-
};
21-
22-
using FileListenerId = long;
23-
using FileWatchCallback = std::function<void(
24-
StringView path, StringView filename, FileWatchAction action, StringView oldFilename)>;
25-
26-
struct PIPE_API FileWatcher
27-
{
28-
private:
29-
OwnPtr fileWatcher;
30-
p::TArray<TOwnPtr<struct FileWatchListener>> listeners;
31-
32-
public:
33-
FileWatcher();
34-
~FileWatcher();
35-
FileWatcher(const FileWatcher& other) = delete;
36-
FileWatcher& operator=(const FileWatcher& other) = delete;
37-
38-
FileListenerId ListenPath(StringView path, bool recursive, FileWatchCallback callback);
39-
void StopListening(FileListenerId id);
40-
void Reset();
41-
42-
void StartAsync();
43-
};
44-
#pragma endregion FileWatch
45-
46-
4713
#pragma region FileDialogs
4814
using DialogFileFilter = TPair<StringView, StringView>;
4915

@@ -104,4 +70,48 @@ namespace p
10470
},
10571
bool alwaysShowDefaultPath = false, bool confirmOverwrite = false);
10672
#pragma endregion FileDialogs
73+
74+
75+
#pragma region FileWatch
76+
enum class FileWatchAction : p::u8
77+
{
78+
Add = 1,
79+
Delete = 2,
80+
Modified = 3,
81+
Moved = 4
82+
};
83+
84+
using FileWatchId = i32;
85+
using FileWatchCallback = std::function<void(FileWatchId id, StringView path,
86+
StringView filename, FileWatchAction action, StringView oldFilename)>;
87+
88+
struct PIPE_API FileWatcher
89+
{
90+
public:
91+
/** Should recursive watchers follow symbolic links? Default: false */
92+
bool followsSymlinks = false;
93+
94+
/** Allow symlinks to watch recursively out of the pointed directory. Default: false.
95+
* 'followsSymlinks' must be enabled.
96+
* E.g: A symlink from '/home/folder' to '/'. With 'followsSymlinks=false' only '/home' and
97+
* deeper are allowed. Set to false it will prevent infinite recursion.
98+
*/
99+
bool allowsOutOfScopeLinks = false;
100+
101+
private:
102+
OwnPtr fileWatcher;
103+
104+
public:
105+
FileWatcher(bool useGeneric = false);
106+
~FileWatcher();
107+
FileWatcher(const FileWatcher& other) = delete;
108+
FileWatcher& operator=(const FileWatcher& other) = delete;
109+
110+
FileWatchId ListenPath(StringView path, bool recursive, FileWatchCallback callback);
111+
void StopListening(FileWatchId id);
112+
void Reset();
113+
114+
void StartWatchingAsync();
115+
};
116+
#pragma endregion FileWatch
107117
}; // namespace p

0 commit comments

Comments
 (0)