mmfenh/enhancedmediaclient/Client/src/Components/EventNotifier/EventNotifier.cpp
changeset 0 71ca22bcf22a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmfenh/enhancedmediaclient/Client/src/Components/EventNotifier/EventNotifier.cpp	Tue Feb 02 01:08:46 2010 +0200
@@ -0,0 +1,366 @@
+/*
+* 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 EventNotifier class.
+*
+*/
+
+
+
+#include "EventNotifier.h"
+#include "EventBase.h"
+#include <ControlObserver.h>
+
+#include "tracemacros.h"
+
+using namespace multimedia;
+
+const TInt KInvalidIndex = -1;
+
+///////////////////////////////////////////////////////////////////////////////
+//                  CObserverManager
+///////////////////////////////////////////////////////////////////////////////
+
+CObserverManager::CObserverManager()
+:iObserverCount(0),
+iCurrentObserverIndex(KInvalidIndex)
+
+    {
+    // No impl
+    }
+
+CObserverManager::~CObserverManager()
+    {
+    iObserversList.Reset();
+    iActiveList.Reset();
+    iObserversList.Close();
+    iActiveList.Close();
+    }
+
+CObserverManager* CObserverManager::NewL()
+    {
+    CObserverManager* self = new (ELeave)CObserverManager;
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+void CObserverManager::ConstructL()
+    {
+
+    }
+
+// Adds observer to list
+TInt CObserverManager::AddObserver( const MControlObserver& aObserver )
+    {
+    // Add to list if observer is not already added
+    TInt status = iObserversList.Find(&aObserver);
+    if ( status == KErrNotFound )
+        {
+        status = iObserversList.Append(&aObserver);
+        status = iActiveList.Append(ETrue);
+        // Update count
+        iObserverCount++;
+        }
+    else
+        {
+        status = KErrAlreadyExists;
+        }
+    return status;
+    }
+
+// Marks observer as inactive in the list
+TInt CObserverManager::RemoveObserver( const MControlObserver& aObserver )
+    {
+    TInt status = iObserversList.Find(&aObserver);
+    // If found status has index to observer in the array
+    // else it would contain KErrNotFound
+    if ( status >= 0 )
+        {
+        // Mark the observer as inactive, but remove it later in Purge();
+        iActiveList[status] = EFalse;
+        // Update count
+        iObserverCount--;
+        status = KErrNone;
+        }
+    return status;
+    }
+
+// Moves the pointer to element before the first in list
+void CObserverManager::Init()
+    {
+    iCurrentObserverIndex = KInvalidIndex;
+    }
+
+// Moves the pointer to next active observer. Client should
+// call this after Init() to get to the first element.
+TBool CObserverManager::Next()
+    {
+    TBool status(EFalse);
+    // Starting from the next index count find an active observer
+    TInt i(iCurrentObserverIndex+1);
+    // Assume that we are not going to find one.
+    iCurrentObserverIndex = KInvalidIndex;
+    for (; i< iActiveList.Count(); i++)
+        {
+        if ( iActiveList[i] == TInt(ETrue) )
+            { // We have found an active observer in the list
+            iCurrentObserverIndex = i;
+            status = ETrue;
+            break;
+            }
+        }
+    return status;
+    }
+
+// Returns a reference to current observer
+void CObserverManager::Observer( MControlObserver*& aObserver )
+    {
+    if ( iCurrentObserverIndex == KInvalidIndex )
+        {
+        aObserver = NULL;
+        }
+    else
+        {
+        aObserver = iObserversList[iCurrentObserverIndex];
+        }
+    }
+
+// Returns the count of active observers
+TInt CObserverManager::Count()
+    {
+    return iObserverCount;
+    }
+
+// Purge inactive observers in the list
+void CObserverManager::Purge()
+    {
+    TInt index(0);
+    iObserverCount = 0; // Recalculate observer count
+    while (index < iActiveList.Count())
+        {
+        if ( iActiveList[index] == TInt(EFalse) )
+            {
+            iObserversList.Remove(index);
+            iActiveList.Remove(index);
+            }
+        else
+            {
+            iObserverCount++;
+            index++;
+            }
+        }
+    }
+
+// Resets the list
+void CObserverManager::Reset()
+    {
+    iCurrentObserverIndex = KInvalidIndex;
+    iObserverCount = 0;
+    iObserversList.Reset();
+    iActiveList.Reset();
+    }
+
+
+///////////////////////////////////////////////////////////////////////////////
+//                  CEventQueueItem
+///////////////////////////////////////////////////////////////////////////////
+
+CEventQueueItem::CEventQueueItem(MControl* aControl, TUint aEvent, CEventBase* aEventObject )
+: iEvent( aEvent), iEventObject(aEventObject),iControl(aControl)
+    {
+    }
+
+CEventQueueItem::~CEventQueueItem()
+    {
+    if ( iEventObject )
+        {
+        delete iEventObject;
+        }
+    }
+
+CEventQueueItem* CEventQueueItem::NewL(MControl* aControl, TUint aEvent, CEventBase* aEventObject )
+    {
+    CEventQueueItem* self = new (ELeave)CEventQueueItem( aControl,aEvent, aEventObject );
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+void CEventQueueItem::ConstructL()
+    {
+    // No impl
+    }
+
+TUint CEventQueueItem::EventType()
+    {
+    return iEvent;
+    }
+
+MControl* CEventQueueItem::ControlObject()
+    {
+    return iControl;
+    }
+
+CEventBase* CEventQueueItem::EventObject()
+    {
+    return iEventObject;
+    }
+
+TAny* CEventQueueItem::GetInterface()
+    {
+    if ( iEventObject )
+        return iEventObject->GetInterface();
+    else
+        return NULL;
+    }
+
+///////////////////////////////////////////////////////////////////////////////
+//                  CObserverManager
+///////////////////////////////////////////////////////////////////////////////
+
+CEventNotifier::CEventNotifier()
+: CActive( CActive::EPriorityStandard )
+    {
+    CActiveScheduler::Add(this);
+    }
+
+CEventNotifier::~CEventNotifier()
+    {
+    Cancel();
+    delete iObserverManager;
+    EmptyQueue();
+    delete iEventQueue;
+    }
+
+CEventNotifier* CEventNotifier::NewL()
+    {
+    CEventNotifier* self = new (ELeave)CEventNotifier;
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+void CEventNotifier::ConstructL()
+    {
+    iObserverManager = CObserverManager::NewL();
+    iEventQueue = new(ELeave) TSglQue<CEventQueueItem>(_FOFF(CEventQueueItem, iLink));
+    }
+
+// Adds observer
+TInt CEventNotifier::AddObserver( const MControlObserver& aObserver )
+    {
+    return iObserverManager->AddObserver(aObserver);
+    }
+
+// Remove observer
+TInt CEventNotifier::RemoveObserver( const MControlObserver& aObserver )
+    {
+    return iObserverManager->RemoveObserver(aObserver);
+    }
+
+// Send notification to observers. If another event is
+// being processed, this will append event to queue and observers will
+// be notified after current event is notified
+TInt CEventNotifier::Event(MControl* aControl, TUint aEvent, CEventBase* aEventObject )
+    {
+    CEventQueueItem* item(NULL);
+    TInt status(KErrNone);
+    // If there are no observers in the list, just delete the event and return
+    if ( iObserverManager->Count() == 0 )
+        {
+        EMC_TRACE2(_L("CEventNotifier::Event:No observers for this event[%d]"), aEvent);
+        delete aEventObject;
+        }
+    else // Observer list is not empty, proceed notifying observers
+        {
+        TRAP( status, item = CEventQueueItem::NewL(aControl, aEvent, aEventObject ) );
+        if ( status == KErrNone )
+            {
+            iEventQueue->AddLast(*item);
+            KickSignal();
+            }
+        }
+    return status;
+    }
+
+void CEventNotifier::KickSignal()
+    {
+    if (!IsActive())
+        {
+        TRequestStatus* s = &iStatus;
+        SetActive();
+        User::RequestComplete( s, KErrNone );
+        }
+    }
+void CEventNotifier::EventNotified()
+    {
+    CEventQueueItem* eventItem = iEventQueue->First();
+    iEventQueue->Remove(*eventItem);
+    delete eventItem;
+    iObserverManager->Init();
+    }
+
+void CEventNotifier::RunL()
+    {
+    if ( !iEventQueue-> IsEmpty() && (iStatus == KErrNone) )
+        {
+        // Get the current item from the observer list
+        if ( iObserverManager->Next() )
+            {
+            MControlObserver* observer(NULL);
+            iObserverManager->Observer(observer);
+            if ( observer ) // Just to make sure. This should never happen
+                {
+                CEventQueueItem* eventItem = iEventQueue->First();
+                observer->Event(eventItem->ControlObject(), eventItem->EventType(), eventItem->GetInterface() );
+                }
+#ifdef _DEBUG
+            else
+                {
+                EMC_TRACE1(_L("CEventNotifier::RunL:ERROR[Observer reference is NULL]"));
+                }
+#endif // _DEBUG
+            }
+        else // if ( iObserverManager->Next() )
+            { // There are no more observers in the list, all observers are
+            // notified of this event.
+            EventNotified();
+            }
+        KickSignal();
+        }
+    }
+
+void CEventNotifier::DoCancel()
+    {
+
+    }
+
+TInt CEventNotifier::RunError(TInt /*aError*/)
+    {
+    return KErrNone;
+    }
+
+void CEventNotifier::EmptyQueue()
+    {
+    CEventQueueItem* item;
+    while ( !iEventQueue->IsEmpty() )
+        {
+        item = iEventQueue->First();
+        iEventQueue->Remove(*item);
+        delete item;
+        }
+    }
+// End of file