--- /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<CVPbkSimCommandStore*>( 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<CVPbkSimCommandStore*>( 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