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

TableViewCache.h

Go to the documentation of this file.
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     /* ShowView:
00059        positions a cached view with the specified image at the specified location
00060        or creates one if there wasn't already one.
00061        */
00062     void ShowView(String column, int row, int x, int y, int w, int h)
00063     {
00064 //        int id = mSource->GetID(row);
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 //                              mViewsToQuid[quid] = GetViewIndexFromCache(quid);
00073 //                v->UserData1 = (void*)quid;
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     /* AddDelayLoad:
00088        enqueues the image for an id to be loaded into v, and reserves v for
00089        this purpose.
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     /*  ProcessDelayLoad:
00102         looks which views where recently made visible (in mDelayedLoadeQueue)
00103         and loads their images. This function is to be called repeatedly, f.e.
00104         from DisplayFunc.
00105         returns; false when done.
00106                  true when there is more to do
00107 
00108         There is a limit to the numer of items loaded at once (even when multithreading),
00109         because there is a check here to see if an image which is still in the queue is
00110         still needed (which is not the case when the user scrolls rapidly)
00111 
00112         FUTURE:
00113             pending talks with Richard I'd like to rewrite this, all images in the
00114             load queue get pushed into the thread pool, when a thread is ready to
00115             actually load the image a verification is done if the image is still on
00116             screen. If this is not the case the load gets cancelled.
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                 //ILOG_DEBUG("Delayed loading of " << row <<
00141                 //           " cancelled. Out of screen area.");
00142 
00143                 // if cashed unhook v, to be requeued again when visible.
00144                 if (v = GetViewFromCache(quid))
00145                     SetViewUserData(v, -1, 0);
00146                 continue;
00147             }
00148             //ILOG_DEBUG("Delayed loading of " << row << ", " <<
00149             //           "mDelayedLoadQueue.size() << " items remaining.");
00150             if (!(v = GetViewFromCache(quid)))
00151             {
00152                 //ILOG_ERROR("QUID " << quid << " was added to the queue, " <<
00153                 //           "but its view got stolen!");
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 //                batch+=2; // don't process too many pictures per DelayLoad
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     // mCacheSize must be equal or smaller than that of ImageCache,
00198     // to allow ImageCache to still contain all OGLIMAGE's, so that
00199     // ImageCache actually works.
00200 
00201     // mCacheSize must be equal or larger than the maximum possible
00202     // amount of views on a single screen
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 } // namespace MediaTable
00250 } // namespace Application
00251 } // namespace Impala
00252 
00253 #endif // TableViewCache_h

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