mmfenh/enhancedmediaclient/Client/src/Components/EventNotifier/EventNotifier.cpp
changeset 0 71ca22bcf22a
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     1 /*
       
     2 * Copyright (c) 2006 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:  Implementation of EventNotifier class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include "EventNotifier.h"
       
    21 #include "EventBase.h"
       
    22 #include <ControlObserver.h>
       
    23 
       
    24 #include "tracemacros.h"
       
    25 
       
    26 using namespace multimedia;
       
    27 
       
    28 const TInt KInvalidIndex = -1;
       
    29 
       
    30 ///////////////////////////////////////////////////////////////////////////////
       
    31 //                  CObserverManager
       
    32 ///////////////////////////////////////////////////////////////////////////////
       
    33 
       
    34 CObserverManager::CObserverManager()
       
    35 :iObserverCount(0),
       
    36 iCurrentObserverIndex(KInvalidIndex)
       
    37 
       
    38     {
       
    39     // No impl
       
    40     }
       
    41 
       
    42 CObserverManager::~CObserverManager()
       
    43     {
       
    44     iObserversList.Reset();
       
    45     iActiveList.Reset();
       
    46     iObserversList.Close();
       
    47     iActiveList.Close();
       
    48     }
       
    49 
       
    50 CObserverManager* CObserverManager::NewL()
       
    51     {
       
    52     CObserverManager* self = new (ELeave)CObserverManager;
       
    53     CleanupStack::PushL(self);
       
    54     self->ConstructL();
       
    55     CleanupStack::Pop(self);
       
    56     return self;
       
    57     }
       
    58 void CObserverManager::ConstructL()
       
    59     {
       
    60 
       
    61     }
       
    62 
       
    63 // Adds observer to list
       
    64 TInt CObserverManager::AddObserver( const MControlObserver& aObserver )
       
    65     {
       
    66     // Add to list if observer is not already added
       
    67     TInt status = iObserversList.Find(&aObserver);
       
    68     if ( status == KErrNotFound )
       
    69         {
       
    70         status = iObserversList.Append(&aObserver);
       
    71         status = iActiveList.Append(ETrue);
       
    72         // Update count
       
    73         iObserverCount++;
       
    74         }
       
    75     else
       
    76         {
       
    77         status = KErrAlreadyExists;
       
    78         }
       
    79     return status;
       
    80     }
       
    81 
       
    82 // Marks observer as inactive in the list
       
    83 TInt CObserverManager::RemoveObserver( const MControlObserver& aObserver )
       
    84     {
       
    85     TInt status = iObserversList.Find(&aObserver);
       
    86     // If found status has index to observer in the array
       
    87     // else it would contain KErrNotFound
       
    88     if ( status >= 0 )
       
    89         {
       
    90         // Mark the observer as inactive, but remove it later in Purge();
       
    91         iActiveList[status] = EFalse;
       
    92         // Update count
       
    93         iObserverCount--;
       
    94         status = KErrNone;
       
    95         }
       
    96     return status;
       
    97     }
       
    98 
       
    99 // Moves the pointer to element before the first in list
       
   100 void CObserverManager::Init()
       
   101     {
       
   102     iCurrentObserverIndex = KInvalidIndex;
       
   103     }
       
   104 
       
   105 // Moves the pointer to next active observer. Client should
       
   106 // call this after Init() to get to the first element.
       
   107 TBool CObserverManager::Next()
       
   108     {
       
   109     TBool status(EFalse);
       
   110     // Starting from the next index count find an active observer
       
   111     TInt i(iCurrentObserverIndex+1);
       
   112     // Assume that we are not going to find one.
       
   113     iCurrentObserverIndex = KInvalidIndex;
       
   114     for (; i< iActiveList.Count(); i++)
       
   115         {
       
   116         if ( iActiveList[i] == TInt(ETrue) )
       
   117             { // We have found an active observer in the list
       
   118             iCurrentObserverIndex = i;
       
   119             status = ETrue;
       
   120             break;
       
   121             }
       
   122         }
       
   123     return status;
       
   124     }
       
   125 
       
   126 // Returns a reference to current observer
       
   127 void CObserverManager::Observer( MControlObserver*& aObserver )
       
   128     {
       
   129     if ( iCurrentObserverIndex == KInvalidIndex )
       
   130         {
       
   131         aObserver = NULL;
       
   132         }
       
   133     else
       
   134         {
       
   135         aObserver = iObserversList[iCurrentObserverIndex];
       
   136         }
       
   137     }
       
   138 
       
   139 // Returns the count of active observers
       
   140 TInt CObserverManager::Count()
       
   141     {
       
   142     return iObserverCount;
       
   143     }
       
   144 
       
   145 // Purge inactive observers in the list
       
   146 void CObserverManager::Purge()
       
   147     {
       
   148     TInt index(0);
       
   149     iObserverCount = 0; // Recalculate observer count
       
   150     while (index < iActiveList.Count())
       
   151         {
       
   152         if ( iActiveList[index] == TInt(EFalse) )
       
   153             {
       
   154             iObserversList.Remove(index);
       
   155             iActiveList.Remove(index);
       
   156             }
       
   157         else
       
   158             {
       
   159             iObserverCount++;
       
   160             index++;
       
   161             }
       
   162         }
       
   163     }
       
   164 
       
   165 // Resets the list
       
   166 void CObserverManager::Reset()
       
   167     {
       
   168     iCurrentObserverIndex = KInvalidIndex;
       
   169     iObserverCount = 0;
       
   170     iObserversList.Reset();
       
   171     iActiveList.Reset();
       
   172     }
       
   173 
       
   174 
       
   175 ///////////////////////////////////////////////////////////////////////////////
       
   176 //                  CEventQueueItem
       
   177 ///////////////////////////////////////////////////////////////////////////////
       
   178 
       
   179 CEventQueueItem::CEventQueueItem(MControl* aControl, TUint aEvent, CEventBase* aEventObject )
       
   180 : iEvent( aEvent), iEventObject(aEventObject),iControl(aControl)
       
   181     {
       
   182     }
       
   183 
       
   184 CEventQueueItem::~CEventQueueItem()
       
   185     {
       
   186     if ( iEventObject )
       
   187         {
       
   188         delete iEventObject;
       
   189         }
       
   190     }
       
   191 
       
   192 CEventQueueItem* CEventQueueItem::NewL(MControl* aControl, TUint aEvent, CEventBase* aEventObject )
       
   193     {
       
   194     CEventQueueItem* self = new (ELeave)CEventQueueItem( aControl,aEvent, aEventObject );
       
   195     CleanupStack::PushL(self);
       
   196     self->ConstructL();
       
   197     CleanupStack::Pop(self);
       
   198     return self;
       
   199     }
       
   200 
       
   201 void CEventQueueItem::ConstructL()
       
   202     {
       
   203     // No impl
       
   204     }
       
   205 
       
   206 TUint CEventQueueItem::EventType()
       
   207     {
       
   208     return iEvent;
       
   209     }
       
   210 
       
   211 MControl* CEventQueueItem::ControlObject()
       
   212     {
       
   213     return iControl;
       
   214     }
       
   215 
       
   216 CEventBase* CEventQueueItem::EventObject()
       
   217     {
       
   218     return iEventObject;
       
   219     }
       
   220 
       
   221 TAny* CEventQueueItem::GetInterface()
       
   222     {
       
   223     if ( iEventObject )
       
   224         return iEventObject->GetInterface();
       
   225     else
       
   226         return NULL;
       
   227     }
       
   228 
       
   229 ///////////////////////////////////////////////////////////////////////////////
       
   230 //                  CObserverManager
       
   231 ///////////////////////////////////////////////////////////////////////////////
       
   232 
       
   233 CEventNotifier::CEventNotifier()
       
   234 : CActive( CActive::EPriorityStandard )
       
   235     {
       
   236     CActiveScheduler::Add(this);
       
   237     }
       
   238 
       
   239 CEventNotifier::~CEventNotifier()
       
   240     {
       
   241     Cancel();
       
   242     delete iObserverManager;
       
   243     EmptyQueue();
       
   244     delete iEventQueue;
       
   245     }
       
   246 
       
   247 CEventNotifier* CEventNotifier::NewL()
       
   248     {
       
   249     CEventNotifier* self = new (ELeave)CEventNotifier;
       
   250     CleanupStack::PushL(self);
       
   251     self->ConstructL();
       
   252     CleanupStack::Pop(self);
       
   253     return self;
       
   254     }
       
   255 
       
   256 void CEventNotifier::ConstructL()
       
   257     {
       
   258     iObserverManager = CObserverManager::NewL();
       
   259     iEventQueue = new(ELeave) TSglQue<CEventQueueItem>(_FOFF(CEventQueueItem, iLink));
       
   260     }
       
   261 
       
   262 // Adds observer
       
   263 TInt CEventNotifier::AddObserver( const MControlObserver& aObserver )
       
   264     {
       
   265     return iObserverManager->AddObserver(aObserver);
       
   266     }
       
   267 
       
   268 // Remove observer
       
   269 TInt CEventNotifier::RemoveObserver( const MControlObserver& aObserver )
       
   270     {
       
   271     return iObserverManager->RemoveObserver(aObserver);
       
   272     }
       
   273 
       
   274 // Send notification to observers. If another event is
       
   275 // being processed, this will append event to queue and observers will
       
   276 // be notified after current event is notified
       
   277 TInt CEventNotifier::Event(MControl* aControl, TUint aEvent, CEventBase* aEventObject )
       
   278     {
       
   279     CEventQueueItem* item(NULL);
       
   280     TInt status(KErrNone);
       
   281     // If there are no observers in the list, just delete the event and return
       
   282     if ( iObserverManager->Count() == 0 )
       
   283         {
       
   284         EMC_TRACE2(_L("CEventNotifier::Event:No observers for this event[%d]"), aEvent);
       
   285         delete aEventObject;
       
   286         }
       
   287     else // Observer list is not empty, proceed notifying observers
       
   288         {
       
   289         TRAP( status, item = CEventQueueItem::NewL(aControl, aEvent, aEventObject ) );
       
   290         if ( status == KErrNone )
       
   291             {
       
   292             iEventQueue->AddLast(*item);
       
   293             KickSignal();
       
   294             }
       
   295         }
       
   296     return status;
       
   297     }
       
   298 
       
   299 void CEventNotifier::KickSignal()
       
   300     {
       
   301     if (!IsActive())
       
   302         {
       
   303         TRequestStatus* s = &iStatus;
       
   304         SetActive();
       
   305         User::RequestComplete( s, KErrNone );
       
   306         }
       
   307     }
       
   308 void CEventNotifier::EventNotified()
       
   309     {
       
   310     CEventQueueItem* eventItem = iEventQueue->First();
       
   311     iEventQueue->Remove(*eventItem);
       
   312     delete eventItem;
       
   313     iObserverManager->Init();
       
   314     }
       
   315 
       
   316 void CEventNotifier::RunL()
       
   317     {
       
   318     if ( !iEventQueue-> IsEmpty() && (iStatus == KErrNone) )
       
   319         {
       
   320         // Get the current item from the observer list
       
   321         if ( iObserverManager->Next() )
       
   322             {
       
   323             MControlObserver* observer(NULL);
       
   324             iObserverManager->Observer(observer);
       
   325             if ( observer ) // Just to make sure. This should never happen
       
   326                 {
       
   327                 CEventQueueItem* eventItem = iEventQueue->First();
       
   328                 observer->Event(eventItem->ControlObject(), eventItem->EventType(), eventItem->GetInterface() );
       
   329                 }
       
   330 #ifdef _DEBUG
       
   331             else
       
   332                 {
       
   333                 EMC_TRACE1(_L("CEventNotifier::RunL:ERROR[Observer reference is NULL]"));
       
   334                 }
       
   335 #endif // _DEBUG
       
   336             }
       
   337         else // if ( iObserverManager->Next() )
       
   338             { // There are no more observers in the list, all observers are
       
   339             // notified of this event.
       
   340             EventNotified();
       
   341             }
       
   342         KickSignal();
       
   343         }
       
   344     }
       
   345 
       
   346 void CEventNotifier::DoCancel()
       
   347     {
       
   348 
       
   349     }
       
   350 
       
   351 TInt CEventNotifier::RunError(TInt /*aError*/)
       
   352     {
       
   353     return KErrNone;
       
   354     }
       
   355 
       
   356 void CEventNotifier::EmptyQueue()
       
   357     {
       
   358     CEventQueueItem* item;
       
   359     while ( !iEventQueue->IsEmpty() )
       
   360         {
       
   361         item = iEventQueue->First();
       
   362         iEventQueue->Remove(*item);
       
   363         delete item;
       
   364         }
       
   365     }
       
   366 // End of file