Petras Saduikis / Mbed 2 deprecated FiniteStateMachine

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers State.h Source File

State.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_STATE_H
00025 #define SNATCH59_STATE_H
00026 
00027 #include <mbed.h> 
00028 #include "FSMDefs.h"
00029 #include "FSM.h"
00030 
00031 STATE_TEMPLATE_ class StateTransition;
00032 
00033 #include "StateTransition.h"
00034 
00035 STATE_TEMPLATE_
00036 class State
00037 {
00038     
00039 public:
00040     State(const char* state_name, ActionPtrType entry_action_ptr, ActionPtrType exit_action_ptr);
00041     ~State( );
00042     
00043     STATE_*    match(const int event_id, STATE_TRANSITION_* &transition) const;
00044     void addTransitions(const TRANSITION_DEFINITION_* &transitions, const int total_transitions,
00045                         STATE_** states, const int total_states);
00046     void doEntryAction(StateObjectType* &its_state_object);
00047     void doExitAction(StateObjectType* &its_state_object);
00048     const char*    getName( ) const;
00049     
00050 private:
00051     const char*    name;
00052     int totalTransitions;
00053     ActionPtrType entryAction;
00054     ActionPtrType exitAction;
00055     STATE_TRANSITION_**    itsTransitions;
00056 };
00057 
00058 STATE_TEMPLATE_
00059 inline const char* STATE_::getName() const
00060 {
00061     return name;
00062 }
00063 
00064 STATE_TEMPLATE_
00065 STATE_::State(const char* state_name, ActionPtrType entry_action_ptr, ActionPtrType exit_action_ptr) : 
00066     name(state_name), entryAction(entry_action_ptr), 
00067     exitAction(exit_action_ptr), totalTransitions(0)
00068 {
00069 }
00070 
00071 STATE_TEMPLATE_
00072 STATE_::~State( )
00073 {
00074     if (itsTransitions != NULL)
00075     {
00076         for (int i = 0; i < totalTransitions; i++)
00077         {
00078             delete itsTransitions[i];
00079         }
00080     
00081         // dust to dust, ashes to ashes
00082         free(itsTransitions);
00083     }
00084 }
00085 
00086 STATE_TEMPLATE_
00087 void STATE_::addTransitions(const TRANSITION_DEFINITION_* &transitions, const int total_transitions, 
00088                             STATE_** states, const int total_states)
00089 {
00090     int tcount = 0;
00091     for (int i = 0; i < total_transitions; i++)
00092     {
00093         TRANSITION_DEFINITION_ tdef = transitions[i];
00094         if (0 == strcmp(name, tdef.ownerState))
00095         {
00096             tcount++;
00097         }
00098     }
00099 
00100     itsTransitions = (STATE_TRANSITION_**)malloc(sizeof(STATE_TRANSITION_*)*tcount);
00101 
00102     for (int i = 0; i < total_transitions; i++)
00103     {
00104         TRANSITION_DEFINITION_ tdef = transitions[i];
00105         if (0 == strcmp(name, tdef.ownerState))
00106         {
00107             STATE_* new_state_ptr = NULL;
00108             for (int k = 0; k < total_states; k++)
00109             {
00110                 if (0 == strcmp(states[k]->getName(), tdef.newState))
00111                 {
00112                     new_state_ptr = states[k];
00113                     break;
00114                 }
00115             }
00116 
00117             itsTransitions[totalTransitions++] = 
00118                     new STATE_TRANSITION_(tdef.eventId, tdef.action, new_state_ptr, tdef.mode);        
00119         }
00120     }
00121 }
00122 
00123 STATE_TEMPLATE_
00124 STATE_* STATE_::match(const int event_id, STATE_TRANSITION_* &transition) const
00125 {
00126     if (0 == totalTransitions)
00127     {
00128         return NULL;
00129     }
00130 
00131     STATE_* new_state = NULL;
00132     
00133     int i = 0;
00134     do
00135     {
00136         new_state = itsTransitions[i]->match(event_id);
00137         transition = itsTransitions[i++];
00138     }
00139     while (NULL == new_state && i < totalTransitions);
00140     
00141     return new_state;
00142 }
00143 
00144 STATE_TEMPLATE_
00145 void STATE_::doEntryAction(StateObjectType* &its_state_object)
00146 {
00147       if (entryAction != NULL)        
00148       {
00149         (its_state_object->*entryAction)( );
00150     }
00151 }
00152 
00153 STATE_TEMPLATE_
00154 void STATE_::doExitAction(StateObjectType* &its_state_object)
00155 {
00156       if (exitAction != NULL)
00157       {
00158         (its_state_object->*exitAction)( );
00159     }
00160 }
00161 
00162 #endif