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
 Delivers notifications using Async (SC::AsyncEventLoop). 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 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, AsyncEventLoop &eventLoop)
 Setup watcher to receive async notifications on SC::AsyncEventLoop.
 
Result close ()
 Stops all watchers and frees the ThreadRunner or EventLoopRunner passed in init.
 
Result watch (FolderWatcher &watcher, StringView path)
 Starts watching a single directory, calling FolderWatcher::notifyCallback on file events.
 

Friends

decltype(internal) friend decltype(FolderWatcher::internal) IntrusiveDoubleLinkedList< FolderWatcherwatchers
 

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

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 Delivers notifications using Async (SC::AsyncEventLoop).

Example using SC::FileSystemWatcher::EventLoopRunner:

// Initialize the FileSystemWatcher
FileSystemWatcher fileSystemWatcher;
SC_TRY(fileSystemWatcher.init(eventLoopRunner, eventLoop));
// Setup notification callback
auto onFileModified = [&](const FileSystemWatcher::Notification& notification)
{
// This callback will be called from the thread calling AsyncEventLoop::run
StringView fullPath;
if (notification.getFullPath(buffer, fullPath))
{
switch (notification.operation)
{
case FileSystemWatcher::Operation::Modified: // File has been modified
console.print("Modified {} {}\n", notification.relativePath, fullPath);
break;
case FileSystemWatcher::Operation::AddRemoveRename: // File was added / removed
console.print("AddRemoveRename {} {}\n", notification.relativePath, fullPath);
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::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!
StringView fullPath;
if (notification.getFullPath(buffer, fullPath))
{
switch (notification.operation)
{
case FileSystemWatcher::Operation::Modified: // File has been modified
console.print("Modified {} {}\n", notification.relativePath, fullPath);
break;
case FileSystemWatcher::Operation::AddRemoveRename: // File was added / removed
console.print("AddRemoveRename {} {}\n", notification.relativePath, fullPath);
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());

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 ( )
nodiscard

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,
AsyncEventLoop & eventLoop )
nodiscard

Setup watcher to receive async notifications on SC::AsyncEventLoop.

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

◆ init() [2/2]

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

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,
StringView path )
nodiscard

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: