Table driven Finite State Machine library based on the Harel state machine, supporting actions on transitions, state entry and state exit. Comes with example illustrating use with interrupts and timers. 03/01/2010 - fixed potential memory leak in DebugTrace.

Dependencies:   mbed

Committer:
snatch59
Date:
Sun Jan 03 11:56:03 2010 +0000
Revision:
0:918566a376fb

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
snatch59 0:918566a376fb 1 /*
snatch59 0:918566a376fb 2 * FiniteStateMachine. Table driven Finite State Machine library
snatch59 0:918566a376fb 3 * based on theHarel state machine, supporting actions on transitions, state
snatch59 0:918566a376fb 4 * entry and state exit.
snatch59 0:918566a376fb 5 *
snatch59 0:918566a376fb 6 * Copyright (C) <2009> Petras Saduikis <petras@petras.co.uk>
snatch59 0:918566a376fb 7 *
snatch59 0:918566a376fb 8 * This file is part of FiniteStateMachine.
snatch59 0:918566a376fb 9 *
snatch59 0:918566a376fb 10 * FiniteStateMachine is free software: you can redistribute it and/or modify
snatch59 0:918566a376fb 11 * it under the terms of the GNU General Public License as published by
snatch59 0:918566a376fb 12 * the Free Software Foundation, either version 3 of the License, or
snatch59 0:918566a376fb 13 * (at your option) any later version.
snatch59 0:918566a376fb 14 *
snatch59 0:918566a376fb 15 * FiniteStateMachine is distributed in the hope that it will be useful,
snatch59 0:918566a376fb 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
snatch59 0:918566a376fb 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
snatch59 0:918566a376fb 18 * GNU General Public License for more details.
snatch59 0:918566a376fb 19 *
snatch59 0:918566a376fb 20 * You should have received a copy of the GNU General Public License
snatch59 0:918566a376fb 21 * along with DebugTrace. If not, see <http://www.gnu.org/licenses/>.
snatch59 0:918566a376fb 22 */
snatch59 0:918566a376fb 23
snatch59 0:918566a376fb 24 #ifndef SNATCH59_STATE_H
snatch59 0:918566a376fb 25 #define SNATCH59_STATE_H
snatch59 0:918566a376fb 26
snatch59 0:918566a376fb 27 #include <mbed.h>
snatch59 0:918566a376fb 28 #include "FSMDefs.h"
snatch59 0:918566a376fb 29 #include "FSM.h"
snatch59 0:918566a376fb 30
snatch59 0:918566a376fb 31 STATE_TEMPLATE_ class StateTransition;
snatch59 0:918566a376fb 32
snatch59 0:918566a376fb 33 #include "StateTransition.h"
snatch59 0:918566a376fb 34
snatch59 0:918566a376fb 35 STATE_TEMPLATE_
snatch59 0:918566a376fb 36 class State
snatch59 0:918566a376fb 37 {
snatch59 0:918566a376fb 38
snatch59 0:918566a376fb 39 public:
snatch59 0:918566a376fb 40 State(const char* state_name, ActionPtrType entry_action_ptr, ActionPtrType exit_action_ptr);
snatch59 0:918566a376fb 41 ~State( );
snatch59 0:918566a376fb 42
snatch59 0:918566a376fb 43 STATE_* match(const int event_id, STATE_TRANSITION_* &transition) const;
snatch59 0:918566a376fb 44 void addTransitions(const TRANSITION_DEFINITION_* &transitions, const int total_transitions,
snatch59 0:918566a376fb 45 STATE_** states, const int total_states);
snatch59 0:918566a376fb 46 void doEntryAction(StateObjectType* &its_state_object);
snatch59 0:918566a376fb 47 void doExitAction(StateObjectType* &its_state_object);
snatch59 0:918566a376fb 48 const char* getName( ) const;
snatch59 0:918566a376fb 49
snatch59 0:918566a376fb 50 private:
snatch59 0:918566a376fb 51 const char* name;
snatch59 0:918566a376fb 52 int totalTransitions;
snatch59 0:918566a376fb 53 ActionPtrType entryAction;
snatch59 0:918566a376fb 54 ActionPtrType exitAction;
snatch59 0:918566a376fb 55 STATE_TRANSITION_** itsTransitions;
snatch59 0:918566a376fb 56 };
snatch59 0:918566a376fb 57
snatch59 0:918566a376fb 58 STATE_TEMPLATE_
snatch59 0:918566a376fb 59 inline const char* STATE_::getName() const
snatch59 0:918566a376fb 60 {
snatch59 0:918566a376fb 61 return name;
snatch59 0:918566a376fb 62 }
snatch59 0:918566a376fb 63
snatch59 0:918566a376fb 64 STATE_TEMPLATE_
snatch59 0:918566a376fb 65 STATE_::State(const char* state_name, ActionPtrType entry_action_ptr, ActionPtrType exit_action_ptr) :
snatch59 0:918566a376fb 66 name(state_name), entryAction(entry_action_ptr),
snatch59 0:918566a376fb 67 exitAction(exit_action_ptr), totalTransitions(0)
snatch59 0:918566a376fb 68 {
snatch59 0:918566a376fb 69 }
snatch59 0:918566a376fb 70
snatch59 0:918566a376fb 71 STATE_TEMPLATE_
snatch59 0:918566a376fb 72 STATE_::~State( )
snatch59 0:918566a376fb 73 {
snatch59 0:918566a376fb 74 if (itsTransitions != NULL)
snatch59 0:918566a376fb 75 {
snatch59 0:918566a376fb 76 for (int i = 0; i < totalTransitions; i++)
snatch59 0:918566a376fb 77 {
snatch59 0:918566a376fb 78 delete itsTransitions[i];
snatch59 0:918566a376fb 79 }
snatch59 0:918566a376fb 80
snatch59 0:918566a376fb 81 // dust to dust, ashes to ashes
snatch59 0:918566a376fb 82 free(itsTransitions);
snatch59 0:918566a376fb 83 }
snatch59 0:918566a376fb 84 }
snatch59 0:918566a376fb 85
snatch59 0:918566a376fb 86 STATE_TEMPLATE_
snatch59 0:918566a376fb 87 void STATE_::addTransitions(const TRANSITION_DEFINITION_* &transitions, const int total_transitions,
snatch59 0:918566a376fb 88 STATE_** states, const int total_states)
snatch59 0:918566a376fb 89 {
snatch59 0:918566a376fb 90 int tcount = 0;
snatch59 0:918566a376fb 91 for (int i = 0; i < total_transitions; i++)
snatch59 0:918566a376fb 92 {
snatch59 0:918566a376fb 93 TRANSITION_DEFINITION_ tdef = transitions[i];
snatch59 0:918566a376fb 94 if (0 == strcmp(name, tdef.ownerState))
snatch59 0:918566a376fb 95 {
snatch59 0:918566a376fb 96 tcount++;
snatch59 0:918566a376fb 97 }
snatch59 0:918566a376fb 98 }
snatch59 0:918566a376fb 99
snatch59 0:918566a376fb 100 itsTransitions = (STATE_TRANSITION_**)malloc(sizeof(STATE_TRANSITION_*)*tcount);
snatch59 0:918566a376fb 101
snatch59 0:918566a376fb 102 for (int i = 0; i < total_transitions; i++)
snatch59 0:918566a376fb 103 {
snatch59 0:918566a376fb 104 TRANSITION_DEFINITION_ tdef = transitions[i];
snatch59 0:918566a376fb 105 if (0 == strcmp(name, tdef.ownerState))
snatch59 0:918566a376fb 106 {
snatch59 0:918566a376fb 107 STATE_* new_state_ptr = NULL;
snatch59 0:918566a376fb 108 for (int k = 0; k < total_states; k++)
snatch59 0:918566a376fb 109 {
snatch59 0:918566a376fb 110 if (0 == strcmp(states[k]->getName(), tdef.newState))
snatch59 0:918566a376fb 111 {
snatch59 0:918566a376fb 112 new_state_ptr = states[k];
snatch59 0:918566a376fb 113 break;
snatch59 0:918566a376fb 114 }
snatch59 0:918566a376fb 115 }
snatch59 0:918566a376fb 116
snatch59 0:918566a376fb 117 itsTransitions[totalTransitions++] =
snatch59 0:918566a376fb 118 new STATE_TRANSITION_(tdef.eventId, tdef.action, new_state_ptr, tdef.mode);
snatch59 0:918566a376fb 119 }
snatch59 0:918566a376fb 120 }
snatch59 0:918566a376fb 121 }
snatch59 0:918566a376fb 122
snatch59 0:918566a376fb 123 STATE_TEMPLATE_
snatch59 0:918566a376fb 124 STATE_* STATE_::match(const int event_id, STATE_TRANSITION_* &transition) const
snatch59 0:918566a376fb 125 {
snatch59 0:918566a376fb 126 if (0 == totalTransitions)
snatch59 0:918566a376fb 127 {
snatch59 0:918566a376fb 128 return NULL;
snatch59 0:918566a376fb 129 }
snatch59 0:918566a376fb 130
snatch59 0:918566a376fb 131 STATE_* new_state = NULL;
snatch59 0:918566a376fb 132
snatch59 0:918566a376fb 133 int i = 0;
snatch59 0:918566a376fb 134 do
snatch59 0:918566a376fb 135 {
snatch59 0:918566a376fb 136 new_state = itsTransitions[i]->match(event_id);
snatch59 0:918566a376fb 137 transition = itsTransitions[i++];
snatch59 0:918566a376fb 138 }
snatch59 0:918566a376fb 139 while (NULL == new_state && i < totalTransitions);
snatch59 0:918566a376fb 140
snatch59 0:918566a376fb 141 return new_state;
snatch59 0:918566a376fb 142 }
snatch59 0:918566a376fb 143
snatch59 0:918566a376fb 144 STATE_TEMPLATE_
snatch59 0:918566a376fb 145 void STATE_::doEntryAction(StateObjectType* &its_state_object)
snatch59 0:918566a376fb 146 {
snatch59 0:918566a376fb 147 if (entryAction != NULL)
snatch59 0:918566a376fb 148 {
snatch59 0:918566a376fb 149 (its_state_object->*entryAction)( );
snatch59 0:918566a376fb 150 }
snatch59 0:918566a376fb 151 }
snatch59 0:918566a376fb 152
snatch59 0:918566a376fb 153 STATE_TEMPLATE_
snatch59 0:918566a376fb 154 void STATE_::doExitAction(StateObjectType* &its_state_object)
snatch59 0:918566a376fb 155 {
snatch59 0:918566a376fb 156 if (exitAction != NULL)
snatch59 0:918566a376fb 157 {
snatch59 0:918566a376fb 158 (its_state_object->*exitAction)( );
snatch59 0:918566a376fb 159 }
snatch59 0:918566a376fb 160 }
snatch59 0:918566a376fb 161
snatch59 0:918566a376fb 162 #endif