Petras Saduikis / Mbed 2 deprecated FiniteStateMachine

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FSM.h Source File

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