edelib  2.1.0
Public Member Functions | Static Public Member Functions | List of all members
DirWatch Class Reference

Directory changes notifier. More...

#include <edelib/DirWatch.h>

Public Member Functions

 DirWatch ()
 ~DirWatch ()

Static Public Member Functions

static bool init (void)
static void shutdown (void)
static bool add (const char *dir, int flags)
static bool remove (const char *dir)
static void callback (DirWatchCallback &cb, void *data=0)
static DirWatchNotifier notifier (void)

Detailed Description

Directory changes notifier.

DirWatch can be used to monitor certain directories for their content changes (their files). Those changes can be creating, removing, altering or attributes changes.

DirWatch can't be used to monitor files directly; use directory where file belongs to.

To accept events, you should initialize DirWatch, add appropriate directories with desired notification flags and register callback. That callback will be called when event occured on target directory with appropriate filled parameters. Some of the parameters can be NULL or -1, depending if DirWatch was able to figure out what was happened.

After initialization, application should go into loop state so it can listen and receive events. This is not a problem for GUI applications since they already use event loops.

DirWatch relies on FLTK loop, and in case of non GUI application, Fl::wait() still has to be used.

This is sample:

* // our callback
* void notify_cb(const char* dir, const char* what_changed, int flags, void*) {
* if(what_changed && flag != -1)
* printf("Content of %s changed: %s was changed with %i flag\n", dir, what_changed, flag);
* else
* printf("Content of %s changed", dir);
* }
* // somewhere in the code
* // check creating/deleting
* if(!DirWatch::add("/some/directory1", DW_CREATE | DW_DELETE))
* printf("Fatal, can't monitor /some/directory1\n");
* // check any modify
* if(!DirWatch::add("/some/directory2", DW_MODIFY))
* printf("Fatal, can't monitor /some/directory2\n");
* // callback called when something was changed
* DirWatch::callback(notify_cb);
* // go into loop
* while(1) {
* // here we restart loop each 5 seconds
* Fl::wait(5);
* }
* //... and when application is done, shutdown() will clear allocated data

You must call init() before further calls or assertion will pop up.

Events can be reported multiple times, one after one (thus calling callback) depending what DirWatchFlags is selected. For example, selecting DW_CREATE|DW_ATTRIB will call callback probably three times when new file in watched directory is created; one for creating and other two for attributes changes. This mostly depends on the way how file is created. Final application should be prepared for this.

When DirWatch was not able to figure out what was changed, what_changed could be set to NULL or flag could be set -1, like:

* void notify_cb(const char* dir, const char* what_changed, int flag) {
* // what_changed can be NULL or name of changed file if succeded
* // flag can be -1 if failed or one of DirWatchFlags if succeded
* ...
* }

When tracking events, at first sight some reports will look odd or maybe wrong; this is related to program/whatever that cause this event. Eg. when you open some file for editing with vim (probably other editors), you will often get DW_CREATE/DW_DELETE events since vim creates another temporary file, copy old content in it, modify it and move it to file you supposed to edit.

Removing registered directories is done with remove(), but given directory name must be equal to one passed to add(), like:

* DirWatch::add("/home/baz");
* // fine, remove it
* DirWatch::remove("/home/baz");
* // note ending slash, it will not be removed since does not matches original
* DirWatch::remove("/home/baz/");

After directory is removed from notifier, further change events in it will not be delivered.

If you want to deliver some data in callback, you can use void* parameter. To remind:

* void notify_cb(const char* dir, const char* what_changed, int flags, void* d) {
* MySampleWidget* w = (MySampleWidget*)d;
* w->write_in_widget(dir);
* }
* MySampleWidget* w = new MySampleWidget(...);
* DirWatch::callback(notify_cb, mywidget);

DirWatch can report what backend it use for notification via notifier() member which will return one of the DirWatchNotifier elements. Then application can choose special case for some backend when is compiled in.

Constructor & Destructor Documentation

DirWatch ( )

Empty constructor

~DirWatch ( )

Clean internal data

Member Function Documentation

static bool add ( const char *  dir,
int  flags 

Add directory to be watched. Directory must exists or will be ignored. It will return true if addition was succesfull or false if not.

static void callback ( DirWatchCallback &  cb,
void *  data = 0 

Register callback called when content of one of added directories was changed.

static bool init ( void  )

Prepare internal data. This must be called before any further add()

static DirWatchNotifier notifier ( void  )

Return current notifier used, or DW_NONE if none of them.

static bool remove ( const char *  dir)

Remove added entry.

static void shutdown ( void  )

Shutdown watcher and clean data. Any further add() call after this will trigger assertion.

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