Plasma Engine  2.0
Loading...
Searching...
No Matches
FileSystemWatcher.h
1#pragma once
2
3#include <ToolsFoundation/ToolsFoundationDLL.h>
4
5#if PL_ENABLED(PL_SUPPORTS_DIRECTORY_WATCHER)
6
7# include <Foundation/Application/Config/FileSystemConfig.h>
8# include <Foundation/IO/DirectoryWatcher.h>
9# include <Foundation/Threading/TaskSystem.h>
10
11class plTask;
12
14struct plFileSystemWatcherEvent
15{
16 enum class Type
17 {
18 FileAdded,
19 FileRemoved,
20 FileChanged,
21 DirectoryAdded,
22 DirectoryRemoved,
23 };
24
25 plStringView m_sPath;
26 Type m_Type;
27};
28
30class PL_TOOLSFOUNDATION_DLL plFileSystemWatcher
31{
32public:
33 plFileSystemWatcher(const plApplicationFileSystemConfig& fileSystemConfig);
34 ~plFileSystemWatcher();
35
37 void Initialize();
38
40 void Deinitialize();
41
43 void MainThreadTick();
44
45public:
47
48private:
49 // On file move / rename operations we want the new file to be seen first before the old file delete event so that we can correctly detect this as a move instead of a delete operation. We achieve this by delaying each event by a fixed number of frames.
50 static constexpr plUInt32 s_AddedFrameDelay = 5;
51 static constexpr plUInt32 s_RemovedFrameDelay = 10;
52 // Sometimes moving a file triggers a modified event on the old file. To prevent this from triggering the removal to be seen before the addition, we also delay modified events by the same amount as remove events.
53 static constexpr plUInt32 s_ModifiedFrameDelay = 10;
54
55 struct WatcherResult
56 {
57 plString m_sFile;
58 plDirectoryWatcherAction m_Action;
59 plDirectoryWatcherType m_Type;
60 };
61
62 struct PendingUpdate
63 {
64 plString m_sAbsPath;
65 plUInt32 m_uiFrameDelay = 0;
66 };
67
69 void HandleWatcherChange(const WatcherResult& res);
71 void NotifyChanges();
73 void AddEntry(plDynamicArray<PendingUpdate>& container, const plStringView sAbsPath, plUInt32 uiFrameDelay);
75 void ConsumeEntry(plDynamicArray<PendingUpdate>& container, plFileSystemWatcherEvent::Type type, const plDelegate<void(const plString& sAbsPath, plFileSystemWatcherEvent::Type type)>& consume);
76
77private:
78 // Immutable data after StartInitialize
79 plApplicationFileSystemConfig m_FileSystemConfig;
80
81 // Watchers
82 mutable plMutex m_WatcherMutex;
84 plSharedPtr<plTask> m_pWatcherTask;
85 plSharedPtr<plTask> m_pNotifyTask;
86 plTaskGroupID m_WatcherGroup;
87 plTaskGroupID m_NotifyGroup;
88 plAtomicBool m_bShutdown = false;
89
90 // Pending ops
94 plHybridArray<PendingUpdate, 4> m_DirectoryAdded;
95 plHybridArray<PendingUpdate, 4> m_DirectoryRemoved;
96};
97
98#endif
Definition FileSystemConfig.h:8
An atomic boolean variable. This is just a wrapper around an atomic int32 for convenience.
Definition AtomicInteger.h:100
Definition DynamicArray.h:81
Definition Event.h:177
A hybrid array uses in-place storage to handle the first few elements without any allocation....
Definition HybridArray.h:12
Provides a simple mechanism for mutual exclusion to prevent multiple threads from accessing a shared ...
Definition Mutex.h:13
A Shared ptr manages a shared object and destroys that object when no one references it anymore....
Definition SharedPtr.h:10
plStringView represent a read-only sub-string of a larger string, as it can store a dedicated string ...
Definition StringView.h:34
Given out by plTaskSystem::CreateTaskGroup to identify a task group.
Definition TaskSystemDeclarations.h:103
Base class for custom tasks.
Definition Task.h:10
A generic delegate class which supports static functions and member functions.
Definition Delegate.h:76