Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

CC_FSM.cpp

00001 // 00002 // Copyright 2004 P&P Software GmbH - All Rights Reserved 00003 // 00004 // CC_FSM.cpp 00005 // 00006 // Version 1.0 00007 // Date 11.04.03 00008 // Author A. Pasetti (P&P Software) 00009 // 00010 // Change Record: 00011 00012 #include "../GeneralInclude/CompilerSwitches.h" 00013 #include "../GeneralInclude/DebugSupport.h" 00014 #include "../GeneralInclude/BasicTypes.h" 00015 #include "../GeneralInclude/ClassId.h" 00016 #include "../GeneralInclude/Constants.h" 00017 #include "../Base/CC_RootObject.h" 00018 #include "FsmState.h" 00019 #include "CC_FSM.h" 00020 00021 CC_FSM::CC_FSM(void) { 00022 pCurrentState = pNULL; 00023 numberOfStates = 0; 00024 currentState = -1; 00025 requestedTargetState = -1; 00026 setClassId(ID_FSM); 00027 } 00028 00029 void CC_FSM::reset(void) { 00030 assert( numberOfStates > 0 ); 00031 assert( pState[0] != pNULL ); 00032 00033 // Enable all state transitions 00034 for (TD_FsmStateIndex i=0; i<numberOfStates; i++) 00035 transitionEnabled[i] = ENABLED; 00036 00037 allTransitionEnabled = ENABLED; 00038 00039 // Compute the nextState indices 00040 for (TD_FsmStateIndex i=0; i<numberOfStates; i++) 00041 { FsmState* pNS = pState[i]->getNextState(); 00042 if ( pNS != pNULL ) 00043 { for (TD_FsmStateIndex j=0; j<numberOfStates; j++) 00044 if ( pNS == pState[j] ) 00045 pNextState[i] = j; 00046 } 00047 } 00048 00049 if ( currentState >= 0 ) 00050 pCurrentState->doExit(); 00051 00052 pCurrentState = pState[0]; 00053 currentState = 0; 00054 pCurrentState->doInit(); 00055 } 00056 00057 bool CC_FSM::isObjectConfigured(void) { 00058 if (!CC_RootObject::isObjectConfigured() || numberOfStates<=0 || pCurrentState==pNULL) 00059 return NOT_CONFIGURED; 00060 00061 for (TD_FsmStateIndex i=0; i<numberOfStates; i++) { 00062 if (pState[i] == pNULL) 00063 return NOT_CONFIGURED; 00064 } 00065 00066 return CONFIGURED; 00067 } 00068 00069 void CC_FSM::setNumberOfStates(TD_FsmStateIndex n) { 00070 assert( n > 0 ); 00071 assert( numberOfStates == 0 ); // Method should only be called once 00072 00073 numberOfStates = n; 00074 00075 // Create and initialize the array that holds the FSM states and their 00076 // next states 00077 pState = new FsmState*[n]; 00078 for (TD_FsmStateIndex i=0; i<numberOfStates; i++) 00079 pState[i] = pNULL; 00080 00081 pNextState = new TD_FsmStateIndex[n]; 00082 for (TD_FsmStateIndex i=0; i<numberOfStates; i++) 00083 pNextState[i] = -1; 00084 00085 // Create and initialize the array that holds the state transition 00086 // enable status 00087 transitionEnabled = new bool[n]; 00088 for (TD_FsmStateIndex i=0; i<numberOfStates; i++) 00089 transitionEnabled[i] = ENABLED; 00090 } 00091 00092 TD_FsmStateIndex CC_FSM::getNumberOfStates(void) const { 00093 return numberOfStates; 00094 } 00095 00096 void CC_FSM::setState(TD_FsmStateIndex i, FsmState* s) { 00097 assert( numberOfStates > 0 ); 00098 assert( (i < numberOfStates) && (s != pNULL) ); 00099 assert( pState != pNULL ); 00100 00101 if ( (i < numberOfStates) && (i >= 0) ) 00102 pState[i] = s; 00103 else 00104 CC_RootObject::getEventRepository()->create(this,EVT_ILLEGAL_FS); 00105 } 00106 00107 void CC_FSM::setTransitionEnableStatus(TD_FsmStateIndex toState, bool enabled) { 00108 assert( toState < numberOfStates ); 00109 assert( transitionEnabled != pNULL ); 00110 00111 if ( (toState < numberOfStates) && (toState >= 0) ) 00112 transitionEnabled[toState] = enabled; 00113 else 00114 CC_RootObject::getEventRepository()->create(this,EVT_ILLEGAL_FS); 00115 } 00116 00117 void CC_FSM::setTransitionEnableStatus(bool enabled) { 00118 allTransitionEnabled = enabled; 00119 } 00120 00121 void CC_FSM::makeTransitionRequest(TD_FsmStateIndex targetState) { 00122 assert( isObjectConfigured() ); 00123 assert( targetState >= 0 ); 00124 assert( targetState < numberOfStates ); 00125 00126 if ( (targetState < numberOfStates) && (targetState >= 0) ) 00127 requestedTargetState = targetState; 00128 else 00129 CC_RootObject::getEventRepository()->create(this,EVT_ILLEGAL_FS); 00130 } 00131 00132 void CC_FSM::activate(void) { 00133 assert( isObjectConfigured() ); 00134 00135 if ( requestedTargetState >= 0 ) // a state transition request is pending 00136 { tryTransition(requestedTargetState); 00137 requestedTargetState = -1; 00138 pCurrentState->doContinue(); 00139 return; 00140 } 00141 00142 if ( (pCurrentState->isFinished()) && 00143 (pCurrentState->getNextState()!=pNULL) ) 00144 tryTransition( pNextState[currentState] ); 00145 00146 pCurrentState->doContinue(); 00147 00148 return; 00149 } 00150 00151 void CC_FSM::tryTransition(TD_FsmStateIndex targetState) { 00152 assert( isObjectConfigured() ); 00153 assert( targetState >= 0 ); 00154 assert( targetState < numberOfStates ); 00155 00156 if (!isTransitionEnabled()) 00157 { CC_RootObject::getEventRepository()->create(this,EVT_FSM_ALL_TRANSITION_DISABLED); 00158 return; 00159 } 00160 00161 if (!isTransitionEnabled(targetState)) 00162 { CC_RootObject::getEventRepository()->create(this,EVT_FSM_TRANSITION_DISABLED); 00163 return; 00164 } 00165 00166 if (!pCurrentState->canExit()) 00167 { CC_RootObject::getEventRepository()->create(this,EVT_FSM_EXIT_FAILED); 00168 return; 00169 } 00170 00171 FsmState* pTargetState = pState[targetState]; 00172 if ( !pTargetState->canEnter() ) 00173 { CC_RootObject::getEventRepository()->create(this,EVT_FSM_ENTRY_FAILED); 00174 return; 00175 } 00176 00177 pCurrentState->doExit(); 00178 pCurrentState = pTargetState; 00179 currentState = targetState; 00180 pCurrentState->doInit(); 00181 00182 CC_RootObject::getEventRepository()->create(this,EVT_FSM_TRANSITION); 00183 return; 00184 }
Copyright 2003 P&P Software GmbH - All Rights Reserved