00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifdef _MSC_VER
00014 #pragma warning( disable : 4786 ) // 'identifier' : identifier was truncated to 'number' characters in the debug information
00015
00016
00017 #pragma warning( disable : 4251 ) // 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
00018 #endif
00019 #ifdef __INTEL_COMPILER
00020 #pragma warning( disable : 985 ) // == C4786
00021 #endif
00022
00023 #include "FSM.h"
00024 #include "FiniteStateMachine-config.h"
00025 #include "FSMErrorCodes.h"
00026
00027 namespace FSM {
00028
00030
00032
00033 {
00034 }
00035
00036 CFSMState::~CFSMState()
00037 {
00038 for(Transition_List::iterator i = m_Transitions.begin() ; i != m_Transitions.end() ; ++i)
00039 {
00040 (*i)->DeleteThis();
00041 }
00042 for(Action_List::iterator j = m_EnterActions.begin() ; j != m_EnterActions.end() ; ++j)
00043 {
00044 (*j)->DeleteThis();
00045 }
00046 for(Action_List::iterator n = m_LeaveActions.begin() ; n != m_LeaveActions.end() ; ++n)
00047 {
00048 (*n)->DeleteThis();
00049 }
00050 m_Transitions.clear();
00051 m_EnterActions.clear();
00052 m_LeaveActions.clear();
00053 }
00054
00056
00058
00059 {
00060 CFSMTransition *Transition = NULL;
00061
00062 Transition = (CFSMTransition *)GetFSM()->Create(className);
00063 if(Transition==NULL)
00064 {
00065 iRethrow();
00066 return NULL;
00067 }
00068
00069 Transition->SetFromState(GetName());
00070 Transition->SetOnEvent(onEvent);
00071
00072 m_Transitions.push_back(Transition);
00073
00074 return Transition;
00075 }
00076
00077 CFSMTransition* CFSMState::AddSimpleTransition(const char *toStateName, const char* onEvent)
00078 {
00079 CFSMSimpleTransition *Transition = (CFSMSimpleTransition *)GetFSM()->Create("SimpleTransition");
00080
00081 if(Transition==NULL)
00082 {
00083 iRethrow();
00084 return NULL;
00085 }
00086
00087 Transition->SetFromState(GetName());
00088 Transition->SetToState(toStateName);
00089 Transition->SetOnEvent(onEvent);
00090
00091 m_Transitions.push_back(Transition);
00092
00093 return Transition;
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 int CFSMState::GetTransitionNumber() const
00115 {
00116 return m_Transitions.size();
00117 }
00118
00119 CFSMTransition* CFSMState::GetTransition(int index) const
00120 {
00121 CFSMTransition* res = NULL;
00122 Transition_List::const_iterator item = m_Transitions.begin();
00123 int n=0;
00124 for (n=0; n<index; ++n)
00125 {
00126 if(item==m_Transitions.end()) break;
00127 ++item;
00128 }
00129 if (item!=m_Transitions.end())
00130 {
00131 res = (*item);
00132 }
00133 if (!res)
00134 {
00135 iThrow(CRITICAL(FSM_TRANSITION_NOT_FOUND));
00136 }
00137 return res;
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 bool CFSMState::DeleteTransition(CFSMTransition *trans)
00180 {
00181 bool res = false;
00182 Transition_List::iterator i = m_Transitions.begin();
00183 while(!(i==m_Transitions.end()))
00184 {
00185 if ((*i)==trans)
00186 {
00187 (*i)->DeleteThis();
00188 m_Transitions.erase(i);
00189 res = true;
00190 break;
00191 }
00192 ++i;
00193 }
00194 if(!res)
00195 {
00196 iThrow(CRITICAL(FSM_TRANSITION_NOT_FOUND));
00197 }
00198 return res;
00199 }
00200
00201 Transition_List::const_iterator CFSMState::GetTransitionsBegin() const
00202 {
00203 return m_Transitions.begin();
00204 }
00205
00206 Transition_List::const_iterator CFSMState::GetTransitionsEnd() const
00207 {
00208 return m_Transitions.end();
00209 }
00210
00212
00214
00215 {
00216 CFSMAction *action = NULL;
00217
00218 action = (CFSMAction *)GetFSM()->Create(className);
00219 if(action==NULL)
00220 {
00221 iRethrow();
00222 return NULL;
00223 }
00224
00225 m_EnterActions.push_back(action);
00226
00227 return action;
00228 }
00229
00230 CFSMAction* CFSMState::AddLeaveAction(const char *className)
00231 {
00232 CFSMAction *action = NULL;
00233
00234 action = (CFSMAction *)GetFSM()->Create(className);
00235 if(action==NULL)
00236 {
00237 iRethrow();
00238 return NULL;
00239 }
00240
00241 m_LeaveActions.push_back(action);
00242
00243 return action;
00244 }
00245
00246 bool CFSMState::DeleteAction(CFSMAction *action)
00247 {
00248 bool res = false;
00249 Action_List::iterator i = m_EnterActions.begin();
00250 while(!(i==m_EnterActions.end()))
00251 {
00252 if ((*i)==action)
00253 {
00254 (*i)->DeleteThis();
00255 m_EnterActions.erase(i);
00256 res = true;
00257 break;
00258 }
00259 ++i;
00260 }
00261
00262 if(!res)
00263 {
00264 i = m_LeaveActions.begin();
00265 while(!(i==m_LeaveActions.end()))
00266 {
00267 if ((*i)==action)
00268 {
00269 (*i)->DeleteThis();
00270 m_LeaveActions.erase(i);
00271 res = true;
00272 break;
00273 }
00274 ++i;
00275 }
00276 }
00277
00278 if(!res)
00279 {
00280 iThrow(CRITICAL(FSM_ACTION_NOT_FOUND));
00281 }
00282 return res;
00283 }
00284
00285 CFSMAction* CFSMState::GetEnterAction(int index) const
00286 {
00287 CFSMAction* res = NULL;
00288 Action_List::const_iterator item = m_EnterActions.begin();
00289 int n=0;
00290 for (n=0; n<index; ++n)
00291 {
00292 if(item==m_EnterActions.end()) break;
00293 ++item;
00294 }
00295 if (item!=m_EnterActions.end())
00296 {
00297 res = (*item);
00298 }
00299 if (!res)
00300 {
00301 iThrow(CRITICAL(FSM_ACTION_NOT_FOUND));
00302 }
00303 return res;
00304 }
00305
00306 CFSMAction* CFSMState::GetLeaveAction(int index) const
00307 {
00308 CFSMAction* res = NULL;
00309 Action_List::const_iterator item = m_LeaveActions.begin();
00310 int n=0;
00311 for (n=0; n<index; ++n)
00312 {
00313 if(item==m_LeaveActions.end()) break;
00314 ++item;
00315 }
00316 if (item!=m_LeaveActions.end())
00317 {
00318 res = (*item);
00319 }
00320 if (!res)
00321 {
00322 iThrow(CRITICAL(FSM_ACTION_NOT_FOUND));
00323 }
00324 return res;
00325 }
00326
00327 Action_List::const_iterator CFSMState::GetEnterActionsBegin() const
00328 {
00329 return m_EnterActions.begin();
00330 }
00331
00332 Action_List::const_iterator CFSMState::GetEnterActionsEnd() const
00333 {
00334 return m_EnterActions.end();
00335 }
00336
00337 Action_List::const_iterator CFSMState::GetLeaveActionsBegin() const
00338 {
00339 return m_LeaveActions.begin();
00340 }
00341
00342 Action_List::const_iterator CFSMState::GetLeaveActionsEnd() const
00343 {
00344 return m_LeaveActions.end();
00345 }
00346
00348
00350
00351 {
00352 return m_Name.c_str();
00353 }
00354
00355 void CFSMState::SetName(const char* name)
00356 {
00357 m_Name = name;
00358 }
00359
00361
00363
00364 {
00365 bool res = true;
00366 bool transit = false;
00367 *trans = NULL;
00368 Transition_List::const_iterator i = m_Transitions.begin();
00369 while( !(i==m_Transitions.end()) )
00370 {
00371 res = (*i)->Check(transit, Event, a, b);
00372 if (!res)
00373 {
00374 iRethrow();
00375 break;;
00376 }
00377 if (transit)
00378 {
00379 *trans=(*i);
00380 break;
00381 }
00382 ++i;
00383 }
00384 return res;
00385 }
00386
00387 bool CFSMState::Activate()
00388 {
00389 bool res = true;
00390 Action_List::const_iterator j = m_EnterActions.begin();
00391 while(!(j==m_EnterActions.end()))
00392 {
00393 res = (*j)->Execute("ACTIVATE", (void*)GetName(), (void*)GetNameOfClass());
00394 if (!res)
00395 {
00396 iRethrow();
00397 break;
00398 }
00399 ++j;
00400 }
00401
00402 if (res)
00403 {
00404 Transition_List::const_iterator i = m_Transitions.begin();
00405 while(!(i==m_Transitions.end()))
00406 {
00407 res = (*i)->Activate();
00408 if (!res)
00409 {
00410 iRethrow();
00411 break;
00412 }
00413 ++i;
00414 }
00415 }
00416
00417 return res;
00418 }
00419
00420 bool CFSMState::Deactivate()
00421 {
00422 bool res = true;
00423
00424 Transition_List::const_iterator i = m_Transitions.begin();
00425 while(!(i==m_Transitions.end()))
00426 {
00427 res = (*i)->Deactivate();
00428 if (!res)
00429 {
00430 iRethrow();
00431 break;
00432 }
00433 ++i;
00434 }
00435
00436 if (res)
00437 {
00438 Action_List::const_iterator j = m_LeaveActions.begin();
00439 while(!(j==m_LeaveActions.end()))
00440 {
00441 res = (*j)->Execute("DEACTIVATE", (void*)GetName(), (void*)GetNameOfClass());
00442 if (!res)
00443 {
00444 iRethrow();
00445 break;
00446 }
00447 ++j;
00448 }
00449 }
00450
00451 return res;
00452 }
00453
00455
00457
00458 {
00459 return new CFSMState;
00460 }
00461
00462 void CFSMState::DeleteThis()
00463 {
00464 delete this;
00465 }
00466
00468 };
00469