This library is designed to create and run state graphs. It supports hierarchical states and parallel states execution.

Committer:
martin13
Date:
Tue Feb 02 20:47:45 2021 +0000
Revision:
4:22b4462fcb26
Parent:
0:f4fdca2c4c67
Added unittests

Who changed what in which revision?

UserRevisionLine numberNew contents of line
martin13 0:f4fdca2c4c67 1 ////////////////////////////////////////////////////////////////////////////////
martin13 0:f4fdca2c4c67 2 // Copyright Rottor SAS 2017
martin13 0:f4fdca2c4c67 3 // All rigths reserved.
martin13 0:f4fdca2c4c67 4 //
martin13 0:f4fdca2c4c67 5 // File Name : StateMachine.h
martin13 0:f4fdca2c4c67 6 // Authors : Martin Matignon
martin13 0:f4fdca2c4c67 7 //
martin13 0:f4fdca2c4c67 8 // If you find any bug or if you have any question please contact
martin13 0:f4fdca2c4c67 9 // Martin Matignon <martin.matignon@rottor.fr>
martin13 0:f4fdca2c4c67 10 // Nicolas Forestier <nicolas.forestier@rottor.fr>
martin13 0:f4fdca2c4c67 11 //
martin13 0:f4fdca2c4c67 12 ////////////////////////////////////////////////////////////////////////////////
martin13 0:f4fdca2c4c67 13
martin13 0:f4fdca2c4c67 14 #ifndef __SM_STATE_MACHINE_H__
martin13 0:f4fdca2c4c67 15 #define __SM_STATE_MACHINE_H__
martin13 0:f4fdca2c4c67 16
martin13 0:f4fdca2c4c67 17 #include <string>
martin13 0:f4fdca2c4c67 18 #include "Transitions.h"
martin13 0:f4fdca2c4c67 19
martin13 0:f4fdca2c4c67 20 // Macro to cast derived State pointer object
martin13 0:f4fdca2c4c67 21 #define STATE(S) ((State*)S)
martin13 0:f4fdca2c4c67 22
martin13 0:f4fdca2c4c67 23 typedef const char* OUTCOME;
martin13 0:f4fdca2c4c67 24
martin13 0:f4fdca2c4c67 25
martin13 0:f4fdca2c4c67 26 /** A class to store and map the states graph and execute
martin13 0:f4fdca2c4c67 27 */
martin13 0:f4fdca2c4c67 28 class StateMachine : public State{
martin13 0:f4fdca2c4c67 29
martin13 0:f4fdca2c4c67 30 public:
martin13 0:f4fdca2c4c67 31
martin13 0:f4fdca2c4c67 32 /** Structure to store list of(state/transitions) :
martin13 0:f4fdca2c4c67 33 * { state : transition{ outcome: target, ...}, ... }
martin13 0:f4fdca2c4c67 34 */
martin13 0:f4fdca2c4c67 35 typedef struct StateItem_t{
martin13 0:f4fdca2c4c67 36
martin13 0:f4fdca2c4c67 37 State *state;
martin13 0:f4fdca2c4c67 38 Transitions *transitions;
martin13 0:f4fdca2c4c67 39 StateItem_t *next;
martin13 0:f4fdca2c4c67 40
martin13 0:f4fdca2c4c67 41 StateItem_t(State* _state);
martin13 0:f4fdca2c4c67 42
martin13 0:f4fdca2c4c67 43 } StateItem_t;
martin13 0:f4fdca2c4c67 44
martin13 0:f4fdca2c4c67 45 /** Create a StateMachine
martin13 0:f4fdca2c4c67 46 *
martin13 0:f4fdca2c4c67 47 * @param const char* The state machine uuid
martin13 0:f4fdca2c4c67 48 * @param UserData* The user data object pointer
martin13 0:f4fdca2c4c67 49 */
martin13 0:f4fdca2c4c67 50 StateMachine(const char* stateMachineUUID, UserData *ud = new UserData());
martin13 0:f4fdca2c4c67 51
martin13 0:f4fdca2c4c67 52 /** Set the initial state to execute
martin13 0:f4fdca2c4c67 53 *
martin13 0:f4fdca2c4c67 54 * @param State* The initial state
martin13 0:f4fdca2c4c67 55 */
martin13 0:f4fdca2c4c67 56 void setInitialState(State* state);
martin13 0:f4fdca2c4c67 57
martin13 0:f4fdca2c4c67 58
martin13 0:f4fdca2c4c67 59 /** Instance state with state machine context
martin13 0:f4fdca2c4c67 60 *
martin13 0:f4fdca2c4c67 61 * @param const char* The state uuid
martin13 0:f4fdca2c4c67 62 */
martin13 0:f4fdca2c4c67 63 template<typename T>
martin13 0:f4fdca2c4c67 64 inline T* Instance(const char* uuid){
martin13 0:f4fdca2c4c67 65
martin13 0:f4fdca2c4c67 66 // State instance with user data context
martin13 0:f4fdca2c4c67 67 T* state = new T(uuid, m_userData);
martin13 0:f4fdca2c4c67 68
martin13 0:f4fdca2c4c67 69 // Registe state into state machine
martin13 0:f4fdca2c4c67 70 this->_addState(STATE(state));
martin13 0:f4fdca2c4c67 71
martin13 0:f4fdca2c4c67 72 // Routing preempt outcome
martin13 0:f4fdca2c4c67 73 this->connect(STATE(state), PREEMPTED, PREEMPTED);
martin13 0:f4fdca2c4c67 74
martin13 0:f4fdca2c4c67 75 return state;
martin13 0:f4fdca2c4c67 76 }
martin13 0:f4fdca2c4c67 77
martin13 0:f4fdca2c4c67 78 /** Method for routing state outcome to other state
martin13 0:f4fdca2c4c67 79 * (Connect state outcome to state target)
martin13 0:f4fdca2c4c67 80 *
martin13 0:f4fdca2c4c67 81 * @param State* The pointer state object
martin13 0:f4fdca2c4c67 82 * @param const char* The state outcome
martin13 0:f4fdca2c4c67 83 * @param State* The pointer target state
martin13 0:f4fdca2c4c67 84 */
martin13 0:f4fdca2c4c67 85 void connect(State* state, const char* outcome, State* target);
martin13 0:f4fdca2c4c67 86
martin13 0:f4fdca2c4c67 87 /** Remap state outcome to other state
martin13 0:f4fdca2c4c67 88 *
martin13 0:f4fdca2c4c67 89 * @param State* The pointer state object
martin13 0:f4fdca2c4c67 90 * @param const char* The state outcome
martin13 0:f4fdca2c4c67 91 * @param State* The pointer target state
martin13 0:f4fdca2c4c67 92 */
martin13 0:f4fdca2c4c67 93 void remap(State* state, const char* outcome, State* target);
martin13 0:f4fdca2c4c67 94
martin13 0:f4fdca2c4c67 95 /** Method for routing state outcome to exit outcome
martin13 0:f4fdca2c4c67 96 *
martin13 0:f4fdca2c4c67 97 * @param State* The pointer state object
martin13 0:f4fdca2c4c67 98 * @param const char* The state outcome
martin13 0:f4fdca2c4c67 99 * @param const char* The exit outcome
martin13 0:f4fdca2c4c67 100 */
martin13 0:f4fdca2c4c67 101 void connect(State* state, const char* outcome, const char* _exit);
martin13 0:f4fdca2c4c67 102
martin13 0:f4fdca2c4c67 103 /** Remap state outcome to exit outcome
martin13 0:f4fdca2c4c67 104 *
martin13 0:f4fdca2c4c67 105 * @param State* The pointer state object
martin13 0:f4fdca2c4c67 106 * @param const char* The state outcome
martin13 0:f4fdca2c4c67 107 * @param const char* The exit outcome
martin13 0:f4fdca2c4c67 108 */
martin13 0:f4fdca2c4c67 109 void remap(State* state, const char* outcome, const char* _exit);
martin13 0:f4fdca2c4c67 110
martin13 0:f4fdca2c4c67 111 /** Before state machine execution (Empty)
martin13 0:f4fdca2c4c67 112 * (You can redefine this method in inherited object)
martin13 0:f4fdca2c4c67 113 */
martin13 0:f4fdca2c4c67 114 virtual void onEntry();
martin13 0:f4fdca2c4c67 115
martin13 0:f4fdca2c4c67 116
martin13 0:f4fdca2c4c67 117 /** State machine execution (Execute graph state)
martin13 0:f4fdca2c4c67 118 *
martin13 0:f4fdca2c4c67 119 * @return const char* The state machine outcome
martin13 0:f4fdca2c4c67 120 */
martin13 0:f4fdca2c4c67 121 virtual const char* onExecute();
martin13 0:f4fdca2c4c67 122
martin13 0:f4fdca2c4c67 123
martin13 0:f4fdca2c4c67 124 /** After state machine execution (Empty)
martin13 0:f4fdca2c4c67 125 * (You can redefine this method in inherited object)
martin13 0:f4fdca2c4c67 126 */
martin13 0:f4fdca2c4c67 127 virtual void onExit();
martin13 0:f4fdca2c4c67 128
martin13 0:f4fdca2c4c67 129 /** The ROOT state machine execution
martin13 0:f4fdca2c4c67 130 *
martin13 0:f4fdca2c4c67 131 * @return const char* The root state machine outcome
martin13 0:f4fdca2c4c67 132 */
martin13 0:f4fdca2c4c67 133 const char* execute();
martin13 0:f4fdca2c4c67 134
martin13 0:f4fdca2c4c67 135 /** Provide the states list registered into state machine
martin13 0:f4fdca2c4c67 136 *
martin13 0:f4fdca2c4c67 137 * @return StateItem_t* The pointer states list
martin13 0:f4fdca2c4c67 138 */
martin13 0:f4fdca2c4c67 139 StateItem_t* getStatesList();
martin13 0:f4fdca2c4c67 140
martin13 0:f4fdca2c4c67 141 /** Provide the number of states registered into state machine
martin13 0:f4fdca2c4c67 142 *
martin13 0:f4fdca2c4c67 143 * @return int The number of state into state machine
martin13 0:f4fdca2c4c67 144 */
martin13 0:f4fdca2c4c67 145 int getNumberStates();
martin13 0:f4fdca2c4c67 146
martin13 0:f4fdca2c4c67 147 /** Provide the user data object
martin13 0:f4fdca2c4c67 148 *
martin13 0:f4fdca2c4c67 149 * @return UserData* The pointer user data object
martin13 0:f4fdca2c4c67 150 */
martin13 0:f4fdca2c4c67 151 UserData* getUserData();
martin13 0:f4fdca2c4c67 152
martin13 0:f4fdca2c4c67 153 /** Print the graph states
martin13 0:f4fdca2c4c67 154 */
martin13 0:f4fdca2c4c67 155 void printGraph(string level="");
martin13 0:f4fdca2c4c67 156
martin13 0:f4fdca2c4c67 157 private:
martin13 0:f4fdca2c4c67 158
martin13 0:f4fdca2c4c67 159 /** Adding a new state
martin13 0:f4fdca2c4c67 160 *
martin13 0:f4fdca2c4c67 161 * @param State* The state object
martin13 0:f4fdca2c4c67 162 */
martin13 0:f4fdca2c4c67 163 void _addState(State *state);
martin13 0:f4fdca2c4c67 164
martin13 0:f4fdca2c4c67 165
martin13 0:f4fdca2c4c67 166 /** Provide the item list by uuid
martin13 0:f4fdca2c4c67 167 *
martin13 0:f4fdca2c4c67 168 * @return StateItem_t* The item structure
martin13 0:f4fdca2c4c67 169 */
martin13 0:f4fdca2c4c67 170 StateItem_t* getItemByUUID(const char* uuid);
martin13 0:f4fdca2c4c67 171
martin13 0:f4fdca2c4c67 172 StateItem_t *m_stateList;
martin13 0:f4fdca2c4c67 173 int m_nbStates;
martin13 0:f4fdca2c4c67 174 StateItem_t *m_currentItem;
martin13 0:f4fdca2c4c67 175 const char *m_initalStateUUID;
martin13 0:f4fdca2c4c67 176 const char *m_targetStateUUID;
martin13 0:f4fdca2c4c67 177 UserData *m_userData;
martin13 0:f4fdca2c4c67 178 };
martin13 0:f4fdca2c4c67 179
martin13 0:f4fdca2c4c67 180 #endif /* #ifndef __SM_STATE_MACHINE_H__*/