Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

TableViewCache.h

Go to the documentation of this file.
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     /* ShowView:
00046        positions a cached view with the specified image at the specified location
00047        or creates one if there wasn't already one.
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     /* AddDelayLoad:
00072        enqueues the image for an id to be loaded into v, and reserves v for
00073        this purpose.
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         //ILOG_DEBUG("Enqueing delayed load for " << id << ", now " <<
00080         //           mDelayedLoadQueue.size() << " items queued.");
00081     }
00082 
00083     /*  ProcessDelayLoad:
00084         looks which views where recently made visible (in mDelayedLoadeQueue)
00085         and loads their images. This function is to be called repeatedly, f.e.
00086         from DisplayFunc.
00087         returns; false when done.
00088                  true when there is more to do
00089 
00090         There is a limit to the numer of items loaded at once (even when multithreading),
00091         because there is a check here to see if an image which is still in the queue is
00092         still needed (which is not the case when the user scrolls rapidly)
00093 
00094         FUTURE:
00095             pending talks with Richard I'd like to rewrite this, all images in the
00096             load queue get pushed into the thread pool, when a thread is ready to
00097             actually load the image a verification is done if the image is still on
00098             screen. If this is not the case the load gets cancelled.
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                 //ILOG_DEBUG("Delayed loading of " << row <<
00122                 //           " cancelled. Out of screen area.");
00123 
00124                 // if cashed unhook v, to be requeued again when visible.
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             //ILOG_DEBUG("Delayed loading of " << row << ", " <<
00134             //           "mDelayedLoadQueue.size() << " items remaining.");
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 //                batch+=2; // don't process too many pictures per DelayLoad
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     // mCacheSize must be equal or smaller than that of ImageCache,
00183     // to allow ImageCache to still contain all OGLIMAGE's, so that
00184     // ImageCache actually works.
00185 
00186     // mCacheSize must be equal or larger than the maximum possible
00187     // amount of views on a single screen
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 } // namespace VideoExcel
00232 } // namespace Application
00233 } // namespace Impala
00234 
00235 #endif // TableViewCache_h

Generated on Fri Mar 19 09:30:36 2010 for ImpalaSrc by  doxygen 1.5.1