00001 #ifndef MediaTable_TableViewCache_h
00002 #define MediaTable_TableViewCache_h
00003
00004 #include "TableDataView.h"
00005 #include "TableDataStore.h"
00006
00007 #include "OglImageCacheStore.h"
00008 #include "OglGui/GetOglImageByIdInterface.h"
00009 #include "ImageLoader.h"
00010
00011 namespace Impala {
00012 namespace Application {
00013 namespace MediaTable {
00014
00015 class TableViewCache
00016 {
00017 public:
00018 TableViewCache(OglGui::Window *table, TableDataView* source)
00019 {
00020 Init(table, source);
00021 }
00022
00023 void SetGetOglImageByIdInterface(OglGui::GetOglImageByIdInterface* i)
00024 {
00025 mGetOglImageByIdI = i;
00026 }
00027
00028 OGLVIEW* GetViewFromCache(unsigned long long quid)
00029 {
00030 if (mQuidToView.find(quid) != mQuidToView.end())
00031 {
00032 return mViews[mQuidToView[quid]];
00033 }
00034 return 0;
00035 }
00036
00037 int GetUnusedIndexFromCache()
00038 {
00039 int item = mLRU.front();
00040 UpdateLRU(item);
00041 std::map<unsigned long long, int>::iterator iter;
00042 for(iter = mQuidToView.begin(); iter != mQuidToView.end(); iter++)
00043 if(iter->second == item)
00044 {
00045 ILOG_DEBUG("Bye bye " << iter->first);
00046 mQuidToView.erase(iter);
00047 break;
00048 }
00049 return item;
00050 }
00051
00052 void HideViews()
00053 {
00054 for (int i=0; i<mViews.size(); i++)
00055 viewSys.ClearTags(mViews[i], visibleTag);
00056 }
00057
00058
00059
00060
00061
00062 void ShowView(String column, int row, int x, int y, int w, int h)
00063 {
00064
00065 unsigned long long quid = mSource->GetSortedQuid(column, row);
00066 OGLVIEW *v = GetViewFromCache(quid);
00067 if (v)
00068 {
00069 if (v->UserData2 != (void*)2 && v->im)
00070 {
00071 UpdateZoom(v, w, h);
00072
00073
00074 viewSys.SetDimensions(v, x,y,w,h);
00075 viewSys.SetTags(v,visibleTag);
00076 }
00077 }
00078 if (!v)
00079 {
00080 int index = GetUnusedIndexFromCache();
00081 v = mViews[index];
00082 viewSys.SetDimensions(v,x,y,w,h);
00083 AddDelayLoad(quid, index);
00084 }
00085 }
00086
00087
00088
00089
00090
00091 void AddDelayLoad(unsigned long long quid, int index)
00092 {
00093 OGLVIEW *v = mViews[index];
00094 mQuidToView[quid] = index;
00095 SetViewUserData(v, index, 2);
00096 mDelayedLoadQueue.push( quid );
00097 ILOG_DEBUG("Enqueing delayed load for " << quid << ", now " <<
00098 mDelayedLoadQueue.size() << " items queued.");
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 bool ProcessDelayLoad()
00120 {
00121 if (mDelayedLoadQueue.empty())
00122 {
00123 ImageLoader* loader = dynamic_cast<ImageLoader*> (mGetOglImageByIdI);
00124 if(loader)
00125 return loader->IsLoading();
00126 else
00127 return false;
00128
00129 }
00130
00131 OGLVIEW* v;
00132 for (int batch=0; batch < 45; batch++)
00133 {
00134 if (mDelayedLoadQueue.empty())
00135 return true;
00136 unsigned long long quid = mDelayedLoadQueue.front();
00137 mDelayedLoadQueue.pop();
00138 if (mSource->OutOfBoundsByQuid(quid))
00139 {
00140
00141
00142
00143
00144 if (v = GetViewFromCache(quid))
00145 SetViewUserData(v, -1, 0);
00146 continue;
00147 }
00148
00149
00150 if (!(v = GetViewFromCache(quid)))
00151 {
00152
00153
00154 continue;
00155 }
00156 v->UserData2 = (void *) 0;
00157 OGLIMAGE* oglIm = mOglImageCache->GetImage(quid);
00158
00159 if ((oglIm == 0) && mGetOglImageByIdI)
00160 {
00161 oglIm = mGetOglImageByIdI->GetOglImageById(quid);
00162 mOglImageCache->Add(oglIm, quid);
00163
00164 }
00165 if (oglIm == 0)
00166 continue;
00167 viewSys.SetImage(v, oglIm);
00168 ReleaseOglImage(oglIm);
00169 }
00170 return true;
00171 }
00172
00173 void UpdateZoom(OGLVIEW *v, int w, int h)
00174 {
00175 if (!v || !v->im) return;
00176
00177 float zoomX, zoomY;
00178 zoomY = zoomX = (v->w)/(float)v->im->w;
00179 viewSys.SetZoom(v, zoomX, zoomY);
00180 }
00181
00182 void UpdateLRU(int index)
00183 {
00184 mLRU.remove(index);
00185 mLRU.push_back(index);
00186 }
00187
00188 private:
00189
00190 void SetViewUserData(OGLVIEW* oglView, int data1, int data2)
00191 {
00192 if (!oglView) return;
00193 oglView->UserData1 = (void *) data1;
00194 oglView->UserData2 = (void *) data2;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203 void Init(OglGui::Window *table, TableDataView* source)
00204 {
00205 mTable = table;
00206 mSource = source;
00207 mCacheSize = 400;
00208 ILOG_DEBUG("Init(" << mCacheSize << " items)");
00209
00210 mGetOglImageByIdI = 0;
00211 mOglImageCache = OglImageCacheStore::GetInstance();
00212 if (!mOglImageCache)
00213 {
00214 ILOG_ERROR("Could not retrieve image cache, segfault in a few " <<
00215 "moments, please stand by.");
00216 }
00217
00218 for (int i=0; i<mCacheSize; i++)
00219 {
00220 OGLVIEW* view = viewSys.View2D(mTable->GetOGLWND(),0,0,0,128,128);
00221 viewSys.SetTags(view, FlexViewTags);
00222 int clearTags = visibleTag|showBorderTag|showBgTag|selectableTag;
00223 viewSys.ClearTags(view, clearTags);
00224 viewSys.SetColor(view, OGL_BG, oglTrLIGHTGREY);
00225 SetViewUserData(view,-1, 0);
00226 mViews.push_back(view);
00227 mLRU.push_back(i);
00228 }
00229 }
00230
00231 int mCacheSize;
00232
00233 TableDataView* mSource;
00234 OglGui::OglImageCache* mOglImageCache;
00235 OglGui::GetOglImageByIdInterface* mGetOglImageByIdI;
00236
00237 std::queue< unsigned long long > mDelayedLoadQueue;
00238 std::vector<OGLVIEW*> mViews;
00239 std::map<unsigned long long, int> mQuidToView;
00240 std::list<int> mLRU;
00241
00242 OglGui::Window* mTable;
00243
00244 ILOG_VAR_DEC;
00245 };
00246
00247 ILOG_VAR_INIT(TableViewCache, Application.MediaTable);
00248
00249 }
00250 }
00251 }
00252
00253 #endif // TableViewCache_h