// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "IDirectoryWatcher.h" #include #define EVENT_SIZE ( sizeof (struct inotify_event) ) #define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) ) class FDirectoryWatchRequestLinux { public: /** * Template class to support FString to TValueType maps with a case sensitive key */ template struct FCaseSensitiveLookupKeyFuncs : BaseKeyFuncs { static FORCEINLINE const FString& GetSetKey(const TPair& Element) { return Element.Key; } static FORCEINLINE bool Matches(const FString& A, const FString& B) { return A.Equals(B, ESearchCase::CaseSensitive); } static FORCEINLINE uint32 GetKeyHash(const FString& Key) { return FCrc::StrCrc32(*Key); } }; FDirectoryWatchRequestLinux(); virtual ~FDirectoryWatchRequestLinux(); /** Sets up the directory handle and request information */ bool Init(const FString& InDirectory, uint32 Flags); /** Adds a delegate to get fired when the directory changes */ FDelegateHandle AddDelegate( const IDirectoryWatcher::FDirectoryChanged& InDelegate, uint32 Flags ); /** Removes a delegate to get fired when the directory changes */ bool RemoveDelegate( FDelegateHandle InHandle ); /** Returns true if this request has any delegates listening to directory changes */ bool HasDelegates() const; /** Prepares the request for deletion */ void EndWatchRequest(); /** Triggers all pending file change notifications */ void ProcessPendingNotifications(); private: /** Adds watches for all files (and subdirectories) in a directory. */ void WatchDirectoryTree(const FString & RootAbsolutePath); /** Removes all watches from a */ void UnwatchDirectoryTree(const FString & RootAbsolutePath); FString Directory; bool bRunning; bool bEndWatchRequestInvoked; /** Whether or not watch subtree. */ bool bWatchSubtree; int FileDescriptor; /** Mapping from watch descriptors to their path names */ TMap WatchDescriptorsToPaths; /** Mapping from paths to watch descriptors */ TMap> PathsToWatchDescriptors; int NotifyFilter; /** A delegate with its corresponding IDirectoryWatcher::WatchOptions flags */ typedef TPair FWatchDelegate; TArray Delegates; /** Each FFileChangeData tracks whether it is a directory or not */ TArray> FileChanges; void Shutdown(); void ProcessChanges(); };