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