commsfwsupport/commselements/StateMachine/include/sm_stateTriple.h
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Structures to create a const static (build time) map of states
       
    15 // THIS API IS INTERNAL TO NETWORKING AND IS SUBJECT TO CHANGE AND NOT FOR EXTERNAL USE
       
    16 // 
       
    17 //
       
    18 
       
    19 /**
       
    20  @file 
       
    21  @internalTechnology
       
    22 */
       
    23 
       
    24 #include <e32base.h>
       
    25 
       
    26 // Enable logging for debug builds or builds with the comms flogger enabled - must be defined before including e32utrace.h
       
    27 #if (defined(_DEBUG) || defined(__FLOG_ACTIVE)) && !defined(SYMBIAN_TRACE_ENABLE)
       
    28 #define SYMBIAN_TRACE_ENABLE
       
    29 #endif
       
    30 
       
    31 
       
    32 #ifndef _SM_StateTriple_H_
       
    33 #define _SM_StateTriple_H_
       
    34 
       
    35 #define DEFINE_TRIPLES_TABLE( name ) \
       
    36 	const NetStateMachine::TStateTriple name[] = { \
       
    37 		{ \
       
    38 		(NetStateMachine::TStateTransitionCtor)NULL, \
       
    39 		(NetStateMachine::TStateCtor)NULL, \
       
    40 		(NetStateMachine::TStateForkCtor)NULL, \
       
    41 		NetStateMachine::KTableBoundaryTag_Internal, \
       
    42 		NULL \
       
    43 		},
       
    44 
       
    45 #define TRIPLES_TABLE_END() \
       
    46 		{ \
       
    47 		(NetStateMachine::TStateTransitionCtor)NULL, \
       
    48 		(NetStateMachine::TStateCtor)NULL, \
       
    49 		(NetStateMachine::TStateForkCtor)NULL, \
       
    50 		NetStateMachine::KTableBoundaryTag_Internal, \
       
    51 		NULL \
       
    52 		} \
       
    53 	};
       
    54 
       
    55 #ifdef SYMBIAN_TRACE_ENABLE
       
    56 
       
    57 #define FIRST_TRIPLE( firstState, firstStateFork ) \
       
    58 		{ \
       
    59 		(NetStateMachine::TStateTransitionCtor)NULL, \
       
    60 		NetStateMachine::TStateSizeChecker<firstState>::GetVTablePtr, \
       
    61 		NetStateMachine::TStateForkSizeChecker<firstStateFork>::GetVTablePtr, \
       
    62 		NetStateMachine::KFirstTripleTag_Internal, \
       
    63 		_S8("NULL->"#firstState) \
       
    64 		}
       
    65 
       
    66 //STATE_TRIPLE can also be used instead of FIRST_TRIPLE to specify a "starting" transition.
       
    67 //Starting transition is a transition that is executed in case the statemachine is already running
       
    68 //and an event that would normally cause the statemachine to start occurs.
       
    69 #define STATE_TRIPLE( transitionTag, stateTransition, state, stateFork ) \
       
    70 		{ \
       
    71 		NetStateMachine::TStateTransitionSizeChecker<stateTransition>::GetVTablePtr, \
       
    72 		NetStateMachine::TStateSizeChecker<state>::GetVTablePtr, \
       
    73 		NetStateMachine::TStateForkSizeChecker<stateFork>::GetVTablePtr, \
       
    74 		transitionTag, \
       
    75 		_S8(#stateTransition "->" #state) \
       
    76 		}
       
    77 
       
    78 #define THROUGH_TRIPLE( transitionTag, stateTransition, stateFork ) \
       
    79 		{ \
       
    80 		NetStateMachine::TStateTransitionSizeChecker<stateTransition>::GetVTablePtr, \
       
    81 		(NetStateMachine::TStateCtor)NULL, \
       
    82 		NetStateMachine::TStateForkSizeChecker<stateFork>::GetVTablePtr, \
       
    83 		transitionTag, \
       
    84 		_S8(#stateTransition "->" #stateFork) \
       
    85 		}
       
    86 
       
    87 #define LAST_TRIPLE( transitionTag, lastTransition ) \
       
    88 		{ \
       
    89 		NetStateMachine::TStateTransitionSizeChecker<lastTransition>::GetVTablePtr, \
       
    90 		(NetStateMachine::TStateCtor)NULL, \
       
    91 		(NetStateMachine::TStateForkCtor)NULL, \
       
    92 		transitionTag, \
       
    93 		_S8(#lastTransition "->NULL") \
       
    94 		}
       
    95 #else
       
    96 
       
    97 #define FIRST_TRIPLE( firstState, firstStateFork ) \
       
    98 		{ \
       
    99 		(NetStateMachine::TStateTransitionCtor)NULL, \
       
   100 		NetStateMachine::TStateSizeChecker<firstState>::GetVTablePtr, \
       
   101 		NetStateMachine::TStateForkSizeChecker<firstStateFork>::GetVTablePtr, \
       
   102 		NetStateMachine::KFirstTripleTag_Internal, \
       
   103 		NULL \
       
   104 		}
       
   105 
       
   106 //STATE_TRIPLE can also be used instead of FIRST_TRIPLE to specify a "starting" transition.
       
   107 //Starting transition is a transition that is executed in case the statemachine is already running
       
   108 //and an event that would normally cause the statemachine to start occurs.
       
   109 #define STATE_TRIPLE( transitionTag, stateTransition, state, stateFork ) \
       
   110 		{ \
       
   111 		NetStateMachine::TStateTransitionSizeChecker<stateTransition>::GetVTablePtr, \
       
   112 		NetStateMachine::TStateSizeChecker<state>::GetVTablePtr, \
       
   113 		NetStateMachine::TStateForkSizeChecker<stateFork>::GetVTablePtr, \
       
   114 		transitionTag, \
       
   115 		NULL \
       
   116 		}
       
   117 
       
   118 #define THROUGH_TRIPLE( transitionTag, stateTransition, stateFork ) \
       
   119 		{ \
       
   120 		NetStateMachine::TStateTransitionSizeChecker<stateTransition>::GetVTablePtr, \
       
   121 		(NetStateMachine::TStateCtor)NULL, \
       
   122 		NetStateMachine::TStateForkSizeChecker<stateFork>::GetVTablePtr, \
       
   123 		transitionTag, \
       
   124 		NULL \
       
   125 		}
       
   126 
       
   127 #define LAST_TRIPLE( transitionTag, lastTransition ) \
       
   128 		{ \
       
   129 		NetStateMachine::TStateTransitionSizeChecker<lastTransition>::GetVTablePtr, \
       
   130 		(NetStateMachine::TStateCtor)NULL, \
       
   131 		(NetStateMachine::TStateForkCtor)NULL, \
       
   132 		transitionTag, \
       
   133 		NULL \
       
   134 		}
       
   135 
       
   136 #endif
       
   137 
       
   138 #define FIRST_TRIPLE_ENTRY( firstState, firstStateFork ) \
       
   139 	FIRST_TRIPLE( firstState, firstStateFork ),
       
   140 
       
   141 #define STATE_TRIPLE_ENTRY( transitionTag, stateTransition, state, stateFork ) \
       
   142 	STATE_TRIPLE( transitionTag, stateTransition, state, stateFork ),
       
   143 
       
   144 #define THROUGH_TRIPLE_ENTRY( transitionTag, stateTransition, stateFork ) \
       
   145 	THROUGH_TRIPLE( transitionTag, stateTransition, stateFork ),
       
   146 
       
   147 #define LAST_TRIPLE_ENTRY( transitionTag, lastTransition ) \
       
   148 	LAST_TRIPLE( transitionTag, lastTransition ),
       
   149 
       
   150 namespace NetStateMachine
       
   151 {
       
   152 
       
   153 const TInt KExecuteAlways               = 0x0FFFFFFF;
       
   154 const TInt KTableBoundaryTag_Internal   = KExecuteAlways - 1; //Should never be used except for the MM itself
       
   155 const TInt KFirstTripleTag_Internal     = KExecuteAlways - 2; //Should never be used except for the MM itself
       
   156 
       
   157 //Used as a flag to determine which direction to move 
       
   158 //in the array of triples for the next transition => the actual transition tag
       
   159 //is only 31bits
       
   160 enum KDirection
       
   161 	{
       
   162 	EIgnore   = 0x40000000, //do nothing, go nowhere, return (bin 0100...)
       
   163 	EForward  = 0x00000000,
       
   164 	EBackward = 0x80000000  //(bin 1000...)
       
   165 	};
       
   166 
       
   167 const TInt KMaxStateClassByteSize = 16;
       
   168 
       
   169 //!!Memory given to MState/MStateTransition derived classes is stack allocated.
       
   170 //The memory therefore is valid only between the constructor and one and 
       
   171 //only one subsequent call. No class variables can therefore preserve
       
   172 //the object state for possible cancel or error call. All such variables
       
   173 //are to be accessed via the given aContext pointer
       
   174 //The destructor of the state must not cancel the operation
       
   175 //There is no guarantie that the destructor of state or transition will be
       
   176 //called at all
       
   177 class MStateTransition
       
   178 	{
       
   179 	friend class ACore;
       
   180 
       
   181 protected:
       
   182 	explicit MStateTransition() 
       
   183 		{
       
   184 		};
       
   185 	virtual ~MStateTransition()
       
   186 		{
       
   187 		};
       
   188 
       
   189 protected:
       
   190 	virtual void DoL() = 0;
       
   191 	virtual void Error( TInt aError ) = 0;
       
   192 	};
       
   193 
       
   194 class MState
       
   195 	{
       
   196 	friend class ACore;
       
   197 
       
   198 protected:
       
   199 	explicit MState() 
       
   200 		{
       
   201 		};
       
   202 	virtual ~MState()
       
   203 		{
       
   204 		};
       
   205 
       
   206 protected:
       
   207 	virtual TBool Accept() = 0;
       
   208 	virtual void Cancel() = 0;
       
   209 	};
       
   210 
       
   211 class MStateFork
       
   212 	{
       
   213 	friend class ACore;
       
   214 
       
   215 protected:
       
   216 	explicit MStateFork() 
       
   217 		{
       
   218 		};
       
   219 	virtual ~MStateFork()
       
   220 		{
       
   221 		};
       
   222 
       
   223 protected:
       
   224 	virtual TInt TransitionTag() = 0; //returns a transition tag + direction see KDirection enum
       
   225 	};
       
   226 
       
   227 
       
   228 typedef MStateTransition* (*TStateTransitionCtor)(TDesC8& aMem, TAny* aContext);
       
   229 typedef MState* (*TStateCtor)(TDesC8& aMem, TAny* aContext);
       
   230 typedef MStateFork* (*TStateForkCtor)(TDesC8& aMem, TAny* aContext);
       
   231 
       
   232 struct TStateTriple
       
   233 	{
       
   234 	TStateTransitionCtor iTCtor;
       
   235 	TStateCtor iSCtor;
       
   236 	TStateForkCtor iFCtor;
       
   237 	TInt iTransitionTag : 30;
       
   238 	const TText8* iName; //For logging purposes only but present in all configurations to preserve BC. Static const (ROM), 4B.
       
   239 	};
       
   240 
       
   241 template <class TSTATETRANSITION>
       
   242 struct TStateTransitionSizeChecker
       
   243     {
       
   244     inline static MStateTransition* GetVTablePtr(TDesC8& aMem, TAny* aContext)
       
   245     	{
       
   246     	__ASSERT_COMPILE(sizeof(TSTATETRANSITION) < KMaxStateClassByteSize); //size of the class is greater than KMaxStateClassByteSize
       
   247     	return TSTATETRANSITION::GetVTablePtr(aMem,aContext);
       
   248     	}
       
   249     };
       
   250 
       
   251 template <class TSTATE>
       
   252 struct TStateSizeChecker
       
   253     {
       
   254     inline static MState* GetVTablePtr(TDesC8& aMem, TAny* aContext)
       
   255     	{
       
   256     	__ASSERT_COMPILE(sizeof(TSTATE) < KMaxStateClassByteSize); //size of the class is greater than KMaxStateClassByteSize
       
   257     	return TSTATE::GetVTablePtr(aMem,aContext);
       
   258     	}
       
   259     };
       
   260 
       
   261 template <class TSTATEFORK>
       
   262 struct TStateForkSizeChecker
       
   263     {
       
   264     inline static MStateFork* GetVTablePtr(TDesC8& aMem, TAny* aContext)
       
   265     	{
       
   266     	__ASSERT_COMPILE(sizeof(TSTATEFORK) < KMaxStateClassByteSize); //size of the class is greater than KMaxStateClassByteSize
       
   267     	return TSTATEFORK::GetVTablePtr(aMem,aContext);
       
   268     	}
       
   269     };
       
   270 
       
   271 } //namespace NetStateMachine
       
   272 
       
   273 #endif //_SM_StateTriple_H_
       
   274 
       
   275