FileWatcherBase.h 4.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #if !defined(Q_MOC_RUN)
  10. #include <QObject>
  11. #include <QString>
  12. #endif
  13. namespace AssetBuilderSDK
  14. {
  15. class FilePatternMatcher;
  16. }
  17. //////////////////////////////////////////////////////////////////////////
  18. //! FileWatcherBase
  19. /*! Base class that handles creation and deletion of FolderRootWatches.
  20. * This API has the following guarantees:
  21. * - you will ALWAYS get fileAdded for every file and every folder added in a watched folder (assuming recursive), and this holds true
  22. * no matter the timing, as long as the folder to watch was added before calling StartWatching.
  23. * - This holds true even for files or folders created immediately inside a folder that was also just created.
  24. * - You will receive all events in the order that they occur on the file system.
  25. * - One exception to this - Rapidly interleaving creation of files with creation of folders can cause the file create
  26. * notifications to occur
  27. * later than the folder create notifications. The folder containing a new file will always precede the new file in it.
  28. * - you will NOT necessarily get fileRemoved for files when the folder containing them is moved or renamed.
  29. * (Operating systems tend to just unlink or rename the folder and not generate file events for things inside the folder).
  30. * - you will NOT necessarily get fileModified if rapidly creating new folders, creating new files in that folder, and then modifying
  31. * the files.
  32. * all in a very short time. You will still get a fileAdded for each folder and file and you will still always get the folders before
  33. * the files in them.
  34. * - you may get fileModified MULTIPLE times including for each file created or each modification done. This is because each operating
  35. * system
  36. * treats file modify differently, and in some cases, creating a file modifies its metadata (security attributes, size, ...) and that
  37. * counts as a modify. likewise, touching the data of a file counts as multiple things being modified (size, content, attributes,
  38. * modification time) and the OS may issue each of those as separate modify events, with no way to tell them apart.
  39. * */
  40. class FileWatcherBase : public QObject
  41. {
  42. Q_OBJECT
  43. public:
  44. virtual void AddFolderWatch(QString directory, bool recursive = true) = 0;
  45. virtual void ClearFolderWatches() = 0;
  46. virtual void StartWatching() = 0;
  47. virtual void StopWatching() = 0;
  48. //! Note that on some platforms, it is cheaper to exclude folders by not watching for
  49. //! events in the first place, but in other platforms, watching is a file system level
  50. //! operation that recurses into every sub-folder without consuming extra resources.
  51. //! It is up to the platform implementation to use the IsExcluded as they see fit.
  52. //! The API will never issue a file signal on something that matches an exclusion.
  53. virtual void AddExclusion(const AssetBuilderSDK::FilePatternMatcher& excludeMatch) = 0;
  54. virtual bool IsExcluded(QString filePath) const = 0;
  55. //! Installs all the default exclusion rules. Exclusions are somewhat expensive and happens
  56. //! inside a OS callback that is time sensitive, so this installs just a few specific known
  57. //! exclusions for cases that usually result in a deep file heirarchy of things that ought to be
  58. //! excluded - the cache folder, the user/log folder, etc.
  59. //! Paths for the params that are empty will cause no rules to be installed for that path or children.
  60. virtual void InstallDefaultExclusionRules(QString cacheRootPath, QString projectRootPath) = 0;
  61. Q_SIGNALS:
  62. // These signals are emitted when a file under a watched path changes
  63. void fileAdded(QString filePath);
  64. void fileRemoved(QString filePath);
  65. void fileModified(QString filePath);
  66. // These signals are emitted by the platform implementations when files
  67. // change. Some platforms' file watch APIs do not support non-recursive
  68. // watches, so the signals are filtered before being forwarded to the
  69. // non-"raw" fileAdded/Removed/Modified signals above.
  70. void rawFileAdded(QString filePath, QPrivateSignal);
  71. void rawFileRemoved(QString filePath, QPrivateSignal);
  72. void rawFileModified(QString filePath, QPrivateSignal);
  73. };