Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
SC::FileSystemWatcher Struct Reference

Notifies about events (add, remove, rename, modified) on files and directories. More...

#include <FileSystemWatcher.h>

Classes

struct  EventLoopRunner
 Abstract class to use event loop notifications (see SC::FileSystemWatcherAsync). More...
 
struct  FolderWatcher
 Represents a single folder being watched. More...
 
struct  Notification
 Notification holding type and path. More...
 

Public Types

enum class  Operation {
  Modified ,
  AddRemoveRename
}
 Specifies the event classes. More...
 
using InternalOpaque = OpaqueObject<InternalDefinition>
 
using ThreadRunner = OpaqueObject<ThreadRunnerDefinition>
 Delivers notifications on a background thread.
 

Public Member Functions

Result init (ThreadRunner &runner)
 Setup watcher to receive notifications from a background thread.
 
Result init (EventLoopRunner &runner)
 Setup watcher to receive async notifications on an event loop.
 
Result close ()
 Stops all watchers and frees the ThreadRunner or EventLoopRunner passed in init.
 
Result watch (FolderWatcher &watcher, StringSpan path)
 Starts watching a single directory, calling FolderWatcher::notifyCallback on file events.
 
void asyncNotify (FolderWatcher *watcher)
 

Friends

decltype(internal) friend decltype(FolderWatcher::internal) friend struct EventLoopRunner
 

Detailed Description

Notifies about events (add, remove, rename, modified) on files and directories.

Caller can specify a callback for receiving notifications the SC::FileSystemWatcher::watch method.

Changes are grouped in two categories:

  • Added, removed and renamed files and directories
  • Modified files
Warning
Modifications to files that do not affect directory entries may not trigger notifications.
This includes modifications made through symbolic or hard links located outside the watched directory, pointing to a file of the watched directory.
Modifications made through memory-mapped file operations (mmap) can also exhibit the same behaviour.
The underlying OS APIs monitor directory entries rather than all possible file access methods.

There are two modes in which FileSystemWatcher can be initialized, defining how notifications are delivered:

Mode Description
SC::FileSystemWatcher::ThreadRunner Delivers notifications on a background thread.
SC::FileSystemWatcher::EventLoopRunner Abstract class to use event loop notifications (see SC::FileSystemWatcherAsync).

Example using SC::FileSystemWatcher::ThreadRunner:

// Initialize the FileSystemWatcher
FileSystemWatcher::ThreadRunner threadRunner; // <--- The thread runner
FileSystemWatcher fileSystemWatcher;
SC_TRY(fileSystemWatcher.init(threadRunner));
// Setup notification callback
auto onFileModified = [&](const FileSystemWatcher::Notification& notification)
{
// Warning! This callback is called from a background thread!
// Make sure to do proper synchronization!
StringPath fullPath;
if (notification.getFullPath(fullPath))
{
switch (notification.operation)
{
case FileSystemWatcher::Operation::Modified: // File has been modified
console.print("Modified {} {}\n", notification.relativePath, fullPath.view());
break;
case FileSystemWatcher::Operation::AddRemoveRename: // File was added / removed
console.print("AddRemoveRename {} {}\n", notification.relativePath, fullPath.view());
break;
}
}
};
// Start watching a specific folder
folderWatcher.notifyCallback = onFileModified;
SC_TRY(fileSystemWatcher.watch(folderWatcher, "/path/to/dir"));
// ...
// At a later point when there is no more need of watching the folder
SC_TRY(folderWatcher.stopWatching());
// ...
// When all watchers have been unwatched and to dispose all system resources
SC_TRY(fileSystemWatcher.close());

Example using SC::FileSystemWatcherAsync (that implements SC::FileSystemWatcher::EventLoopRunner):

// Initialize the FileSystemWatcher
FileSystemWatcher fileSystemWatcher;
FileSystemWatcherAsync eventLoopRunner;
eventLoopRunner.init(eventLoop);
SC_TRY(fileSystemWatcher.init(eventLoopRunner));
// Setup notification callback
auto onFileModified = [&](const FileSystemWatcher::Notification& notification)
{
// This callback will be called from the thread calling AsyncEventLoop::run
StringPath fullPath;
if (notification.getFullPath(fullPath))
{
switch (notification.operation)
{
case FileSystemWatcher::Operation::Modified: // File has been modified
console.print("Modified {} {}\n", notification.relativePath, fullPath.view());
break;
case FileSystemWatcher::Operation::AddRemoveRename: // File was added / removed
console.print("AddRemoveRename {} {}\n", notification.relativePath, fullPath.view());
break;
}
}
};
// Start watching a specific folder
folderWatcher.notifyCallback = onFileModified;
SC_TRY(fileSystemWatcher.watch(folderWatcher, "/path/to/dir"));
// ...
// At a later point when there is no more need of watching the folder
SC_TRY(folderWatcher.stopWatching());
// ...
// When all watchers have been unwatched and to dispose all system resources
SC_TRY(fileSystemWatcher.close());

[OpaqueDeclarationSnippet]

Member Typedef Documentation

◆ ThreadRunner

using SC::FileSystemWatcher::ThreadRunner = OpaqueObject<ThreadRunnerDefinition>

Delivers notifications on a background thread.

Member Enumeration Documentation

◆ Operation

Specifies the event classes.

Some events are grouped in a single one because it's non-trivial providing precise notifications that are consistent across platforms.

Enumerator
Modified 

A file or directory has been modified in its contents and/or timestamp.

AddRemoveRename 

A file or directory has been added, removed or renamed.

Member Function Documentation

◆ close()

Result SC::FileSystemWatcher::close ( )

Stops all watchers and frees the ThreadRunner or EventLoopRunner passed in init.

Returns
Valid Result if resources have been freed successfully

◆ init() [1/2]

Result SC::FileSystemWatcher::init ( EventLoopRunner & runner)

Setup watcher to receive async notifications on an event loop.

Parameters
runnerAddress of a EventLoopRunner object that must be valid until close()
Returns
Valid Result if the watcher has been initialized correctly

◆ init() [2/2]

Result SC::FileSystemWatcher::init ( ThreadRunner & runner)

Setup watcher to receive notifications from a background thread.

Parameters
runnerAddress of a ThreadRunner object that must be valid until close()
Returns
Valid Result if the watcher has been initialized correctly

◆ watch()

Result SC::FileSystemWatcher::watch ( FolderWatcher & watcher,
StringSpan path )

Starts watching a single directory, calling FolderWatcher::notifyCallback on file events.

Parameters
watcherReference to a (not already used) watcher, with a valid FolderWatcher::notifyCallback. Its address must not change until FolderWatcher::stopWatching or FileSystemWatcher::close
pathThe directory being monitored
Returns
Valid Result if directory is accessible and the watcher is initialized properly.

The documentation for this struct was generated from the following file: