Created
June 19, 2019 18:20
-
-
Save dheeptuck/b9c2d6e32d87f5fc67ecf8edb9adcf77 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdio.h" | |
typedef void (*ptStateFunc)(void); | |
/// Define all events | |
typedef enum eEvent { | |
EVT_NO_EVENT, | |
EVT_BUTTON_PRESSED, | |
EVT_BEAN_CRUSHED, | |
EVT_MILK_HEATED, | |
EVT_WATER_MIXED, | |
EVT_DISPENSED, | |
EVT_NO_BEAN, | |
EVT_NO_MILK, | |
EVT_NO_WATER | |
} eEvent; | |
/// Define all states | |
void stateIdle(void); | |
void stateCrushBean(void); | |
void stateHeatMilk(void); | |
void stateMixWater(void); | |
void stateDispenseCofee(void); | |
void stateError(void); | |
/// Define a row of STM | |
typedef struct stStmRow { | |
ptStateFunc pSrcState; | |
eEvent eEvt; | |
ptStateFunc pDestState; | |
} stStmRow; | |
void stateIdle(void) | |
{ | |
if(bIsStateFirstEntry) | |
{ | |
/// Do stuff for first entry(state initialization stuff) | |
} | |
if(bIsStateAboutToExit) | |
{ | |
/// Handle exit(i.e free up resources) | |
} | |
} | |
void stateCrushBean(void) | |
{ | |
if(bIsStateFirstEntry) | |
{ | |
/// Do stuff for first entry(state initialization stuff) | |
/// TurnHeaterOn(); | |
} | |
if(bIsStateAboutToExit) | |
{ | |
/// Handle exit(i.e free up resources) | |
/// TurnHeaterOff(); | |
} | |
} | |
void stateHeatMilk(void) | |
{ | |
} | |
void stateMixWater(void) | |
{ | |
} | |
void stateDispenseCofee(void) | |
{ | |
} | |
void stateError(void) | |
{ | |
} | |
static eEvent eCurrentEvent = EVT_NO_EVENT; | |
static ptStateFunc stCurrentState = stateIdle; | |
/// Used to flag first entry to a state | |
static bool bIsStateFirstEntry = false; | |
/// Used to flag an imminent exit from the state | |
static bool bIsStateAboutToExit = false; | |
stStmRow stStm[] = { | |
{stateIdle , EVT_BUTTON_PRESSED, stateCrushBean }, | |
{stateCrushBean, EVT_BEAN_CRUSHED , stateHeatMilk }, | |
{stateCrushBean, EVT_NO_BEAN , stateError }, | |
{stateHeatMilk , EVT_MILK_HEATED , stateMixWater }, | |
{stateHeatMilk , EVT_NO_MILK , stateError }, | |
{stateMixWater , EVT_WATER_MIXED , stateDispenseCofee}, | |
{stateMixWater , EVT_NO_WATER , stateError } | |
}; | |
void StateMachineHandler() | |
{ | |
int idx = 0; | |
if(EVT_NO_EVENT != eCurrentEvent) | |
{ | |
for(;idx < sizeof(stStm)/sizeof(stStmRow); idx++) | |
{ | |
if( (stStm[idx].pSrcState == stCurrentState) && | |
(stStm[idx].eEvt == eCurrentEvent)) | |
{ | |
/// Clear event | |
eCurrentEvent = EVT_NO_EVENT; | |
/// Notify the state that the exit is imminent; | |
bIsStateAboutToExit = true; | |
stCurrentState(); | |
/// Move to new state | |
stCurrentState = stStm[idx].pDestState; | |
/// Flag that this is the first entry to the state | |
bIsStateFirstEntry = true; | |
} | |
} | |
} | |
if(NULL != stCurrentState) | |
{ | |
/// Run the state | |
stCurrentState(); | |
/// Unfllag first entry | |
bIsStateFirstEntry = false; | |
} | |
} | |
int main() | |
{ | |
while(true) | |
{ | |
StateMachineHandler(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment