phonebookengines/VirtualPhonebook/VPbkSimStoreImpl/src/CVPbkSimCommandStore.cpp
changeset 0 e686773b3f54
--- /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