/******************************************************************** * Tiny state machine - Version 1.1 * * Developed by Flashsystems 2012-2014 * No rights reserved. ********************************************************************/ /** * Macro for event declaration */ #define DECLARE_EVENTS(_MACHINENAME, ...) \ enum SMEvents_##_MACHINENAME { __VA_ARGS__ }; /** * Macro for declaration of state functions and a transition handlers */ #define STATEFUNC(_MACHINENAME, _STATENAME) enum SMEvents_##_MACHINENAME _MACHINENAME##_##_STATENAME() // C compilers do not know about bool so we use int #ifdef __cplusplus #define HANDLERFUNC(_MACHINENAME, _EVENTNAME) bool _MACHINENAME##_##_EVENTNAME() #else #define HANDLERFUNC(_MACHINENAME, _EVENTNAME) int _MACHINENAME##_##_EVENTNAME() #endif /** * The following macros implement the real state machine. * BEGIN_STATE_MACHINE: Starts the state machine declaration. * STATE: Declares a new state. * EVENT: Declares a new event that can happen for this state. * EVENT_WITH_HANDLER: Declares a new event that can happen and an additional transition handler for this event. * END_STATE: Terminates a state declaration. * END_STATE_MACHINE: Terminates the state machine declaration. */ #define BEGIN_STATE_MACHINE(_MACHINENAME, _STARTSTATE) \ { \ enum SMEvents_##_MACHINENAME (*currentStateFunc)() = _MACHINENAME##_##_STARTSTATE; \ while (1) \ { \ if (0) {} #define STATE(_MACHINENAME, _STATENAME) \ else if (currentStateFunc == _MACHINENAME##_##_STATENAME) \ { \ switch (_MACHINENAME##_##_STATENAME()) \ { #define EVENT(_MACHINENAME, _EVENTNAME, _STATEFUNC) \ case _EVENTNAME: \ currentStateFunc = _MACHINENAME##_##_STATEFUNC; \ break; #define EVENT_WITH_HANDLER(_MACHINENAME, _EVENTNAME, _STATEFUNC, _TRANSITION_HANDLER) \ case _EVENTNAME: \ if (_MACHINENAME##_##_TRANSITION_HANDLER()) \ currentStateFunc = _MACHINENAME##_##_STATEFUNC; \ break; #define END_STATE() \ default: \ break; \ } \ } #define END_STATE_MACHINE() \ } \ }