ganeswidgets/tsrc/fute/HgWidgetTest/src/buffermanager.cpp
changeset 1 e48454f237ca
child 3 c863538fcbb6
equal deleted inserted replaced
0:89c329efa980 1:e48454f237ca
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:     
       
    15 *
       
    16 */
       
    17 #include "buffermanager.h"
       
    18 #include <qglobal.h>
       
    19 
       
    20 BufferManager::BufferManager(
       
    21     AbstractDataProvider* aObserver,
       
    22 	int aBufferSize,
       
    23 	int aBufferTreshold,
       
    24 	int aInitialPosition,
       
    25 	int aTotalCount )
       
    26 :
       
    27 mObserver(aObserver),
       
    28 mBufferSize( aBufferSize ),
       
    29 mBufferTreshold( aBufferTreshold ),
       
    30 mBufferPosition( aInitialPosition ),
       
    31 mTotalCount( aTotalCount )
       
    32 {
       
    33     mBufferPosition -= (mBufferSize / 2);
       
    34     
       
    35     if( mBufferPosition + mBufferSize > mTotalCount - 1 ){
       
    36         mBufferPosition = (mTotalCount - 1) - mBufferSize;
       
    37     }
       
    38     
       
    39     if(mBufferPosition < 0 ){
       
    40         mBufferPosition = 0;
       
    41     }
       
    42     
       
    43     mDiff = 0;
       
    44 	//request Initial Buffer
       
    45 	mRequestStart = mBufferPosition;
       
    46 	mRequestCount = mBufferSize;
       
    47 
       
    48 	calculate();
       
    49 }
       
    50 
       
    51 
       
    52 BufferManager::~BufferManager()
       
    53 {
       
    54 }
       
    55 
       
    56 void BufferManager::resizeCache(int newSize, int newTreshold)
       
    57 {
       
    58     if (newTreshold != mBufferTreshold){
       
    59         mBufferTreshold = newTreshold;
       
    60     }
       
    61     
       
    62     if (newSize!=mBufferSize){
       
    63 //        int pos = mBufferPosition + (mBufferSize / 2);
       
    64 
       
    65         int a = qMax(0, mBufferPosition + mBufferSize/2 - newSize/2);
       
    66         int b = qMin(a + newSize, mTotalCount);
       
    67         if ( b == mTotalCount){
       
    68             a = mTotalCount - newSize;
       
    69         }
       
    70         
       
    71         int c = qMax(0, mBufferPosition);
       
    72         int d = qMin(c + mBufferSize, mTotalCount);
       
    73         if ( d == mTotalCount){
       
    74             c = mTotalCount - mBufferSize;
       
    75         }
       
    76         
       
    77         if ( newSize>mBufferSize){
       
    78             mObserver->request(a, c-1, AbstractDataProvider::ascending);
       
    79             mObserver->request(d, b-1, AbstractDataProvider::ascending);
       
    80         }else if ( newSize<mBufferSize){
       
    81             mObserver->release(c, a-1);
       
    82             mObserver->release(b, d);
       
    83         }
       
    84         mBufferPosition = a;
       
    85         mBufferSize = newSize;
       
    86     }
       
    87 }
       
    88 
       
    89 void BufferManager::calculate()
       
    90 {  
       
    91     AbstractDataProvider::requestsOrder direction = AbstractDataProvider::ascending;
       
    92     
       
    93     if(mResetOrdered){
       
    94         mResetOrdered = false;
       
    95     } else {
       
    96         if(mDiff < 0){
       
    97             mReleaseStart = mBufferPosition;
       
    98             mRequestStart = mBufferPosition + mBufferSize;
       
    99             direction = AbstractDataProvider::ascending; 
       
   100         } else if( mDiff > 0) {
       
   101             mReleaseStart = mBufferPosition + mBufferSize - mDiff;
       
   102             mRequestStart = mBufferPosition - mDiff;
       
   103             direction = AbstractDataProvider::descending;
       
   104         }
       
   105     }
       
   106     
       
   107     // Release 
       
   108     int end = mReleaseStart + mReleaseCount < mTotalCount ?
       
   109         mReleaseStart + mReleaseCount: mTotalCount; 
       
   110     end--;
       
   111     if(end >= mReleaseStart ){
       
   112         mObserver->release(mReleaseStart, end);
       
   113     }
       
   114     
       
   115     mReleaseCount = 0;
       
   116     
       
   117     // Request
       
   118     end = mRequestStart + mRequestCount < mTotalCount ? 
       
   119         mRequestStart + mRequestCount : mTotalCount;
       
   120     
       
   121     end--;
       
   122     if(end >= mRequestStart ){
       
   123         mObserver->request(mRequestStart, end, direction);
       
   124 	}
       
   125       
       
   126     mRequestCount = 0;
       
   127     
       
   128     // Move Buffer
       
   129     mBufferPosition -= mDiff;
       
   130     // Reset Diff
       
   131     mDiff = 0;
       
   132 }
       
   133 
       
   134 // -----------------------------------------------------------------------------
       
   135 // BufferManager::SetPosition()
       
   136 // -----------------------------------------------------------------------------
       
   137 //
       
   138 void BufferManager::setPosition( int aIndex )
       
   139 {
       
   140     // If all the items fit in the buffer no need to move the buffer
       
   141     if(mTotalCount <= mBufferSize) return;
       
   142 	
       
   143 	bool forceUpdate = false;
       
   144     aIndex -= mBufferSize / 2; // normalize index to Buffer start
       
   145     
       
   146     if(aIndex < 0){
       
   147         aIndex = 0;
       
   148         forceUpdate = true;
       
   149     }else if( aIndex > mTotalCount - mBufferSize ){
       
   150         aIndex = mTotalCount - mBufferSize;
       
   151         forceUpdate = true;
       
   152     }
       
   153 
       
   154     mDiff = mBufferPosition - aIndex; 
       
   155 
       
   156     // Too large change reset whole buffer
       
   157     if( mDiff >= mBufferSize || -mDiff >= mBufferSize || mResetOrdered ) {
       
   158         resetBuffer(aIndex + (mBufferSize/2), mTotalCount);
       
   159     } else if( mDiff >= mBufferTreshold ) { // Move Up
       
   160         mRequestCount = mDiff;
       
   161         mReleaseCount = mDiff;
       
   162         calculate();
       
   163     } else if ( -mDiff >= mBufferTreshold ) {// Move Down
       
   164         mRequestCount = -mDiff;
       
   165         mReleaseCount = -mDiff;
       
   166         calculate();
       
   167     } else if( forceUpdate && mDiff ) { // Top or bottom has been reached
       
   168         int diff = mDiff < 0 ? -mDiff : mDiff;
       
   169         mRequestCount = diff;
       
   170         mReleaseCount = diff;
       
   171         calculate();
       
   172     }
       
   173 }
       
   174 
       
   175 // -----------------------------------------------------------------------------
       
   176 // BufferManager::ResetBuffer()
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 void BufferManager::resetBuffer( int aPosition, int aTotalCount)
       
   180 {
       
   181     if( !mResetOrdered ){
       
   182         // release Old buffer
       
   183         mReleaseStart = mBufferPosition;
       
   184         mReleaseCount = mBufferSize;
       
   185     }
       
   186     
       
   187     // set position and count
       
   188     mBufferPosition = aPosition - (mBufferSize / 2);
       
   189     mTotalCount = aTotalCount;
       
   190     mDiff = 0;
       
   191     
       
   192     if( mBufferPosition + mBufferSize > mTotalCount - 1 ){
       
   193         mBufferPosition = mTotalCount - mBufferSize;
       
   194     }
       
   195     
       
   196     if(mBufferPosition < 0 ){
       
   197         mBufferPosition = 0;
       
   198     }
       
   199     
       
   200     //request new Buffer
       
   201     mRequestStart = mBufferPosition;
       
   202     mRequestCount = mBufferSize;
       
   203     mResetOrdered = true;
       
   204     calculate();
       
   205 }
       
   206 
       
   207 void BufferManager::itemCountChanged( int aIndex, 
       
   208                                       bool aRemoved,
       
   209                                       int aNewTotalCount )
       
   210 {
       
   211     mTotalCount = aNewTotalCount;
       
   212     AbstractDataProvider::requestsOrder direction = AbstractDataProvider::ascending;    
       
   213     if ( aIndex >= mBufferPosition && aIndex < mBufferPosition + mBufferSize ){
       
   214         // Change inside the buffer
       
   215         if( aRemoved ){
       
   216             // Release removed item ( Item deleted already from the owner )
       
   217 			mObserver->release( aIndex, aIndex );
       
   218             if( mTotalCount >= mBufferSize ){
       
   219                 // There are more items to keep the buffer filled
       
   220                 if( mBufferPosition + mBufferSize <= mTotalCount ){
       
   221                     // Requested from the end
       
   222 					mObserver->request( mBufferPosition + mBufferSize, 
       
   223                                         mBufferPosition + mBufferSize,
       
   224                                         direction );
       
   225                 }else if( mBufferPosition > 0 ){
       
   226                     // Move buffer and request from the beginning 
       
   227                     mBufferPosition--;
       
   228                     mObserver->request( mBufferPosition, mBufferPosition, direction);
       
   229                 }
       
   230             }
       
   231         }else{
       
   232             if( mTotalCount > mBufferSize ){
       
   233                 // One item needs to be released
       
   234                 if( mBufferPosition + mBufferSize < mTotalCount ){
       
   235                     // Release from the end of the buffer
       
   236 					mObserver->release(mBufferPosition + mBufferSize, mBufferPosition + mBufferSize);
       
   237                 }
       
   238             }
       
   239             // Request added item
       
   240             mObserver->request(aIndex, aIndex, direction);
       
   241         }
       
   242     }
       
   243 }
       
   244