diff -r 000000000000 -r e686773b3f54 phonebookengines/VirtualPhonebook/VPbkSimStoreImpl/src/CVPbkSimCommandStore.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/VirtualPhonebook/VPbkSimStoreImpl/src/CVPbkSimCommandStore.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,356 @@ +/* +* Copyright (c) 2002-2007 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: A command store for handling lifetime of the commands +* +*/ + + + +// INCLUDE FILES +#include "CVPbkSimCommandStore.h" +#include "VPbkSimStoreImplError.h" +#include "MVPbkSimCommand.h" + +// DATA TYPES + +namespace +{ + +/** +* The state of the command +*/ +enum TCommandState + { + /// command is active + EExecuting, + /// command is waiting to be executed + EWaiting, + /// command is wating to be deleted + EToBeDeleted + }; +} + +// ============================ MEMBER FUNCTIONS =============================== + +/** +* A simple helper class to know which commands should be deleted +*/ +NONSHARABLE_CLASS( CVPbkSimCommandStore::CCmd ): public CBase + { + public: + CCmd( MVPbkSimCommand* aCommand ); + ~CCmd(); + + public: // Data + MVPbkSimCommand* iCommand; + TCommandState iState; + }; + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::CCmd::CCmd +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CVPbkSimCommandStore::CCmd::CCmd( MVPbkSimCommand* aCommand ) +: iCommand( aCommand ) + { + } + +CVPbkSimCommandStore::CCmd::~CCmd() + { + delete iCommand; + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::CVPbkSimCommandStore +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CVPbkSimCommandStore::CVPbkSimCommandStore( TBool aExecuteOneAtTime ) +: iExecuteOneAtTime( aExecuteOneAtTime ) + { + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CVPbkSimCommandStore::ConstructL() + { + iIdleDestroyer = CIdle::NewL( CActive::EPriorityIdle ); + iIdleCmdRunner = CIdle::NewL( CActive::EPriorityStandard ); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CVPbkSimCommandStore* CVPbkSimCommandStore::NewL( + TBool aExecuteOneAtTime ) + { + CVPbkSimCommandStore* self = + new( ELeave ) CVPbkSimCommandStore( aExecuteOneAtTime ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// Destructor +CVPbkSimCommandStore::~CVPbkSimCommandStore() + { + delete iIdleCmdRunner; + delete iIdleDestroyer; + iCmdArray.ResetAndDestroy(); + iCmdArray.Close(); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::AddAndExecuteCommandL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVPbkSimCommandStore::AddAndExecuteCommandL( + MVPbkSimCommand* aCommand ) + { + CleanupDeletePushL( aCommand ); + CCmd* cmd = new( ELeave ) CCmd( aCommand ); + CleanupStack::Pop( aCommand ); + CleanupStack::PushL( cmd ); + iCmdArray.AppendL( cmd ); + CleanupStack::Pop( cmd ); + + aCommand->AddObserverL( *this ); + + if ( iExecuteOneAtTime ) + { + cmd->iState = EWaiting; + RunNextCommand(); + } + else + { + cmd->iState = EExecuting; + aCommand->Execute(); + } + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::CancelAll +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVPbkSimCommandStore::CancelAll() + { + const TInt count = iCmdArray.Count(); + for ( TInt i = 0; i < count; ++i ) + { + if ( iCmdArray[i]->iState == EExecuting || + iCmdArray[i]->iState == EWaiting ) + { + iCmdArray[i]->iCommand->CancelCmd(); + } + iCmdArray[i]->iState = EToBeDeleted; + } + + StartAsyncDelete(); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::CancelCommand +// ----------------------------------------------------------------------------- +// +EXPORT_C void CVPbkSimCommandStore::CancelCommand( MVPbkSimCommand& aCommand ) + { + TInt pos = FindCommandPosition( aCommand ); + if ( pos >= 0 ) + { + if ( iCmdArray[pos]->iState == EExecuting ) + { + /// Run next waiting command if exists + StartAsyncCommandRunner(); + } + + if ( iCmdArray[pos]->iState != EToBeDeleted ) + { + // Cancel it. + iCmdArray[pos]->iCommand->CancelCmd(); + // Set command to delete state... + iCmdArray[pos]->iState = EToBeDeleted; + // ...and start idle deletion + StartAsyncDelete(); + } + } + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::Executing +// ----------------------------------------------------------------------------- +// +TBool CVPbkSimCommandStore::Executing() const + { + TInt count = iCmdArray.Count(); + for ( TInt i = 0; i < count; ++i ) + { + if ( iCmdArray[i]->iState == EExecuting ) + { + return ETrue; + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::CommandDone +// ----------------------------------------------------------------------------- +// +void CVPbkSimCommandStore::CommandDone( MVPbkSimCommand& aCommand ) + { + HandleCommandComplete( aCommand ); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::CommandError +// ----------------------------------------------------------------------------- +// +void CVPbkSimCommandStore::CommandError( MVPbkSimCommand& aCommand, + TInt /*aError*/ ) + { + HandleCommandComplete( aCommand ); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::RunNextCommand +// ----------------------------------------------------------------------------- +// +void CVPbkSimCommandStore::RunNextCommand() + { + CVPbkSimCommandStore::CCmd* firstWaitingCmd = NULL; + TInt count = iCmdArray.Count(); + for ( TInt i = 0; i < count; ++i ) + { + if ( iCmdArray[i]->iState == EExecuting ) + { + // Active command found -> don't start next command + return; + } + else if ( iCmdArray[i]->iState == EWaiting ) + { + firstWaitingCmd = iCmdArray[i]; + /// first waiting command found -> break the loop and execute it + break; + } + } + + if ( firstWaitingCmd ) + { + firstWaitingCmd->iState = EExecuting; + firstWaitingCmd->iCommand->Execute(); + } + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::HandleCommandComplete +// ----------------------------------------------------------------------------- +// +void CVPbkSimCommandStore::HandleCommandComplete( MVPbkSimCommand& aCommand ) + { + TInt pos = FindCommandPosition( aCommand ); + if ( pos >= 0 ) + { + iCmdArray[pos]->iState = EToBeDeleted; + } + + StartAsyncDelete(); + StartAsyncCommandRunner(); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::StartAsyncDelete +// ----------------------------------------------------------------------------- +// +void CVPbkSimCommandStore::StartAsyncDelete() + { + iIdleDestroyer->Cancel(); + iIdleDestroyer->Start( + TCallBack( (&CVPbkSimCommandStore::IdleDestroyerCallback), this ) ); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::StartAsyncCommandRunner +// ----------------------------------------------------------------------------- +// +void CVPbkSimCommandStore::StartAsyncCommandRunner() + { + iIdleCmdRunner->Cancel(); + iIdleCmdRunner->Start( + TCallBack( ( &CmdRunnerCallback ), this ) ); + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::IdleDestroyerCallback +// ----------------------------------------------------------------------------- +// +TInt CVPbkSimCommandStore::IdleDestroyerCallback( TAny* aSelf ) + { + static_cast( aSelf )->DestroyCommands(); + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::DestroyCommands +// ----------------------------------------------------------------------------- +// +void CVPbkSimCommandStore::DestroyCommands() + { + TInt count = iCmdArray.Count(); + for ( TInt i = count - 1; i >= 0; --i ) + { + if ( iCmdArray[i]->iState == EToBeDeleted ) + { + delete iCmdArray[i]; + iCmdArray.Remove( i ); + } + } + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::CmdRunnerCallback +// ----------------------------------------------------------------------------- +// +TInt CVPbkSimCommandStore::CmdRunnerCallback( TAny* aSelf ) + { + static_cast( aSelf )->RunNextCommand(); + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CVPbkSimCommandStore::FindCommandPosition +// ----------------------------------------------------------------------------- +// +TInt CVPbkSimCommandStore::FindCommandPosition( MVPbkSimCommand& aCommand ) + { + TInt count = iCmdArray.Count(); + for ( TInt i = 0; i < count; ++i ) + { + if ( iCmdArray[i]->iCommand == &aCommand ) + { + return i; + } + } + return KErrNotFound; + } + +// End of File