diff -r 2c7f27287390 -r 053c6c7c14f3 idlefw/tsrc/devicestatusplugin/mt_devstaplg/DelayedFunctionCall.h --- /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 + + +// 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 + +