Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
FSM.h
00001 /* 00002 * FiniteStateMachine. Table driven Finite State Machine library 00003 * based on theHarel state machine, supporting actions on transitions, state 00004 * entry and state exit. 00005 * 00006 * Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk> 00007 * 00008 * This file is part of FiniteStateMachine. 00009 * 00010 * FiniteStateMachine is free software: you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation, either version 3 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * FiniteStateMachine is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with DebugTrace. If not, see <http://www.gnu.org/licenses/>. 00022 */ 00023 00024 #ifndef SNATCH59_FSM_H 00025 #define SNATCH59_FSM_H 00026 00027 #include <mbed.h> 00028 #include "FSMDefs.h" 00029 00030 STATE_TEMPLATE_ class State; 00031 00032 TRANS_DEF_TEMPLATE_ 00033 struct TransitionDefinition 00034 { 00035 const char* ownerState; 00036 int eventId; 00037 StateBehaviour mode; 00038 ActionPtrType action; 00039 const char* newState; 00040 }; 00041 00042 TRANS_DEF_TEMPLATE_ 00043 class StateDefinition 00044 { 00045 public: 00046 const char* stateName; 00047 ActionPtrType stateEntryAction; 00048 ActionPtrType stateExitAction; 00049 }; 00050 00051 #include "State.h" 00052 00053 FSM_TEMPLATE_ 00054 class FiniteStateMachine 00055 { 00056 public: 00057 FiniteStateMachine(); 00058 ~FiniteStateMachine(); 00059 00060 void initialize(StateObjectType* owner, 00061 const STATE_DEFINITION_* states, const int total_states, 00062 const TRANSITION_DEFINITION_* transitions, const int total_transitions, 00063 const char* this_state); 00064 void traverse(const int new_event); 00065 void forceToState(const char* stat_name); 00066 bool isState(const char* this_state) const; 00067 const char* getCurrentStateName() const; 00068 00069 private: 00070 void addStates(const STATE_DEFINITION_* states, const int total_states, 00071 const TRANSITION_DEFINITION_* &transitions, const int total_transitions); 00072 void executeTraversal(const int event); 00073 00074 // Data Members 00075 STATE_* currentState; 00076 int totalStates; 00077 StateObjectType* itsStateObject; 00078 STATE_* itsStates[maxStates]; 00079 }; 00080 00081 FSM_TEMPLATE_ 00082 inline const char* FINITE_STATE_MACHINE_::getCurrentStateName() const 00083 { 00084 return (currentState->getName()); 00085 } 00086 00087 FSM_TEMPLATE_ 00088 inline bool FINITE_STATE_MACHINE_::isState(const char* this_state) const 00089 { 00090 if (0 == strcmp(currentState->getName(), this_state)) return true; 00091 00092 return false; 00093 } 00094 00095 FSM_TEMPLATE_ 00096 FINITE_STATE_MACHINE_::FiniteStateMachine() : totalStates(0), currentState(NULL) 00097 { 00098 } 00099 00100 FSM_TEMPLATE_ 00101 FINITE_STATE_MACHINE_::~FiniteStateMachine() 00102 { 00103 if (itsStates != NULL) 00104 { 00105 // delete all its States 00106 for (int i = 0; i < totalStates; i++) 00107 { 00108 delete itsStates[i]; 00109 } 00110 } 00111 } 00112 00113 FSM_TEMPLATE_ 00114 void FINITE_STATE_MACHINE_::initialize(StateObjectType* owner, 00115 const STATE_DEFINITION_* states, const int total_states, 00116 const TRANSITION_DEFINITION_* transitions, const int total_transitions, 00117 const char* this_state) 00118 { 00119 itsStateObject = owner; 00120 00121 for (int k = 0; k < total_states; k++) 00122 { 00123 addStates(states, total_states, transitions, total_transitions); 00124 } 00125 00126 forceToState(this_state); 00127 } 00128 00129 FSM_TEMPLATE_ 00130 void FINITE_STATE_MACHINE_::traverse(const int new_event) 00131 { 00132 if (0 == totalStates) 00133 { 00134 return; 00135 } 00136 00137 STATE_TRANSITION_* associated_transition = NULL; 00138 STATE_* new_state = currentState->match(new_event, associated_transition); 00139 00140 if (new_state != NULL && associated_transition != NULL) 00141 { 00142 StateBehaviour behaviour = associated_transition->getStateBehaviour(); 00143 00144 if (actions == behaviour) 00145 { 00146 currentState->doExitAction(itsStateObject); 00147 } 00148 00149 currentState = new_state; 00150 00151 associated_transition->doAction(itsStateObject); 00152 00153 if (actions == behaviour) 00154 { 00155 new_state->doEntryAction(itsStateObject); 00156 } 00157 } 00158 } 00159 00160 FSM_TEMPLATE_ 00161 void FINITE_STATE_MACHINE_::forceToState(const char* state_name) 00162 { 00163 for (int i = 0; i < totalStates; i++) 00164 { 00165 if (0 == strcmp(itsStates[i]->getName(), state_name)) 00166 { 00167 currentState = itsStates[i]; 00168 break; 00169 } 00170 } 00171 } 00172 00173 FSM_TEMPLATE_ 00174 void FINITE_STATE_MACHINE_::addStates(const STATE_DEFINITION_* states, const int total_states, 00175 const TRANSITION_DEFINITION_* &transitions, const int total_transitions) 00176 { 00177 for (int i = 0; i < total_states; i++) 00178 { 00179 00180 itsStates[i] = new STATE_(states[i].stateName, 00181 states[i].stateEntryAction, 00182 states[i].stateExitAction); 00183 } 00184 totalStates = total_states; 00185 00186 for (int i = 0; i < total_states; i++) 00187 { 00188 itsStates[i]->addTransitions(transitions, total_transitions, itsStates, total_states); 00189 } 00190 } 00191 00192 #endif
Generated on Wed Jul 13 2022 21:34:29 by
1.7.2