587ae25b84177c5af73d1794bba555c6643b39bd
Stefan Schuermans created template class for...

Stefan Schuermans authored 12 years ago

1) /* Blinker
2)    Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org>
3)    Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4)    a blinkenarea.org project */
5) 
Stefan Schuermans namespace for preprocessor...

Stefan Schuermans authored 12 years ago

6) #ifndef BLINKER_LISTTRACKER_IMPL_H
7) #define BLINKER_LISTTRACKER_IMPL_H
Stefan Schuermans created template class for...

Stefan Schuermans authored 12 years ago

8) 
9) #include <list>
10) #include <string>
11) 
12) #include "Directory.h"
13) #include "File.h"
14) #include "ListTracker.h"
15) 
16) namespace Blinker {
17) 
18) /* ###################
19)    # ListTrackerFiDi #
20)    ################### */
21) 
22) 
23) /// internal helper class to achive different behavior for FIDI parameter
24) template <typename FIDI>
25) class ListTrackerFiDi
26) {
27) public:
28)   static inline Directory::Type type();
29)   static inline FIDI get(const Directory &dir, const std::string name);
30) };
31) 
32) template<>
33) inline Directory::Type ListTrackerFiDi<File>::type()
34) {
35)   return Directory::TypeFile;
36) }
37) 
38) template<>
39) inline File ListTrackerFiDi<File>::
40)   get(const Directory &dir, const std::string name)
41) {
42)   return dir.getFile(name);
43) }
44) 
45) template<>
46) inline Directory::Type ListTrackerFiDi<Directory>::type()
47) {
48)   return Directory::TypeSubdir;
49) }
50) 
51) template<>
52) inline Directory ListTrackerFiDi<Directory>::
53)   get(const Directory &dir, const std::string name)
54) {
55)   return dir.getSubdir(name);
56) }
57) 
58) /* ###############
59)    # ListTracker #
60)    ############### */
61) 
62) /**
63)  * @brief constructor
64)  * @param[in] dir directory containing list and begin tracked
65)  * @param[in] parent parent object
66)  */
67) template<typename PARENT, typename TYPE, typename FIDI>
68) ListTracker<PARENT, TYPE, FIDI>::ListTracker(PARENT &parent,
69)                                              const Directory &dir):
70)   m_parent(parent),
71)   m_dir(dir)
72) {
73) }
74) 
75) /// destructor
76) template<typename PARENT, typename TYPE, typename FIDI>
77) ListTracker<PARENT, TYPE, FIDI>::~ListTracker()
78) {
79)   /* free leftover list entries:
80)      Depending on the interaction bet ween the list entry object and
81)      the parent, it might be too late to free them, as the parent might
82)      already be partly deconstructed and thus might be in an inconsistent
83)      state. It's recommended to call clear manually before, so that the
84)      following call becomes a no-operation. */
85)   clear();
86) }
87) 
88) /// initialize list by reading directory
89) template<typename PARENT, typename TYPE, typename FIDI>
90) void ListTracker<PARENT, TYPE, FIDI>::init()
91) {
92)   updateListFull();
93) }
94) 
95) /// clear list
96) template<typename PARENT, typename TYPE, typename FIDI>
97) void ListTracker<PARENT, TYPE, FIDI>::clear()
98) {
99)   while (!m_list.empty()) {
100)     delete m_list.back().m_pObj;
101)     m_list.pop_back();
102)   }
103) }
104) 
105) /// check for update of configuration
106) template<typename PARENT, typename TYPE, typename FIDI>
107) void ListTracker<PARENT, TYPE, FIDI>::updateConfig()
108) {
109)   // directory modified -> full, otherwise -> light
110)   if (m_dir.checkModified())
111)     updateListFull();
112)   else
113)     updateListLight();
114) }
115) 
116) /// light update of list, i.e. check all entries in current list
117) template<typename PARENT, typename TYPE, typename FIDI>
118) void ListTracker<PARENT, TYPE, FIDI>::updateListLight()
119) {
120)   typename List::iterator it;
121)   for (it = m_list.begin(); it != m_list.end(); ++it)
122)     it->m_pObj->updateConfig();
123) }
124) 
125) /// full update of list, i.e. scan files/subdirs in list directory
126) template<typename PARENT, typename TYPE, typename FIDI>
127) void ListTracker<PARENT, TYPE, FIDI>::updateListFull()
128) {
129)   // get list of files/subdirs in directory
130)   typedef std::list<std::string> FileList;
131)   FileList curFiles;
132)   m_dir.getEntries(ListTrackerFiDi<FIDI>::type(), curFiles);
133) 
134)   // walk through current list and file/subdir list simultaneously
135)   FileList::const_iterator itFile = curFiles.begin();
136)   typename List::iterator  it     = m_list.begin();
137)   while (itFile != curFiles.end() || it != m_list.end()) {
138) 
139)     // new entry inserted
140)     if (it == m_list.end() ||
141)         (itFile != curFiles.end() && *itFile < it->m_name)) {
142)       // create object
143)       Entry entry;
144)       entry.m_name = *itFile;
145)       entry.m_pObj = new TYPE(m_parent, *itFile,
146)                               ListTrackerFiDi<FIDI>::get(m_dir, *itFile));
147)       if (entry.m_pObj)
148)         // insert list entry
149)         m_list.insert(it, entry);
150)       // advance to next file/subdir
151)       ++itFile;
152)     }
153) 
154)     // entry removed
155)     else if (itFile == curFiles.end() || *itFile > it->m_name) {
156)       // remove entry
157)       delete it->m_pObj;
158)       it = m_list.erase(it);
159)       // do not advance to next file/subdir
160)     }
161) 
162)     // entry stayed in list
163)     else {
164)       // check for update
165)       it->m_pObj->updateConfig();
166)       // advance to next file/subdir and next entry
167)       ++itFile;
168)       ++it;
169)     }
170) 
171)   } // while itFile it
172) }
173) 
174) } // namespace Blinker
175) 
Stefan Schuermans namespace for preprocessor...

Stefan Schuermans authored 12 years ago

176) #endif // #ifndef BLINKER_LISTTRACKER_IMPL_H