Being told when files in a folder are created, changed, moved or removed.
A File_Watcher watches folders (and, by default, everything below them) through the operating system's own
notifications: inotify on Linux, FSEvents on macOS and ReadDirectoryChangesW on Windows. Nothing runs in the
background for you: call process_changes from your own loop and it calls your callback for each change that
has settled. Changes to one path within a short window are merged into one File_Change with the events combined.
Other targets do not have this module.
Starts watching each folder in dir_paths and returns true when all of them were added. It stops at the first one that
cannot be watched (it is missing, is not a folder, or the system is out of watches) and returns false; the ones before it stay
watched. The failure is logged through context.logger.
Collects what the system has reported, calls the callback for every change whose merge window has passed, and returns
(changed, needs_wait, wait_seconds): whether any callback ran, whether more may come, and how long to wait before the next
call in the worst case.
Stops watching and frees everything the watcher holds, including changes that were found but not yet delivered, and
leaves watcher empty: it can be set up again with init, and a second deinit does nothing. Call it once for each
successful init. It is safe on a watcher that was never set up.
Watches folders for changes and calls a callback for them. User_Data is the type of the pointer handed to the callback; the
default void is for a watcher with none.
#import"Extensions/Environment";
#import"File";
#import"String";
Seen :: struct {
found: bool;
}
on_change :: (watcher: *File_Watcher(Seen), change: *File_Change, seen: *Seen) {
if path_filename(change.full_path) == "jai-doc-watched.txt" && (change.events & (.ADDED | .MODIFIED)) != 0 seen.found = true;
}
main :: () {
base := environment_variable("TMPDIR");
if base == "" base = "/tmp";
root := tprint("%/jai-doc-file-watcher", base);
file := tprint("%/jai-doc-watched.txt", root);
assert(make_directory_if_it_does_not_exist(root));
defer {
file_delete(file);
delete_directory(root);
}
seen: Seen;
watcher: File_Watcher(Seen);
assert(init(*watcher, on_change, *seen));
deferdeinit(*watcher);
assert(add_directories(*watcher, root));
assert(write_entire_file(file, "hello"));
for0..249 { // up to five seconds for the system to report itprocess_changes(*watcher);
if seen.found break;
sleep_milliseconds(20);
}
assert(seen.found);
}