mulwidgets/muldatamodel/src/mulasyncdataprovider.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 21 Jun 2010 16:15:51 +0300
branchRCL_3
changeset 23 514d98f21c43
parent 0 e83bab7cf002
permissions -rw-r--r--
Revision: 201023 Kit: 2010125

/*
* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  Active Object Implementation for providing data asynchronously
*
*/


#include "mulasyncdataprovider.h"

#include <osn/osnnew.h>
#include <algorithm> //for find algorithm

#include "mullog.h"

namespace Alf
    {

// ---------------------------------------------------------------------------
// MulAsyncDataProvider
// ---------------------------------------------------------------------------
//
MulAsyncDataProvider::MulAsyncDataProvider( IMulModelProvider& aDataProvider,
                                            const MulPageDataWindow& aDataWindow )
                     :CActive( EPriorityNormal ),
                      mDataProvider(aDataProvider),
                      mDataWindow(aDataWindow)
    {
    MUL_LOG_ENTRY_EXIT("MUL::MulAsyncDataProvider::MulAsyncDataProvider");
    CActiveScheduler::Add(this);
    }

// ---------------------------------------------------------------------------
// ~MulAsyncDataProvider
// ---------------------------------------------------------------------------
//
MulAsyncDataProvider::~MulAsyncDataProvider()
    {
    MUL_LOG_ENTRY_EXIT("MUL::MulAsyncDataProvider::~MulAsyncDataProvider");  
    Cancel();
    mDataQueue.clear();
    }

// ---------------------------------------------------------------------------
// RunL
// ---------------------------------------------------------------------------
//
void MulAsyncDataProvider::RunL()
    {  
    vector<MulAsyncData>::iterator iter = mDataQueue.begin();
    if( iter < mDataQueue.end() )
        {
        bool inDataWindow = false;
        MulAsyncData asyncData = *iter;
        
        if(mDataWindow.IsItemInDataWindow(asyncData.mStartIndex) /*&& mDataWindow->IsItemInDataWindow(mStartIndex+ITEMS)*/)
            { 
            if( asyncData.mRange < mDataWindow.WindowSize() )
                {
                mDataProvider.ProvideData( asyncData.mStartIndex, asyncData.mRange, asyncData.mPath); 
                }
            else
                {
                mDataProvider.ProvideData( asyncData.mStartIndex, mDataWindow.WindowSize() , asyncData.mPath); 
                }
            inDataWindow = true;
            }
                  
        asyncData.mStartIndex += mDataWindow.WindowSize();
        asyncData.mRange -= mDataWindow.WindowSize();
        mDataQueue.erase(iter);
        
       if( asyncData.mRange > 0 && inDataWindow )
            {     
            mDataQueue.insert( iter, asyncData ); 
            if( !IsActive() )
                {
                ActivateAndComplete();
                }
            }
         else if(mDataQueue.begin() < mDataQueue.end())
            {  
            if( !IsActive() )
                {
                ActivateAndComplete();
                }
            }
        }     
    }

// ---------------------------------------------------------------------------
// DoCancel
// ---------------------------------------------------------------------------
//
void MulAsyncDataProvider::DoCancel()
    {
    //does this function required??
    }
//    
// ---------------------------------------------------------------------------
// ProvideData
// ---------------------------------------------------------------------------
//
void MulAsyncDataProvider::ProvideData( int aStartIndex, int aRange, const MulDataPath& aPath, const bool aIsSync )
    { 
    if( aIsSync )
        {
        mDataProvider.ProvideData( aStartIndex, aRange, aPath);
        return;
        }
    MulAsyncData asyncData;
    asyncData.mStartIndex = aStartIndex;
    asyncData.mRange = aRange;
    asyncData.mPath = aPath;
    if( std::find( mDataQueue.begin(), mDataQueue.end(), asyncData ) ==  mDataQueue.end())
        {
        mDataQueue.push_back( asyncData );
        }
                 
    for( int i = 0 ; i < mDataQueue.size() ; ++i )
        {
        MulAsyncData data = mDataQueue[i]; 
        if ( (mDataWindow.IsItemInDataWindow( data.mStartIndex ) &&
              !mDataWindow.IsItemInDataWindow( data.mStartIndex + data.mRange - 1 ) ) )
            {
            int index = GetFirstIndexForWhichDataIsPresent(data.mStartIndex , data.mStartIndex + data.mRange - 1 );
            if( index!= -1 &&( index - data.mStartIndex + 1) > 0)
                {
                mDataQueue.erase(mDataQueue.begin() + i);
                data.mRange = index - data.mStartIndex + 1;
                mDataQueue.insert(mDataQueue.begin() + i, data);
                }
            else
                {
                mDataQueue.erase(mDataQueue.begin() + i);
                i--;
                }    
            
            }
        else if ( (!mDataWindow.IsItemInDataWindow( data.mStartIndex ) &&
              mDataWindow.IsItemInDataWindow( data.mStartIndex + data.mRange - 1 ) ) )
            {
            int index = GetFirstIndexForWhichDataIsPresent(data.mStartIndex , data.mStartIndex + data.mRange - 1 );
            if( index!= -1 &&( data.mStartIndex + data.mRange - index ) > 0 )
                {
                mDataQueue.erase(mDataQueue.begin() + i);
                int endIndex = (data.mStartIndex + data.mRange - 1);
                data.mStartIndex = index;
                data.mRange = (endIndex - index + 1);
                mDataQueue.insert(mDataQueue.begin() + i, data);
                }
            else
                {
                mDataQueue.erase(mDataQueue.begin() + i);
                i--;
                }
            }
        else if ( (!mDataWindow.IsItemInDataWindow( data.mStartIndex ) &&
              !mDataWindow.IsItemInDataWindow( data.mStartIndex + data.mRange - 1 ) ) )
           {
           mDataQueue.erase(mDataQueue.begin() + i);
           i--;
           MUL_LOG_INFO2( "MUL::MulAsyncDataProvider::ProvideData Removing From Q: startIndx=%d,range=%d", data.mStartIndex, data.mRange ); 
           }
        }
    
    if( !IsActive() )
        { 
        ActivateAndComplete();
        }
    }
// ---------------------------------------------------------------------------
// GetFirstIndexForWhichDataIsPresent
// ---------------------------------------------------------------------------
//
int MulAsyncDataProvider::GetFirstIndexForWhichDataIsPresent(int aStartIndex, int aEndIndex)
    {
    if ( aStartIndex > aEndIndex )
        {
        return -1;
        }
    int mid = (aStartIndex + aEndIndex)/2;
    if(mDataWindow.IsItemInDataWindow(aStartIndex))
        {
        if(mid == aStartIndex)
            {
            return mid;
            }
        if(mDataWindow.IsItemInDataWindow(mid))
            {
            return GetFirstIndexForWhichDataIsPresent(mid, aEndIndex);
            }
        else
            {
            return GetFirstIndexForWhichDataIsPresent(aStartIndex, mid);
            }
        }
     else if(mDataWindow.IsItemInDataWindow(aEndIndex))
        {
        if(mid == aStartIndex)
            {
            return (mid + 1);
            }
        if(mDataWindow.IsItemInDataWindow(mid))
            {
            return GetFirstIndexForWhichDataIsPresent(aStartIndex, mid);
            }
        else
            {
            return GetFirstIndexForWhichDataIsPresent(mid, aEndIndex);
            }           
        }   
    return -1;
    }
  
// ---------------------------------------------------------------------------
// ActivateAndComplete
// ---------------------------------------------------------------------------
//
 void MulAsyncDataProvider::ActivateAndComplete()
    {
    TRequestStatus* lStatus = &iStatus;
    iStatus = KRequestPending;
    SetActive();
    User::RequestComplete(lStatus, KErrNone);
    }
 
    } // End of namespace Alf .


// End of file