ARB
FileWatch.h
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : FileWatch.h //
4 // Purpose : Watch awar pointing to file AND file itself //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in October 2017 //
7 // http://www.arb-home.de/ //
8 // //
9 // =============================================================== //
10 
11 #ifndef FILEWATCH_H
12 #define FILEWATCH_H
13 
14 #ifndef AW_AWAR_HXX
15 #include <aw_awar.hxx>
16 #endif
17 #ifndef AW_ROOT_HXX
18 #include <aw_root.hxx>
19 #endif
20 #ifndef AW_INOTIFY_HXX
21 #include <aw_inotify.hxx>
22 #endif
23 #ifndef ARB_FILE_H
24 #include <arb_file.h>
25 #endif
26 
27 /* Binds user-callback to an awar which contains a filename (full-path; e.g. from File_selection)
28  * - the user-callback will be called whenever the awar triggers
29  * - the awar will automatically change when
30  * - it points to a file and the file gets modified (awar gets touched)
31  * - the file is deleted (awar changes to "")
32  * - the file is re-created (if awar is "" -> awar points to file again)
33  */
34 
35 class FileWatch : virtual Noncopyable {
36  AW_awar *awar_selfile; // contains name of file (or sth invalid like "")
37  SmartCharPtr watched_file; // if set -> currently watched file
38  FileChangedCallback wf_cb; // used to watch file changes
39  FileChangedCallback user_cb; // called if awar or (pointed-to) file changes
40  // Warning: be aware that callbacks may be called with empty name (""),
41  // depending on where awar is used!
42 
43  void file_modified_handler(const char *file, ChangeReason reason) const {
44  // - corrects "selected file" in response to filesystem changes (de- and re-select)
45  // - triggers awar callback if file gets modified
46 
47  switch (reason) {
48  case CR_CREATED:
49  case CR_MODIFIED:
50  if (awar_selfile->read_char_pntr()[0]) { // awar has content (do not overwrite)
51  awar_selfile->touch();
52  }
53  else if (GB_is_regularfile(file)) {
54  awar_selfile->write_string(file);
55  }
56  break;
57  case CR_DELETED:
59  awar_selfile->write_string("");
60  break;
61  }
62 
63  }
64 
65  void remove_inotification() {
66  if (watched_file.isSet()) {
67  AW_remove_inotification(&*watched_file, wf_cb);
68  watched_file.setNull();
69  }
70  }
71 
72  void awar_modified_handler() {
73  SmartCharPtr file(awar_selfile->read_string());
74 
75  bool points_to_file = GB_is_regularfile(&*file);
76  bool need_change_watch =
77  points_to_file
78  ? (watched_file.isNull() || strcmp(&*watched_file, &*file) != 0)
79  : watched_file.isSet();
80 
81  if (need_change_watch) {
82  remove_inotification();
83  if (points_to_file) {
84  watched_file = file;
85  AW_add_inotification(&*watched_file, wf_cb);
86  }
87  }
88 
89  user_cb(&*file, CR_MODIFIED);
90  }
91 
92  // callback-wrappers
93  static void file_modified_wrapper(const char *file, ChangeReason reason, FileWatch *watch) { watch->file_modified_handler(file, reason); }
94  static void awar_modified_wrapper(AW_root*, FileWatch *watch) { watch->awar_modified_handler(); }
95 
96 public:
97 
98  FileWatch(const char *sel_file_awar, const FileChangedCallback& file_changed_cb) :
99  awar_selfile(AW_root::SINGLETON->awar(sel_file_awar)),
100  wf_cb(makeFileChangedCallback(file_modified_wrapper, this)),
101  user_cb(file_changed_cb)
102  {
103  awar_selfile->add_callback(makeRootCallback(awar_modified_wrapper, this));
104  }
105 
107  awar_selfile->remove_callback(makeRootCallback(awar_modified_wrapper, this));
108  remove_inotification();
109  }
110 };
111 
112 #else
113 #error FileWatch.h included twice
114 #endif // FILEWATCH_H
~FileWatch()
Definition: FileWatch.h:106
AW_awar * add_callback(const RootCallback &cb)
Definition: AW_awar.cxx:231
const char * read_char_pntr() const
Definition: AW_awar.cxx:168
void AW_remove_inotification(const char *file, const FileChangedCallback &fccb)
Definition: AW_inotify.cxx:489
void AW_add_inotification(const char *file, const FileChangedCallback &fccb)
Definition: AW_inotify.cxx:473
#define aw_assert(bed)
Definition: aw_position.hxx:29
void touch()
Definition: AW_awar.cxx:207
char * read_string() const
Definition: AW_awar.cxx:198
AW_awar * remove_callback(const RootCallback &cb)
Definition: AW_awar.cxx:525
ChangeReason
Definition: aw_inotify.hxx:18
bool GB_is_regularfile(const char *path)
Definition: arb_file.cxx:76
FileWatch(const char *sel_file_awar, const FileChangedCallback &file_changed_cb)
Definition: FileWatch.h:98
GB_ERROR write_string(const char *aw_string)