--- /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
+
+