idlefw/tsrc/devicestatusplugin/mt_devstaplg/DelayedFunctionCall.h
branchRCL_3
changeset 28 053c6c7c14f3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlefw/tsrc/devicestatusplugin/mt_devstaplg/DelayedFunctionCall.h	Thu Aug 19 10:13:44 2010 +0300
@@ -0,0 +1,712 @@
+/*
+* Copyright (c) 2009 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:
+*
+*/
+//DelayedFunctionCall.h
+//DFC caller and templated generic function call objects.
+
+#ifndef CDELAYEDFUNCTIONCALL_H__
+#define CDELAYEDFUNCTIONCALL_H__
+
+
+// INCLUDES
+#include <E32base.h>
+
+
+// CLASS DESCRIPTION
+
+/**
+ * Abstract interface for function call object.
+ */
+class MFunctionCall
+    {
+    public:
+
+        /**
+         * Function execution.
+         *
+         * Executes the function call.
+         *
+         * If function execution fails (e.g. leaves),
+         * leave code is stored in CDelayedFunctionCall host.
+         */
+        virtual void InvokeL() = 0;
+
+        virtual MFunctionCall* CloneLC() const = 0;
+
+
+        /**
+         * Public virtual destructor.
+         *
+         * Allows thus function call object deletion.
+         */
+        virtual ~MFunctionCall() {}
+    };
+
+
+
+// CLASS DESCRIPTION
+
+/**
+ * Delayed Function Call - caller.
+ *
+ * Executes DFC objects after given delay.
+ */
+class CDelayedFunctionCall : public CTimer
+    {
+    public: //Construction
+
+        static inline CDelayedFunctionCall* NewLC();
+        static inline CDelayedFunctionCall* NewL();
+        inline ~CDelayedFunctionCall();
+
+    public: //Delayed call
+
+        /**
+         * Issues DFC call. Panics if CDelayedFunctionCall object
+         * is already in use.
+         *
+         * @param aFC The FC object to execute.
+         * @param aCallDelay The delay when to execute the FC.
+         * @param aFCOwnershipTransf If ETrue, the aFC object
+         * ownership is transferred to DFC caller and DFC caller
+         * deletes object. If EFalse, no ownership transfer is done.
+         */
+        inline void IssueDfc( MFunctionCall& aFC, TInt aCallDelay, TBool aFCOwnershipTransf = ETrue );
+
+
+        /**
+         * Similar like IssueDfc() but pushes
+         * release to CleanupStack ==>
+         * if there happens a leave before the DFC gets scheduled,
+         * DFC is canceled.
+         */
+        inline void IssueDfcLC( MFunctionCall& aFC, TInt aCallDelay, TBool aFCOwnershipTransf = ETrue );
+
+
+        /**
+         * Releases the DFC.
+         * Cancels the call and deletes possibly owned FC.
+         */
+        inline void Release();
+
+
+        /**
+         * Delayed FC error handling.
+         */
+        inline void LeaveIfFcFailedL();
+
+        /**
+         * Tests was the FC executed or not.
+         */
+        inline TBool FcExecuted();
+
+
+    private:
+        inline CDelayedFunctionCall();
+        inline void RunL();
+        inline TInt RunError( TInt aError );
+        inline void InvokeL();
+
+
+    private:    //data
+
+        //REF/OWN: Function call object
+        MFunctionCall*    iFC;
+
+        //OWN: Is function call object owned
+        TBool    iFCOwned;
+
+        //OWN: Did function call leave
+        TBool   iFCLeft;
+
+        //OWN: Was function called
+        TBool   iFCCalled;
+
+        //OWN: Leave code from the function call
+        TInt    iFCLeaveErr;
+    };
+
+
+
+
+// -----------------------------------------------------------------------------
+// CDelayedFunctionCall public functions
+// -----------------------------------------------------------------------------
+//
+inline CDelayedFunctionCall* CDelayedFunctionCall::NewLC()
+    {
+    CDelayedFunctionCall* self = new (ELeave) CDelayedFunctionCall();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+inline CDelayedFunctionCall* CDelayedFunctionCall::NewL()
+    {
+    CDelayedFunctionCall* self = NewLC();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+inline CDelayedFunctionCall::~CDelayedFunctionCall()
+    {
+    Cancel();
+    if( iFCOwned )
+        {
+        delete iFC;
+        }
+    }
+
+
+inline void CDelayedFunctionCall::IssueDfc( MFunctionCall& aFC,
+                                            TInt aFCDelay,
+                                            TBool aFCOwnershipTransf )
+    {
+    __ASSERT_ALWAYS( !IsActive(), User::Panic( _L("DFC caller"), KErrInUse ) );
+
+    iFC = &aFC;
+    iFCOwned = aFCOwnershipTransf;
+    iFCLeft = EFalse;
+    iFCLeaveErr = KErrNone;
+    iFCCalled = EFalse;
+
+    if( aFCDelay >= 0 )
+        {
+        After( aFCDelay );
+        }
+    else
+        {
+        InvokeL();
+        }
+    }
+
+
+inline void CDelayedFunctionCall::IssueDfcLC( MFunctionCall& aFC,
+                                              TInt aFCDelay,
+                                              TBool aFCOwnershipTransf )
+    {
+    IssueDfc( aFC, aFCDelay, aFCOwnershipTransf );
+    CleanupReleasePushL( *this );
+    }
+
+
+inline void CDelayedFunctionCall::Release()
+    {
+    Cancel();
+    if( iFCOwned )
+        {
+        delete iFC;
+        iFC = NULL;
+        }
+    }
+
+inline void CDelayedFunctionCall::LeaveIfFcFailedL()
+    {
+    if( iFCLeft )
+        {
+        User::Leave( iFCLeaveErr );
+        }
+    }
+
+
+inline TBool CDelayedFunctionCall::FcExecuted()
+    {
+    return iFCCalled;
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CDelayedFunctionCall private functions
+// -----------------------------------------------------------------------------
+//
+inline CDelayedFunctionCall::CDelayedFunctionCall()
+    : CTimer( CActive::EPriorityHigh )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+inline void CDelayedFunctionCall::RunL()
+    {
+    InvokeL();
+    }
+
+inline TInt CDelayedFunctionCall::RunError( TInt aError )
+    {
+    iFCLeft = ETrue;
+    iFCCalled = ETrue;
+    iFCLeaveErr = aError;
+    if( iFCOwned )
+        {
+        delete iFC;
+        iFC = NULL;
+        }
+
+    return KErrNone;
+    }
+
+
+inline void CDelayedFunctionCall::InvokeL()
+    {
+    iFC->InvokeL();
+    iFCCalled = ETrue;
+    if( iFCOwned )
+        {
+        delete iFC;
+        iFC = NULL;
+        }
+    }
+
+
+
+
+
+
+
+// =============================================================================
+// Generic Function Call classes
+// =============================================================================
+
+
+// CLASS DESCRIPTION
+
+/**
+ * Base class for generic function call objects.
+ * Initializes function call members to zero
+ * during the object construction.
+ */
+class TMemFillBase
+    {
+    protected: //Protected constructor & virtual destructor
+        TMemFillBase( TUint aSize ) { Mem::FillZ( this, aSize); }
+        virtual ~TMemFillBase() {}
+    };
+
+
+
+
+
+// CLASS DESCRIPTION
+
+/**
+ * Generic function call object for function that returns void.
+ *
+ * This function call object doesn't own any of the
+ * call parameters, nor the called object.
+ */
+template< class C,
+          class P1=TInt,
+          class P2=TInt,
+          class P3=TInt,
+          class P4=TInt >
+class TGenericFuncCallVoid : public TMemFillBase, public MFunctionCall
+    {
+    private: //Function type shortcuts
+        typedef void (C::*TFuncTypeVoid)();
+        typedef void (C::*TFuncType1)( P1 aP1 );
+        typedef void (C::*TFuncType2)( P1 aP1, P2 aP2 );
+        typedef void (C::*TFuncType3)( P1 aP1, P2 aP2, P3 aP3 );
+        typedef void (C::*TFuncType4)( P1 aP1, P2 aP2, P3 aP3, P4 aP4 );
+
+
+    public: //Construction / destruction
+        TGenericFuncCallVoid( C& aObj, TFuncTypeVoid aFunc )
+            : TMemFillBase( sizeof( TGenericFuncCallVoid ) ),
+              iObj( aObj ),
+              iFVoid( aFunc )
+            {}
+
+        TGenericFuncCallVoid( C& aObj, TFuncType1 aFunc, P1 aP1 )
+            : TMemFillBase( sizeof( TGenericFuncCallVoid ) ),
+              iObj( aObj ),
+              iF1( aFunc ),
+              iP1( aP1 )
+            {}
+
+        TGenericFuncCallVoid( C& aObj, TFuncType2 aFunc, P1 aP1, P2 aP2  )
+            : TMemFillBase( sizeof( TGenericFuncCallVoid ) ),
+              iObj( aObj ),
+              iF2( aFunc ),
+              iP1( aP1 ), iP2( aP2 )
+            {}
+
+        TGenericFuncCallVoid( C& aObj, TFuncType3 aFunc, P1 aP1 , P2 aP2, P3 aP3  )
+            : TMemFillBase( sizeof( TGenericFuncCallVoid ) ),
+              iObj( aObj ),
+              iF3( aFunc ),
+              iP1( aP1 ), iP2( aP2 ), iP3( aP3 )
+            {}
+
+        TGenericFuncCallVoid( C& aObj, TFuncType4 aFunc, P1 aP1 , P2 aP2, P3 aP3, P4 aP4 )
+            : TMemFillBase( sizeof( TGenericFuncCallVoid ) ),
+              iObj( aObj ),
+              iF4( aFunc ),
+              iP1( aP1 ), iP2( aP2 ), iP3( aP3 ), iP4( aP4 )
+            {}
+
+        ~TGenericFuncCallVoid()
+            {}
+
+    private: //From MFunctionCall
+
+        void InvokeL()
+            {
+            if( iFVoid )
+                {
+                (iObj.*iFVoid)();
+                }
+            else if( iF1 )
+                {
+                (iObj.*iF1)( iP1 );
+                }
+            else if( iF2 )
+                {
+                (iObj.*iF2)( iP1, iP2 );
+                }
+            else if( iF3 )
+                {
+                (iObj.*iF3)( iP1, iP2, iP3 );
+                }
+            else if( iF4 )
+                {
+                (iObj.*iF4)( iP1, iP2, iP3, iP4 );
+                }
+            }
+
+        MFunctionCall* TGenericFuncCallVoid::CloneLC() const
+            {
+			TAny* self = User::AllocL( sizeof( TGenericFuncCallVoid ) );
+            Mem::Copy( self, this, sizeof( TGenericFuncCallVoid ) );
+            TGenericFuncCallVoid* self2 = (TGenericFuncCallVoid*) self;
+            CleanupDeletePushL( self2 );
+            return (MFunctionCall*) self2;
+            }
+
+
+    private: //Call data
+
+        C& iObj;
+        P1 iP1;
+        P2 iP2;
+        P3 iP3;
+        P4 iP4;
+        TFuncTypeVoid iFVoid;
+        TFuncType1 iF1;
+        TFuncType2 iF2;
+        TFuncType3 iF3;
+        TFuncType4 iF4;
+    };
+
+
+
+
+
+// CLASS DESCRIPTION
+
+/**
+ * Generic function call object for function that returns a value
+ * (with by-value convention).
+ *
+ * This function call object doesn't own any of the
+ * call parameters, nor the called object or the result.
+ */
+template< class C,
+          class R,
+          class P1=TInt,
+          class P2=TInt,
+          class P3=TInt,
+          class P4=TInt >
+class TGenericFuncCallRetByValue : public TMemFillBase, public MFunctionCall
+    {
+    private: //Function type shortcuts
+        typedef R (C::*TFuncTypeVoid)();
+        typedef R (C::*TFuncType1)( P1 aP1 );
+        typedef R (C::*TFuncType2)( P1 aP1, P2 aP2 );
+        typedef R (C::*TFuncType3)( P1 aP1, P2 aP2, P3 aP3 );
+        typedef R (C::*TFuncType4)( P1 aP1, P2 aP2, P3 aP3, P4 aP4 );
+
+
+    public: //Construction / destruction
+        TGenericFuncCallRetByValue( C& aObj, TFuncTypeVoid aFunc )
+            : TMemFillBase( sizeof( TGenericFuncCallRetByValue ) ),
+              iObj( aObj ),
+              iFVoid( aFunc )
+            {}
+
+        TGenericFuncCallRetByValue( C& aObj, TFuncType1 aFunc, P1 aP1 )
+            : TMemFillBase( sizeof( TGenericFuncCallRetByValue ) ),
+              iObj( aObj ),
+              iF1( aFunc ),
+              iP1( aP1 )
+            {}
+
+        TGenericFuncCallRetByValue( C& aObj, TFuncType2 aFunc, P1 aP1, P2 aP2  )
+            : TMemFillBase( sizeof( TGenericFuncCallRetByValue ) ),
+              iObj( aObj ),
+              iF2( aFunc ),
+              iP1( aP1 ), iP2( aP2 )
+            {}
+
+        TGenericFuncCallRetByValue( C& aObj, TFuncType3 aFunc, P1 aP1 , P2 aP2, P3 aP3  )
+            : TMemFillBase( sizeof( TGenericFuncCallRetByValue ) ),
+              iObj( aObj ),
+              iF3( aFunc ),
+              iP1( aP1 ), iP2( aP2 ), iP3( aP3 )
+            {}
+
+        TGenericFuncCallRetByValue( C& aObj, TFuncType4 aFunc, P1 aP1 , P2 aP2, P3 aP3, P4 aP4 )
+            : TMemFillBase( sizeof( TGenericFuncCallRetByValue ) ),
+              iObj( aObj ),
+              iF4( aFunc ),
+              iP1( aP1 ), iP2( aP2 ), iP3( aP3 ), iP4( aP4 )
+            {}
+
+        ~TGenericFuncCallRetByValue()
+            {}
+
+    private: //From MFunctionCall
+
+        void InvokeL()
+            {
+            if( iFVoid )
+                {
+                iReturnValue = (iObj.*iFVoid)();
+                }
+            else if( iF1 )
+                {
+                iReturnValue = (iObj.*iF1)( iP1 );
+                }
+            else if( iF2 )
+                {
+                iReturnValue = (iObj.*iF2)( iP1, iP2 );
+                }
+            else if( iF3 )
+                {
+                iReturnValue = (iObj.*iF3)( iP1, iP2, iP3 );
+                }
+            else if( iF4 )
+                {
+                iReturnValue = (iObj.*iF4)( iP1, iP2, iP3, iP4 );
+                }
+            }
+
+        MFunctionCall* TGenericFuncCallRetByValue::CloneLC() const
+            {
+			TAny* self = User::AllocL( sizeof( TGenericFuncCallRetByValue ) );
+            Mem::Copy( self, this, sizeof( TGenericFuncCallRetByValue ) );
+            TGenericFuncCallRetByValue* self2 = (TGenericFuncCallRetByValue*) self;
+            CleanupDeletePushL( self2 );
+            return (MFunctionCall*) self2;
+            }
+
+    private: //Call data
+
+        C& iObj;
+        P1 iP1;
+        P2 iP2;
+        P3 iP3;
+        P4 iP4;
+        TFuncTypeVoid iFVoid;
+        TFuncType1 iF1;
+        TFuncType2 iF2;
+        TFuncType3 iF3;
+        TFuncType4 iF4;
+
+    public: //Return value
+
+        R iReturnValue;
+    };
+
+
+
+
+template< class P1=TInt,
+          class P2=TInt,
+          class P3=TInt,
+          class P4=TInt >
+class TGenericGlobalFuncCallVoid : public TMemFillBase, public MFunctionCall
+    {
+    private: //Function type shortcuts
+        typedef void (*TFuncTypeVoid)();
+        typedef void (*TFuncType1)( P1 aP1 );
+        typedef void (*TFuncType2)( P1 aP1, P2 aP2 );
+        typedef void (*TFuncType3)( P1 aP1, P2 aP2, P3 aP3 );
+        typedef void (*TFuncType4)( P1 aP1, P2 aP2, P3 aP3, P4 aP4 );
+
+
+    public: //Construction / destruction
+        TGenericGlobalFuncCallVoid( TFuncTypeVoid aFunc )
+            : TMemFillBase( sizeof( TGenericGlobalFuncCallVoid ) ),
+              iFVoid( aFunc )
+            {}
+
+        TGenericGlobalFuncCallVoid( TFuncType1 aFunc, P1 aP1 )
+            : TMemFillBase( sizeof( TGenericGlobalFuncCallVoid ) ),
+              iF1( aFunc ),
+              iP1( aP1 )
+            {}
+
+        TGenericGlobalFuncCallVoid( TFuncType2 aFunc, P1 aP1, P2 aP2  )
+            : TMemFillBase( sizeof( TGenericGlobalFuncCallVoid ) ),
+              iF2( aFunc ),
+              iP1( aP1 ), iP2( aP2 )
+            {}
+
+        TGenericGlobalFuncCallVoid( TFuncType3 aFunc, P1 aP1 , P2 aP2, P3 aP3  )
+            : TMemFillBase( sizeof( TGenericGlobalFuncCallVoid ) ),
+              iF3( aFunc ),
+              iP1( aP1 ), iP2( aP2 ), iP3( aP3 )
+            {}
+
+        TGenericGlobalFuncCallVoid( TFuncType4 aFunc, P1 aP1 , P2 aP2, P3 aP3, P4 aP4 )
+            : TMemFillBase( sizeof( TGenericGlobalFuncCallVoid ) ),
+              iF4( aFunc ),
+              iP1( aP1 ), iP2( aP2 ), iP3( aP3 ), iP4( aP4 )
+            {}
+
+        ~TGenericGlobalFuncCallVoid()
+            {}
+
+    private: //From MFunctionCall
+
+        void InvokeL()
+            {
+            if( iFVoid )
+                {
+                (*iFVoid)();
+                }
+            else if( iF1 )
+                {
+                (*iF1)( iP1 );
+                }
+            else if( iF2 )
+                {
+                (*iF2)( iP1, iP2 );
+                }
+            else if( iF3 )
+                {
+                (*iF3)( iP1, iP2, iP3 );
+                }
+            else if( iF4 )
+                {
+                (*iF4)( iP1, iP2, iP3, iP4 );
+                }
+            }
+
+        MFunctionCall* TGenericGlobalFuncCallVoid::CloneLC() const
+            {
+			TAny* self = User::AllocL( sizeof( TGenericGlobalFuncCallVoid ) );
+            Mem::Copy( self, this, sizeof( TGenericGlobalFuncCallVoid ) );
+            TGenericGlobalFuncCallVoid* self2 = (TGenericGlobalFuncCallVoid*) self;
+            CleanupDeletePushL( self2 );
+            return (MFunctionCall*) self2;
+            }
+
+    private: //Call data
+
+        P1 iP1;
+        P2 iP2;
+        P3 iP3;
+        P4 iP4;
+        TFuncTypeVoid iFVoid;
+        TFuncType1 iF1;
+        TFuncType2 iF2;
+        TFuncType3 iF3;
+        TFuncType4 iF4;
+    };
+
+
+
+
+// CLASS DESCRIPTION
+
+
+/**
+ * Generic function call object to delete objects.
+ *
+ * This function call object doesn't own any of the
+ * parameters ==> the objects are deleted only when
+ * the DFC is executed.
+ *
+ * If deleted objects are provided as pointer reference ( Class*& ),
+ * the original pointer to object (e.g. class member)
+ * is set to NULL during the deletion.
+ */
+template< class C1,
+          class C2 = TAny*,
+          class C3 = TAny* >
+class TGenericObjDelete : public TMemFillBase, public MFunctionCall
+    {
+    public: //Construction / destruction
+        explicit TGenericObjDelete( C1 aObj1 )
+            : TMemFillBase( sizeof( TGenericObjDelete ) ),
+              iObj1( aObj1 )
+            {}
+
+        TGenericObjDelete( C1 aObj1, C2 aObj2 )
+            : TMemFillBase( sizeof( TGenericObjDelete ) ),
+              iObj1( aObj1 ),
+              iObj2( aObj2 )
+            {}
+
+        TGenericObjDelete( C1 aObj1, C2 aObj2, C3 aObj3 )
+            : TMemFillBase( sizeof( TGenericObjDelete ) ),
+              iObj1( aObj1 ),
+              iObj2( aObj2 ),
+              iObj3( aObj3 )
+            {}
+
+        ~TGenericObjDelete()
+            {}
+
+    private: //From MFunctionCall
+
+        void InvokeL()
+            {
+            delete iObj1;
+            iObj1 = NULL;
+
+            delete iObj2;
+            iObj2 = NULL;
+
+            delete iObj3;
+            iObj3 = NULL;
+            }
+
+        MFunctionCall* TGenericObjDelete::CloneLC() const
+            {
+			TAny* self = User::AllocL( sizeof( TGenericObjDelete ) );
+            Mem::Copy( self, this, sizeof( TGenericObjDelete ) );
+            TGenericObjDelete* self2 = (TGenericObjDelete*) self;
+            CleanupDeletePushL( self2 );
+            return (MFunctionCall*) self2;
+            }
+
+    private: //Call data
+
+        C1 iObj1;
+        C2 iObj2;
+        C3 iObj3;
+    };
+
+
+#endif // CDELAYEDFUNCTIONCALL_H__
+
+
+// End of File
+
+