--- /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