ximpfw/core/srcprocessor/ximpcontexteventqueue.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 18 Jan 2010 20:33:04 +0200
changeset 2 89455bbf90d8
parent 0 e6b17d312c8b
permissions -rw-r--r--
Revision: 201001 Kit: 201003

/*
* Copyright (c) 2006 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: Implementation of context event queue
 *
*/

#include "ximpcontexteventqueue.h"
#include "ximpeventqueueobserver.h"

#include "ximpglobals.h"
#include "ximpeventmanager.h"
#include "ximpeventcapsule.h"
#include "ximpcontexteventfilter.h"
#include "ximppanics.h"
#include "ximpcontextstateeventimp.h"
#include "ximprequestcompleteeventimp.h"

#include <e32base.h>



// ============================ MEMBER FUNCTIONS =============================

// ---------------------------------------------------------------------------
// CXIMPContextEventQueue::NewL()
// ---------------------------------------------------------------------------
//
EXPORT_C CXIMPContextEventQueue* CXIMPContextEventQueue::NewL()
    {
    CXIMPContextEventQueue* self =
        new( ELeave ) CXIMPContextEventQueue( );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    return self;
    }


// ---------------------------------------------------------------------------
// CXIMPContextEventQueue::~CXIMPContextEventQueue()
// ---------------------------------------------------------------------------
//
CXIMPContextEventQueue::~CXIMPContextEventQueue()
    {
    ClearQueuedEvents();
    delete iEventFilter;

    TInt eventCount =  iPreservedEvents.Count();
    for( TInt ix = 0; ix < eventCount ; ix++ )
        {
        iPreservedEvents[ ix ]->Close();
        }
    iPreservedEvents.Reset();
    eventCount =  iRequestCompleteEvents.Count();
    for( TInt ix = 0; ix < eventCount ; ix++ )
        {
        iRequestCompleteEvents[ ix ]->Close();
        }
    iRequestCompleteEvents.Reset();
    }


// ---------------------------------------------------------------------------
// CXIMPContextEventQueue::CXIMPContextEventQueue()
// ---------------------------------------------------------------------------
//
CXIMPContextEventQueue::CXIMPContextEventQueue()
    {
    }


// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::ConstructL()
// -----------------------------------------------------------------------------
//
void CXIMPContextEventQueue::ConstructL()
    {
    iEventFilter = CXIMPContextEventFilter::NewL();
    CXIMPContextStateEventImp* tempEvent =
            CXIMPContextStateEventImp::NewLC();
            
    for( TInt a = 0; a < 6; ++a ) // Count of different states + complete
        {
        AddPreservedEventL( *tempEvent );
        }
        
    CleanupStack::PopAndDestroy(); // tempEvent
    StopConsuming();
    }


// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::SetEventFilter()
// -----------------------------------------------------------------------------
//
EXPORT_C void CXIMPContextEventQueue::SetEventFilter(
    CXIMPContextEventFilter& aFilter )
    {
    delete iEventFilter;
    iEventFilter = &aFilter;

    //Refilter event queue so we don't deliver such events
    //that client isn't wanting
    TInt eventCount =  iPreservedEvents.Count();
    for( TInt ix = 0; ix < eventCount ; ix++ )
        {
        CXIMPEventCapsule* event = iPreservedEvents[ ix ];
        if( !iEventFilter->IsEventAccepted( event->EventType() ) &&
            event->Ready() )
            {
            event->SetReady( EFalse );
            }
        }

    eventCount =  iEvents.Count() - 1;
    for( TInt ix = eventCount; ix >= 0 ; ix-- )
        {
        CXIMPEventCapsule* event = iEvents[ ix ];
        if( !iEventFilter->IsEventAccepted( event->EventType() ) )
            {
            event->Close();
            iEvents.Remove( ix );
            }
        }
    }


// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::StartConsuming()
// -----------------------------------------------------------------------------
//
EXPORT_C void CXIMPContextEventQueue::StartConsuming(
    MXIMPEventQueueObserver& aQueueObserver )
    {
    iObserver = &aQueueObserver;
    }


// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::StopConsuming()
// -----------------------------------------------------------------------------
//
EXPORT_C void CXIMPContextEventQueue::StopConsuming()
    {
    iObserver = NULL;
    ClearQueuedEvents();
    }


// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::HasElements()
// -----------------------------------------------------------------------------
//
EXPORT_C TBool CXIMPContextEventQueue::HasElements() const
    {
    TInt eventCount = iPreservedEvents.Count();
    TInt count = 0;
    for( TInt a = 0; a < eventCount; ++a )
        {
        if( iPreservedEvents[ a ]->Ready() )
            {
            ++count;
            }
        }

    eventCount = iRequestCompleteEvents.Count();
    for( TInt a = 0; a < eventCount; ++a )
        {
        if( iRequestCompleteEvents[ a ]->Ready() )
            {
            ++count;
            }
        }

    return ( iEvents.Count() + count > 0 );
    }


// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::FindNextEvent()
// -----------------------------------------------------------------------------
//
TBool CXIMPContextEventQueue::FindNextEvent( RPointerArray< CXIMPEventCapsule >& aArray )
    {
    TInt eventIndex = KErrNotFound;
    TInt eventCount = aArray.Count();
    for( TInt a = 0; a < eventCount; ++a )
        {
        if( aArray[ a ]->Ready() )
            {
            if( iNextEventToGo )
                {
                if( *aArray[ a ] < *iNextEventToGo )
                    {
                    eventIndex = a;
                    iNextEventToGo = aArray[ a ];
                    }
                }
            else
                {
                eventIndex = a;
                iNextEventToGo = aArray[ a ];
                }            
            }
        }
    return eventIndex;
    }

// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::SelectTopEventIfNeededL()
// -----------------------------------------------------------------------------
//
EXPORT_C void CXIMPContextEventQueue::SelectTopEventIfNeededL()
    {
    if( iNextEventToGo )
        {
        return;
        }

    __ASSERT_ALWAYS( HasElements(), User::Leave( KErrNotFound ) );

    TInt presEvent = FindNextEvent( iPreservedEvents );
    TInt reqEvent = FindNextEvent( iRequestCompleteEvents );
    TInt event = FindNextEvent( iEvents );

    if( event != KErrNotFound )
        {
        iEvents.Remove( event );
        }
    else if( reqEvent != KErrNotFound )
        {
        iRequestCompleteEvents.Remove( reqEvent );
        }
    else
        {
        if(iNextEventToGo)
         {
         User::LeaveIfError(iNextEventToGo->Open()); //Open always return KErrNone.      
         }              
        }
    }

// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::TopEventDataL()
// -----------------------------------------------------------------------------
//
EXPORT_C const TDesC8& CXIMPContextEventQueue::TopEventDataL()
    {
    __ASSERT_ALWAYS( iNextEventToGo,
                     User::Leave( KErrNotFound ) );
                     
    return iNextEventToGo->EventData();
    }


// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::TopEventReqIdL()
// -----------------------------------------------------------------------------
//
EXPORT_C TXIMPRequestId CXIMPContextEventQueue::TopEventReqIdL()
    {
    __ASSERT_ALWAYS( iNextEventToGo,
                     User::Leave( KErrNotFound ) );
                     
    return iNextEventToGo->EventReqId();
    }
    

// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::DropTopEvent()
// -----------------------------------------------------------------------------
//
EXPORT_C void CXIMPContextEventQueue::DropTopEvent()
    {
    if( iNextEventToGo )
        {
        iNextEventToGo->SetReady( EFalse ); // For preserved events
        iNextEventToGo->Close();
        iNextEventToGo = NULL;
        }
    }


// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::AddEventL()
// -----------------------------------------------------------------------------
//
void CXIMPContextEventQueue::AddEventL( CXIMPEventCapsule& aEvent )
    {
    // Queue accepts the event if:
    // 1. it has a registered observer
    // 2. event type is a accepted one
    TInt32 eventType = aEvent.EventType();
    if( eventType == MXIMPRequestCompleteEvent::KInterfaceId )
        {
        aEvent.SetReady( EFalse );
        iRequestCompleteEvents.AppendL( &aEvent );
        User::LeaveIfError(aEvent.Open()); //Open always return KErrNone.  
        }
    else if( iObserver &&
        iEventFilter->IsEventAccepted( eventType ) )
        {
        iEvents.AppendL( &aEvent );
        User::LeaveIfError(aEvent.Open()); //Open always return KErrNone.  
        aEvent.SetTimeStamp( iTimeStamp++ );
        iObserver->NewEventAvailable();
        }
    }

// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::AddPreservedEventL()
// -----------------------------------------------------------------------------
//
void CXIMPContextEventQueue::AddPreservedEventL( CXIMPApiEventBase& aEvent )
    {
    // Queue accepts the event always. Activation uses filter.
    CXIMPEventCapsule* capsulatedEvent = CXIMPEventCapsule::NewL( aEvent, EFalse );
    CleanupClosePushL( *capsulatedEvent );
    iPreservedEvents.AppendL( capsulatedEvent );
    CleanupStack::Pop( capsulatedEvent );
    }

// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::ActivatePreservedEventL()
// -----------------------------------------------------------------------------
//
void CXIMPContextEventQueue::ActivatePreservedEventL( CXIMPApiEventBase& aEvent )
    {
    if( iObserver )
        {
        TInt eventCount = iPreservedEvents.Count();
        for( TInt a = 0; a < eventCount; ++a )
            {
            if( !iPreservedEvents[ a ]->Ready() )
                {
                iPreservedEvents[ a ]->UpdateEventDataL( aEvent );
                if( iEventFilter->IsEventAccepted( iPreservedEvents[ a ]->EventType() ) )
                    {
                    iPreservedEvents[ a ]->SetReady( ETrue );
                    iPreservedEvents[ a ]->SetTimeStamp( iTimeStamp++ );
                    iObserver->NewEventAvailable();
                    }
                return;
                }
            }
        }
    }

// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::ActivateRequestCompleteEvent()
// -----------------------------------------------------------------------------
//
void CXIMPContextEventQueue::ActivateRequestCompleteEvent( CXIMPRequestCompleteEventImp& aEvent )
    {
    TInt eventCount = iRequestCompleteEvents.Count();
    for( TInt a = 0; a < eventCount; ++a )
        {
        if( iRequestCompleteEvents[ a ]->EventReqId() == aEvent.RequestId() )
            {
            if( iObserver )
                {
                if( iEventFilter->IsEventAccepted( iRequestCompleteEvents[ a ]->EventType() ) )
                    {
                    iRequestCompleteEvents[ a ]->UpdateEventData( aEvent );
                    iRequestCompleteEvents[ a ]->SetReady( ETrue );
                    iRequestCompleteEvents[ a ]->SetTimeStamp( iTimeStamp++ );
                    iObserver->NewEventAvailable();
                    }
                }
            else
                {
                iRequestCompleteEvents[ a ]->Close();
                iRequestCompleteEvents.Remove( a );
                }
            return;
            }
        }
    }

// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::ActivateRequestCompleteEvent()
// -----------------------------------------------------------------------------
//
void CXIMPContextEventQueue::RemoveRequestCompleteEvent( CXIMPRequestCompleteEventImp& aEvent )
    {
    TInt eventCount = iRequestCompleteEvents.Count();
    for( TInt a = 0; a < eventCount; ++a )
        {
        if( iRequestCompleteEvents[ a ]->EventReqId() == aEvent.RequestId() )
            {
            iRequestCompleteEvents[ a ]->Close();
            iRequestCompleteEvents.Remove( a );
            return;
            }
        }
    }

// -----------------------------------------------------------------------------
// CXIMPContextEventQueue::ClearQueuedEvents()
// -----------------------------------------------------------------------------
//
void CXIMPContextEventQueue::ClearQueuedEvents()
    {
    const TInt eventCount =  iEvents.Count();
    for( TInt ix = 0; ix < eventCount ; ix++ )
        {
        iEvents[ ix ]->Close();
        }

    iEvents.Reset();
    if( iNextEventToGo )
        {
        iNextEventToGo->Close();
        iNextEventToGo = NULL;
        }
    }

// End of file