Last active
October 6, 2015 18:08
-
-
Save tfeldmann/3033278 to your computer and use it in GitHub Desktop.
C - Statemachine
This file contains 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
/** | |
* Erweiterte C-Statemachine | |
* Das Programm gibt folgendes aus: | |
* | |
* BEGIN: Es geht los. Ich initialisiere das Ganze. | |
* BEGIN: Es geht weiter in den Zustand ADDITION_SMALL | |
* BEGIN: Auf Wiedersehen! | |
* ADDITION_SMALL: Ich fange erst einmal mit kleinen Zahlen an. | |
* ADDITION_SMALL: Addiere Eins... | |
* ADDITION_SMALL: Addiere Eins... | |
* ADDITION_BIG: Small hat sich gar nicht verabschiedet. Frech. | |
* ADDITION_BIG: Jetzt große Zahlen. | |
* ADDITION_BIG: Addiere Zehn... | |
* ADDITION_BIG: Addiere Zehn... | |
* ADDITION_BIG: Addiere Zehn... | |
* ADDITION_BIG: Addiere Zehn... | |
* ADDITION_BIG: Ergebnis: 42! | |
*/ | |
#include <stdio.h> | |
// ----------------------------------------------------------------------------- | |
// Defines für die Statemachine | |
// | |
#define STATES(_states_...) char flag_state_inited; \ | |
enum State {_states_, STATE_NONE} state; \ | |
State next_state; | |
#define STATE_MACHINE_START(_x_) flag_state_inited = false; \ | |
state = _x_; next_state = _x_; | |
#define STATE_SWITCH(_x_) next_state = _x_ | |
#define STATE_IS_ACTIVE(_x_) (state == _x_) | |
#define STATEMACHINE switch (state) { | |
#define STATE_ENTER(_x_) case _x_: if (!flag_state_inited) { \ | |
flag_state_inited = 1; | |
#define STATE_LOOP } else { if (next_state == state) { | |
#define STATE_LEAVE } else { state = next_state; \ | |
flag_state_inited = false; | |
#define END_OF_STATE }} break; | |
#define END_STATEMACHINE STATE_ENTER(STATE_NONE) STATE_LOOP \ | |
STATE_LEAVE END_OF_STATE default: break; } | |
// ----------------------------------------------------------------------------- | |
// Der eigentliche Code | |
// | |
int some_number; | |
STATES( | |
// hier einfach deine Zustände einfügen | |
BEGIN, | |
ADDITION_SMALL, | |
ADDITION_BIG | |
); | |
void statemachine() | |
{ | |
STATEMACHINE | |
STATE_ENTER(BEGIN) | |
puts("BEGIN: Es geht los. Ich initialisiere das Ganze."); | |
some_number = 0; | |
STATE_LOOP | |
puts("BEGIN: Es geht weiter in den Zustand ADDITION_SMALL"); | |
STATE_SWITCH(ADDITION_SMALL); | |
STATE_LEAVE | |
puts("BEGIN: Auf Wiedersehen!"); | |
END_OF_STATE | |
STATE_ENTER(ADDITION_SMALL) | |
puts("ADDITION_SMALL: Ich fange erst einmal mit kleinen Zahlen an."); | |
STATE_LOOP | |
puts("ADDITION_SMALL: Addiere Eins..."); | |
some_number += 1; | |
// in den loop kommt die Abbruchbedingung, z.B. durch Sensorwerte | |
if (some_number == 2) | |
{ | |
STATE_SWITCH(ADDITION_BIG); | |
} | |
STATE_LEAVE | |
END_OF_STATE | |
STATE_ENTER(ADDITION_BIG) | |
puts("ADDITION_BIG: Small hat sich gar nicht verabschiedet. Frech."); | |
puts("ADDITION_BIG: Jetzt große Zahlen."); | |
STATE_LOOP | |
puts("ADDITION_BIG: Addiere Zehn..."); | |
some_number += 10; | |
if (some_number >= 42) | |
{ | |
STATE_SWITCH(STATE_NONE); // fertig -> kein Zustand ausgewählt | |
} | |
STATE_LEAVE | |
printf("ADDITION_BIG: Ergebnis: %d!\n", some_number); | |
END_OF_STATE | |
END_STATEMACHINE | |
} | |
int main() | |
{ | |
STATE_MACHINE_START(BEGIN); | |
while (!STATE_IS_ACTIVE(STATE_NONE)) | |
{ | |
// der statemachine() Aufruf kommt dann in deinen loop() | |
statemachine(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment