BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
3d07564
Branches
Tags
master
Blinker
src
noarch
ListTracker_impl.h
created template class for tracking lists in directories, converted priority module to use this class
Stefan Schuermans
commited
3d07564
at 2011-12-10 22:52:36
ListTracker_impl.h
Blame
History
Raw
/* Blinker Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org> Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #ifndef LISTTRACKER_IMPL_H #define LISTTRACKER_IMPL_H #include <list> #include <string> #include "Directory.h" #include "File.h" #include "ListTracker.h" namespace Blinker { /* ################### # ListTrackerFiDi # ################### */ /// internal helper class to achive different behavior for FIDI parameter template <typename FIDI> class ListTrackerFiDi { public: static inline Directory::Type type(); static inline FIDI get(const Directory &dir, const std::string name); }; template<> inline Directory::Type ListTrackerFiDi<File>::type() { return Directory::TypeFile; } template<> inline File ListTrackerFiDi<File>:: get(const Directory &dir, const std::string name) { return dir.getFile(name); } template<> inline Directory::Type ListTrackerFiDi<Directory>::type() { return Directory::TypeSubdir; } template<> inline Directory ListTrackerFiDi<Directory>:: get(const Directory &dir, const std::string name) { return dir.getSubdir(name); } /* ############### # ListTracker # ############### */ /** * @brief constructor * @param[in] dir directory containing list and begin tracked * @param[in] parent parent object */ template<typename PARENT, typename TYPE, typename FIDI> ListTracker<PARENT, TYPE, FIDI>::ListTracker(PARENT &parent, const Directory &dir): m_parent(parent), m_dir(dir) { } /// destructor template<typename PARENT, typename TYPE, typename FIDI> ListTracker<PARENT, TYPE, FIDI>::~ListTracker() { /* free leftover list entries: Depending on the interaction bet ween the list entry object and the parent, it might be too late to free them, as the parent might already be partly deconstructed and thus might be in an inconsistent state. It's recommended to call clear manually before, so that the following call becomes a no-operation. */ clear(); } /// initialize list by reading directory template<typename PARENT, typename TYPE, typename FIDI> void ListTracker<PARENT, TYPE, FIDI>::init() { updateListFull(); } /// clear list template<typename PARENT, typename TYPE, typename FIDI> void ListTracker<PARENT, TYPE, FIDI>::clear() { while (!m_list.empty()) { delete m_list.back().m_pObj; m_list.pop_back(); } } /// check for update of configuration template<typename PARENT, typename TYPE, typename FIDI> void ListTracker<PARENT, TYPE, FIDI>::updateConfig() { // directory modified -> full, otherwise -> light if (m_dir.checkModified()) updateListFull(); else updateListLight(); } /// light update of list, i.e. check all entries in current list template<typename PARENT, typename TYPE, typename FIDI> void ListTracker<PARENT, TYPE, FIDI>::updateListLight() { typename List::iterator it; for (it = m_list.begin(); it != m_list.end(); ++it) it->m_pObj->updateConfig(); } /// full update of list, i.e. scan files/subdirs in list directory template<typename PARENT, typename TYPE, typename FIDI> void ListTracker<PARENT, TYPE, FIDI>::updateListFull() { // get list of files/subdirs in directory typedef std::list<std::string> FileList; FileList curFiles; m_dir.getEntries(ListTrackerFiDi<FIDI>::type(), curFiles); // walk through current list and file/subdir list simultaneously FileList::const_iterator itFile = curFiles.begin(); typename List::iterator it = m_list.begin(); while (itFile != curFiles.end() || it != m_list.end()) { // new entry inserted if (it == m_list.end() || (itFile != curFiles.end() && *itFile < it->m_name)) { // create object Entry entry; entry.m_name = *itFile; entry.m_pObj = new TYPE(m_parent, *itFile, ListTrackerFiDi<FIDI>::get(m_dir, *itFile)); if (entry.m_pObj) // insert list entry m_list.insert(it, entry); // advance to next file/subdir ++itFile; } // entry removed else if (itFile == curFiles.end() || *itFile > it->m_name) { // remove entry delete it->m_pObj; it = m_list.erase(it); // do not advance to next file/subdir } // entry stayed in list else { // check for update it->m_pObj->updateConfig(); // advance to next file/subdir and next entry ++itFile; ++it; } } // while itFile it } } // namespace Blinker #endif // #ifndef LISTTRACKER_IMPL_H