|
MythTV
0.26-pre
|
00001 // -*- Mode: c++ -*- 00002 // vim:set sw=4 ts=4 expandtab: 00003 // Copyright (c) 2009, Daniel Thor Kristjansson 00004 // Distributed as part of MythTV under GPL version 2 00005 // (or at your option a later version) 00006 00007 #include <QCoreApplication> 00008 #include <QRunnable> 00009 00010 #include "programinfocache.h" 00011 #include "mthreadpool.h" 00012 #include "mythlogging.h" 00013 #include "programinfo.h" 00014 #include "remoteutil.h" 00015 #include "mythevent.h" 00016 00017 typedef vector<ProgramInfo*> *VPI_ptr; 00018 static void free_vec(VPI_ptr &v) 00019 { 00020 if (v) 00021 { 00022 vector<ProgramInfo*>::iterator it = v->begin(); 00023 for (; it != v->end(); ++it) 00024 delete *it; 00025 delete v; 00026 v = NULL; 00027 } 00028 } 00029 00030 class ProgramInfoLoader : public QRunnable 00031 { 00032 public: 00033 ProgramInfoLoader(ProgramInfoCache &c, const bool updateUI) 00034 : m_cache(c), m_updateUI(updateUI) {} 00035 00036 void run(void) 00037 { 00038 m_cache.Load(m_updateUI); 00039 } 00040 00041 ProgramInfoCache &m_cache; 00042 bool m_updateUI; 00043 }; 00044 00045 ProgramInfoCache::ProgramInfoCache(QObject *o) : 00046 m_next_cache(NULL), m_listener(o), 00047 m_load_is_queued(false), m_loads_in_progress(0) 00048 { 00049 } 00050 00051 ProgramInfoCache::~ProgramInfoCache() 00052 { 00053 QMutexLocker locker(&m_lock); 00054 00055 while (m_loads_in_progress) 00056 m_load_wait.wait(&m_lock); 00057 00058 Clear(); 00059 free_vec(m_next_cache); 00060 } 00061 00062 void ProgramInfoCache::ScheduleLoad(const bool updateUI) 00063 { 00064 QMutexLocker locker(&m_lock); 00065 if (!m_load_is_queued) 00066 { 00067 m_load_is_queued = true; 00068 m_loads_in_progress++; 00069 MThreadPool::globalInstance()->start( 00070 new ProgramInfoLoader(*this, updateUI), "ProgramInfoLoader"); 00071 } 00072 } 00073 00074 void ProgramInfoCache::Load(const bool updateUI) 00075 { 00076 QMutexLocker locker(&m_lock); 00077 m_load_is_queued = false; 00078 00079 locker.unlock(); 00080 00081 // Get an unsorted list (sort = 0) from RemoteGetRecordedList 00082 // we sort the list later anyway. 00083 vector<ProgramInfo*> *tmp = RemoteGetRecordedList(0); 00084 00085 locker.relock(); 00086 00087 free_vec(m_next_cache); 00088 m_next_cache = tmp; 00089 00090 if (updateUI) 00091 QCoreApplication::postEvent( 00092 m_listener, new MythEvent("UPDATE_UI_LIST")); 00093 00094 m_loads_in_progress--; 00095 m_load_wait.wakeAll(); 00096 } 00097 00098 bool ProgramInfoCache::IsLoadInProgress(void) const 00099 { 00100 QMutexLocker locker(&m_lock); 00101 return m_loads_in_progress; 00102 } 00103 00104 void ProgramInfoCache::WaitForLoadToComplete(void) const 00105 { 00106 QMutexLocker locker(&m_lock); 00107 while (m_loads_in_progress) 00108 m_load_wait.wait(&m_lock); 00109 } 00110 00121 void ProgramInfoCache::Refresh(void) 00122 { 00123 QMutexLocker locker(&m_lock); 00124 if (m_next_cache) 00125 { 00126 Clear(); 00127 vector<ProgramInfo*>::iterator it = m_next_cache->begin(); 00128 for (; it != m_next_cache->end(); ++it) 00129 { 00130 if (!(*it)->GetChanID()) 00131 continue; 00132 00133 PICKey k((*it)->GetChanID(), (*it)->GetRecordingStartTime()); 00134 m_cache[k] = *it; 00135 } 00136 delete m_next_cache; 00137 m_next_cache = NULL; 00138 return; 00139 } 00140 locker.unlock(); 00141 00142 Cache::iterator it = m_cache.begin(); 00143 Cache::iterator nit = it; 00144 for (; it != m_cache.end(); it = nit) 00145 { 00146 nit = it; 00147 ++nit; 00148 00149 if (it->second->GetAvailableStatus() == asDeleted) 00150 { 00151 delete it->second; 00152 m_cache.erase(it); 00153 } 00154 } 00155 } 00156 00161 bool ProgramInfoCache::Update(const ProgramInfo &pginfo) 00162 { 00163 QMutexLocker locker(&m_lock); 00164 00165 Cache::iterator it = m_cache.find( 00166 PICKey(pginfo.GetChanID(),pginfo.GetRecordingStartTime())); 00167 00168 if (it != m_cache.end()) 00169 it->second->clone(pginfo, true); 00170 00171 return it != m_cache.end(); 00172 } 00173 00178 bool ProgramInfoCache::UpdateFileSize( 00179 uint chanid, const QDateTime &recstartts, uint64_t filesize) 00180 { 00181 QMutexLocker locker(&m_lock); 00182 00183 Cache::iterator it = m_cache.find(PICKey(chanid,recstartts)); 00184 00185 if (it != m_cache.end()) 00186 { 00187 it->second->SetFilesize(filesize); 00188 if (filesize) 00189 it->second->SetAvailableStatus(asAvailable, "PIC::UpdateFileSize"); 00190 } 00191 00192 return it != m_cache.end(); 00193 } 00194 00198 QString ProgramInfoCache::GetRecGroup( 00199 uint chanid, const QDateTime &recstartts) const 00200 { 00201 QMutexLocker locker(&m_lock); 00202 00203 Cache::const_iterator it = m_cache.find(PICKey(chanid,recstartts)); 00204 00205 QString recgroup; 00206 if (it != m_cache.end()) 00207 recgroup = it->second->GetRecordingGroup(); 00208 00209 return recgroup; 00210 } 00211 00215 void ProgramInfoCache::Add(const ProgramInfo &pginfo) 00216 { 00217 if (!pginfo.GetChanID() || Update(pginfo)) 00218 return; 00219 00220 PICKey key(pginfo.GetChanID(),pginfo.GetRecordingStartTime()); 00221 m_cache[key] = new ProgramInfo(pginfo); 00222 } 00223 00229 bool ProgramInfoCache::Remove(uint chanid, const QDateTime &recstartts) 00230 { 00231 Cache::iterator it = m_cache.find(PICKey(chanid,recstartts)); 00232 00233 if (it != m_cache.end()) 00234 it->second->SetAvailableStatus(asDeleted, "PIC::Remove"); 00235 00236 return it != m_cache.end(); 00237 } 00238 00239 void ProgramInfoCache::GetOrdered(vector<ProgramInfo*> &list, bool newest_first) 00240 { 00241 if (newest_first) 00242 { 00243 Cache::reverse_iterator it = m_cache.rbegin(); 00244 for (; it != m_cache.rend(); ++it) 00245 list.push_back(it->second); 00246 } 00247 else 00248 { 00249 for (Cache::iterator it = m_cache.begin(); it != m_cache.end(); ++it) 00250 list.push_back(it->second); 00251 } 00252 } 00253 00254 ProgramInfo *ProgramInfoCache::GetProgramInfo( 00255 uint chanid, const QDateTime &recstartts) const 00256 { 00257 Cache::const_iterator it = m_cache.find(PICKey(chanid,recstartts)); 00258 00259 if (it != m_cache.end()) 00260 return it->second; 00261 00262 return NULL; 00263 } 00264 00265 ProgramInfo *ProgramInfoCache::GetProgramInfo(const QString &piKey) const 00266 { 00267 uint chanid; 00268 QDateTime recstartts; 00269 if (ProgramInfo::ExtractKey(piKey, chanid, recstartts)) 00270 return GetProgramInfo(chanid, recstartts); 00271 return NULL; 00272 } 00273 00275 void ProgramInfoCache::Clear(void) 00276 { 00277 for (Cache::iterator it = m_cache.begin(); it != m_cache.end(); ++it) 00278 delete it->second; 00279 m_cache.clear(); 00280 } 00281
1.7.6.1