state_machine.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. /*
  2. * Copyright (c) 2013 Andreas Misje
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. /**
  23. * \mainpage %state_machine
  24. *
  25. * %state_machine is a feature-rich, yet simple finite state machine
  26. * implementation. It supports grouped states, guarded transitions, events
  27. * with payload, entry and exit actions, transition actions and access to
  28. * user-defined state data from all actions.
  29. *
  30. * The user must build the state machine by linking together states and
  31. * transitions arrays with pointers. A pointer to an initial state and an
  32. * error state is given to statem_init() to initialise a state machine object.
  33. * The state machine is run by passing events to it with the function
  34. * statem_handle_event(). The return value of statem_handle_event() will
  35. * give an indication to what has happened.
  36. *
  37. * \image html state_machine.svg "Illustrating a state_machine"
  38. */
  39. /**
  40. * \defgroup state_machine State machine
  41. *
  42. * \author Andreas Misje
  43. * \date 27.03.13
  44. *
  45. * \brief Finite state machine
  46. *
  47. * A finite state machine implementation that supports nested states, guards
  48. * and entry/exit routines. All state machine data is stored in separate
  49. * objects, and the state machine must be built by the user. States are
  50. * connected using pointers, and all data can be stored on either the stack,
  51. * heap or both.
  52. */
  53. /**
  54. * \addtogroup state_machine
  55. * @{
  56. *
  57. * \file
  58. * \example state_machineExample.c Simple example of how to create a state
  59. * machine
  60. * \example nestedTest.c Simple example testing the behaviour of nested
  61. * parent states
  62. */
  63. #ifndef __STATE_MACHINE_H
  64. #define __STATE_MACHINE_H
  65. #include <stddef.h>
  66. #include <stdbool.h>
  67. /**
  68. * \brief Event
  69. *
  70. * Events trigger transitions from a state to another. Event types are defined
  71. * by the user. Any event may optionally contain a \ref #event::data
  72. * "payload".
  73. *
  74. * \sa state
  75. * \sa transition
  76. */
  77. struct event
  78. {
  79. /** \brief Type of event. Defined by user. */
  80. int type;
  81. /**
  82. * \brief Event payload.
  83. *
  84. * How this is used is entirely up to the user. This data
  85. * is always passed together with #type in order to make it possible to
  86. * always cast the data correctly.
  87. */
  88. void *data;
  89. };
  90. struct state;
  91. /**
  92. * \brief Transition between a state and another state
  93. *
  94. * All states that are not final must have at least one transition. The
  95. * transition may be guarded or not. Transitions are triggered by events. If
  96. * a state has more than one transition with the same type of event (and the
  97. * same condition), the first transition in the array will be run. An
  98. * unconditional transition placed last in the transition array of a state can
  99. * act as a "catch-all". A transition may optionally run an #action, which
  100. * will have the triggering event passed to it as an argument, along with the
  101. * current and new states' \ref state::data "data".
  102. *
  103. * It is perfectly valid for a transition to return to the state it belongs
  104. * to. Such a transition will not call the state's \ref state::action_entry
  105. * "entry action" or \ref state::action_exti "exit action". If there are no
  106. * transitions for the current event, the state's parent will be handed the
  107. * event.
  108. *
  109. * ### Examples ###
  110. * - An ungarded transition to a state with no action performed:
  111. * ~~~{.c}
  112. * {
  113. * .event_type = Event_timeout,
  114. * .condition = NULL,
  115. * .guard = NULL,
  116. * .action = NULL,
  117. * .state_next = &mainMenuState,
  118. * },
  119. * ~~~
  120. * - A guarded transition executing an action
  121. * ~~~{.c}
  122. * {
  123. * .event_type = EVENT_KEYBOARD,
  124. * .condition = NULL,
  125. * .guard = &ensureNumericInput,
  126. * .action = &addToBuffer,
  127. * .state_next = &awaitingInputState,
  128. * },
  129. * ~~~
  130. * - A guarded transition using a condition
  131. * ~~~{.c}
  132. * {
  133. * .event_type = Event_mouse,
  134. * .condition = boxLimits,
  135. * .guard = &coordinatesWithinLimits,
  136. * },
  137. * ~~~
  138. * By using \ref #condition "conditions" a more general guard function can be
  139. * used, operating on the supplied argument #condition. In this example,
  140. * `coordinatesWithinLimits` checks whether the coordinates in the mouse event
  141. * are within the limits of the "box".
  142. *
  143. * \sa event
  144. * \sa state
  145. */
  146. struct transition
  147. {
  148. /** \brief The event that will trigger this transition. */
  149. int event_type;
  150. /**
  151. * \brief Condition that event must fulfil
  152. *
  153. * This variable will be passed to the #guard (if #guard is non-NULL) and
  154. * may be used as a condition that the incoming event's data must fulfil in
  155. * order for the transition to be performed. By using this variable, the
  156. * number of #guard functions can be minimised by making them more general.
  157. */
  158. void *condition;
  159. /**
  160. * \brief Check if data passed with event fulfils a condition
  161. *
  162. * A transition may be conditional. If so, this function, if non-NULL, will
  163. * be called. Its first argument will be supplied with #condition, which
  164. * can be compared against the \ref event::data "payload" in the #event.
  165. * The user may choose to use this argument or not. Only if the result is
  166. * true, the transition will take place.
  167. *
  168. * \param condition event (data) to compare the incoming event against.
  169. * \param event the event passed to the state machine.
  170. *
  171. * \returns true if the event's data fulfils the condition, otherwise false.
  172. */
  173. bool ( *guard )( void *condition, struct event *event );
  174. /**
  175. * \brief Function containing tasks to be performed during the transition
  176. *
  177. * The transition may optionally do some work in this function before
  178. * entering the next state. May be NULL.
  179. *
  180. * \param state_current_data the leaving state's \ref state::data "data"
  181. * \param event the event passed to the state machine.
  182. * \param state_new_data the new state's (the \ref state::state_entry
  183. * "state_entry" of any (chain of) parent states, not the parent state
  184. * itself) \ref state::data "data"
  185. */
  186. void ( *action )( void *state_current_data, struct event *event,
  187. void *state_new_data );
  188. /**
  189. * \brief The next state
  190. *
  191. * This must point to the next state that will be entered. It cannot be
  192. * NULL. If it is, the state machine will detect it and enter the \ref
  193. * state_machine::state_error "error state".
  194. */
  195. struct state *state_next;
  196. };
  197. /**
  198. * \brief State
  199. *
  200. * The current state in a state machine moves to a new state when one of the
  201. * #transitions in the current state triggers on an event. An optional \ref
  202. * #action_exti "exit action" is called when the state is left, and an \ref
  203. * #action_entry "entry action" is called when the state machine enters a new
  204. * state. If a state returns to itself, neither #action_exti nor #action_entry
  205. * will be called. An optional \ref transition::action "transition action" is
  206. * called in either case.
  207. *
  208. * States may be organised in a hierarchy by setting \ref #state_parent
  209. * "parent states". When a group/parent state is entered, the state machine is
  210. * redirected to the group state's \ref #state_entry "entry state" (if
  211. * non-NULL). If an event does not trigger a transition in a state and if the
  212. * state has a parent state, the event will be passed to the parent state.
  213. * This behaviour is repeated for all parents. Thus all children of a state
  214. * have a set of common #transitions. A parent state's #action_entry will not
  215. * be called if an event is passed on to a child state.
  216. *
  217. * The following lists the different types of states that may be created, and
  218. * how to create them:
  219. *
  220. * ### Normal state ###
  221. * ~~~{.c}
  222. * struct state normalState = {
  223. * .state_parent = &groupState,
  224. * .state_entry = NULL,
  225. * .transition = (struct transition[]){
  226. * { EVENT_KEYBOARD, (void *)(intptr_t)'\n', &keyboard_char_compare,
  227. * NULL, &msgReceivedState },
  228. * },
  229. * .transition_nums = 1,
  230. * .data = normalstate_data,
  231. * .action_entry = &doSomething,
  232. * .action_exti = &cleanUp,
  233. * };
  234. * ~~~
  235. * In this example, `normalState` is a child of `groupState`, but the
  236. * #state_parent value may also be NULL to indicate that it is not a child of
  237. * any group state.
  238. *
  239. * ### Group/parent state ###
  240. * A state becomes a group/parent state when it is linked to by child states
  241. * by using #state_parent. No members in the group state need to be set in a
  242. * particular way. A parent state may also have a parent.
  243. * ~~~{.c}
  244. * struct state groupState = {
  245. * .state_entry = &normalState,
  246. * .action_entry = NULL,
  247. * ~~~
  248. * If there are any transitions in the state machine that lead to a group
  249. * state, it makes sense to define an entry state in the group. This can be
  250. * done by using #state_entry, but it is not mandatory. If the #state_entry
  251. * state has children, the chain of children will be traversed until a child
  252. * with its #state_entry set to NULL is found.
  253. *
  254. * \note If #state_entry is defined for a group state, the group state's
  255. * #action_entry will not be called (the state pointed to by #state_entry (after
  256. * following the chain of children), however, will have its #action_entry
  257. * called).
  258. *
  259. * \warning The state machine cannot detect cycles in parent chains and
  260. * children chains. If such cycles are present, statem_handle_event() will
  261. * never finish due to never-ending loops.
  262. *
  263. * ### Final state ###
  264. * A final state is a state that terminates the state machine. A state is
  265. * considered as a final state if its #transition_nums is 0:
  266. * ~~~{.c}
  267. * struct state finalState = {
  268. * .transitions = NULL,
  269. * .transition_nums = 0,
  270. * ~~~
  271. * The error state used by the state machine to indicate errors should be a
  272. * final state. Any calls to statem_handle_event() when the current state is a
  273. * final state will return #STATEM_STATE_NOCHANGE.
  274. *
  275. * \sa event
  276. * \sa transition
  277. */
  278. struct state
  279. {
  280. /**
  281. * \brief If the state has a parent state, this pointer must be non-NULL.
  282. */
  283. struct state *state_parent;
  284. /**
  285. * \brief If this state is a parent state, this pointer may point to a
  286. * child state that serves as an entry point.
  287. */
  288. struct state *state_entry;
  289. /**
  290. * \brief An array of transitions for the state.
  291. */
  292. struct transition *transitions;
  293. /**
  294. * \brief Number of transitions in the #transitions array.
  295. */
  296. size_t transition_nums;
  297. /**
  298. * \brief Data that will be available for the state in its #action_entry and
  299. * #action_exti, and in any \ref transition::action "transition action"
  300. */
  301. void *data;
  302. /**
  303. * \brief This function is called whenever the state is being entered. May
  304. * be NULL.
  305. *
  306. * \note If a state returns to itself through a transition (either directly
  307. * or through a parent/group sate), its #action_entry will not be called.
  308. *
  309. * \note A group/parent state with its #state_entry defined will not have
  310. * its #action_entry called.
  311. *
  312. * \param state_data the state's #data will be passed.
  313. * \param event the event that triggered the transition will be passed.
  314. */
  315. void ( *action_entry )( void *state_data, struct event *event );
  316. /**
  317. * \brief This function is called whenever the state is being left. May be
  318. * NULL.
  319. *
  320. * \note If a state returns to itself through a transition (either directly
  321. * or through a parent/group sate), its #action_exti will not be called.
  322. *
  323. * \param state_data the state's #data will be passed.
  324. * \param event the event that triggered a transition will be passed.
  325. */
  326. void ( *action_exti )( void *state_data, struct event *event );
  327. };
  328. /**
  329. * \brief State machine
  330. *
  331. * There is no need to manipulate the members directly.
  332. */
  333. struct state_machine
  334. {
  335. /** \brief Pointer to the current state */
  336. struct state *state_current;
  337. /**
  338. * \brief Pointer to previous state
  339. *
  340. * The previous state is stored for convenience in case the user needs to
  341. * keep track of previous states.
  342. */
  343. struct state *state_previous;
  344. /**
  345. * \brief Pointer to a state that will be entered whenever an error occurs
  346. * in the state machine.
  347. *
  348. * See #STATEM_ERR_STATE_RECHED for when the state machine enters the
  349. * error state.
  350. */
  351. struct state *state_error;
  352. };
  353. /**
  354. * \brief Initialise the state machine
  355. *
  356. * This function initialises the supplied state_machine and sets the current
  357. * state to \pn{state_init}. No actions are performed until
  358. * statem_handle_event() is called. It is safe to call this function numerous
  359. * times, for instance in order to reset/restart the state machine if a final
  360. * state has been reached.
  361. *
  362. * \note The \ref #state::action_entry "entry action" for \pn{state_init}
  363. * will not be called.
  364. *
  365. * \note If \pn{state_init} is a parent state with its \ref
  366. * state::state_entry "state_entry" defined, it will not be entered. The user
  367. * must explicitly set the initial state.
  368. *
  369. * \param state_machine the state machine to initialise.
  370. * \param state_init the initial state of the state machine.
  371. * \param state_error pointer to a state that acts a final state and notifies
  372. * the system/user that an error has occurred.
  373. */
  374. int statem_init( struct state_machine *state_machine,
  375. struct state *state_init, struct state *state_error );
  376. /**
  377. * \brief statem_handle_event() return values
  378. */
  379. enum statem_handle_event_return_vals
  380. {
  381. /** \brief Erroneous arguments were passed */
  382. STATEM_ERR_ARG = -2,
  383. /**
  384. * \brief The error state was reached
  385. *
  386. * This value is returned either when the state machine enters the error
  387. * state itself as a result of an error, or when the error state is the
  388. * next state as a result of a successful transition.
  389. *
  390. * The state machine enters the state machine if any of the following
  391. * happens:
  392. * - The current state is NULL
  393. * - A transition for the current event did not define the next state
  394. */
  395. STATEM_ERR_STATE_RECHED,
  396. /** \brief The current state changed into a non-final state */
  397. STATEM_STATE_CHANGED,
  398. /**
  399. * \brief The state changed back to itself
  400. *
  401. * The state can return to itself either directly or indirectly. An
  402. * indirect path may inlude a transition from a parent state and the use of
  403. * \ref state::state_entry "state_entrys".
  404. */
  405. STATEM_STATE_LOOPSELF,
  406. /**
  407. * \brief The current state did not change on the given event
  408. *
  409. * If any event passed to the state machine should result in a state
  410. * change, this return value should be considered as an error.
  411. */
  412. STATEM_STATE_NOCHANGE,
  413. /** \brief A final state (any but the error state) was reached */
  414. STATEM_FINAL_STATE_RECHED,
  415. };
  416. /**
  417. * \brief Pass an event to the state machine
  418. *
  419. * The event will be passed to the current state, and possibly to the current
  420. * state's parent states (if any). If the event triggers a transition, a new
  421. * state will be entered. If the transition has an \ref transition::action
  422. * "action" defined, it will be called. If the transition is to a state other
  423. * than the current state, the current state's \ref state::action_exti
  424. * "exit action" is called (if defined). Likewise, if the state is a new
  425. * state, the new state's \ref state::action_entry "entry action" is called (if
  426. * defined).
  427. *
  428. * The returned value is negative if an error occurs.
  429. *
  430. * \param state_machine the state machine to pass an event to.
  431. * \param event the event to be handled.
  432. *
  433. * \return #statem_handle_event_return_vals
  434. */
  435. int statem_handle_event( struct state_machine *state_machine,
  436. struct event *event );
  437. /**
  438. * \brief Get the current state
  439. *
  440. * \param state_machine the state machine to get the current state from.
  441. *
  442. * \retval a pointer to the current state.
  443. * \retval NULL if \pn{state_machine} is NULL.
  444. */
  445. struct state *statem_state_current( struct state_machine *state_machine );
  446. /**
  447. * \brief Get the previous state
  448. *
  449. * \param state_machine the state machine to get the previous state from.
  450. *
  451. * \retval the previous state.
  452. * \retval NULL if \pn{state_machine} is NULL.
  453. * \retval NULL if there has not yet been any transitions.
  454. */
  455. struct state *statem_state_previous( struct state_machine *state_machine );
  456. /**
  457. * \brief Check if the state machine has stopped
  458. *
  459. * \param state_machine the state machine to test.
  460. *
  461. * \retval true if the state machine has reached a final state.
  462. * \retval false if \pn{state_machine} is NULL or if the current state is not a
  463. * final state.
  464. */
  465. int statem_stopped( struct state_machine *state_machine );
  466. #endif // state_machine_H
  467. /**
  468. * @}
  469. */