Immer wieder kommen Statemachines in Programmen vor. Die Implementierung einer solchen kann bzw. muss unterschiedlich ausfallen, je nach dem wie groß eine solche Statemachine werden kann.
Ein erster kleiner Entwurf könnte wie folgt aussehen:
while(1) { switch(state) { case state1: // do something break; case state2: // do different thing // no break case state3: // do other things break; default: // Error: invalid state break; } }
Vom Ansatz her ist das eine sehr überschaubare Statemachine. Die Variable state stellt den aktuellen Status dar und in der switch-Anweisung wird in den passenden Zweig die Arbeit fortgesetzt. Sind jedoch die Anweisungen sehr umfangreich und sehr viele Status zu verwalten, kann die Übersicht schnell verloren gehen. Dabei wird es schwer zu unterscheiden zwischen dem „Funktionskörper“ der für den jeweiligen Status ausgeführt werden soll und der Bestimmung für den Folgezustand. Der nächste Zustand wird durch setzten von state im noch aktuellen Zustand durchgeführt.
Bei Funktionen wird jeder Zustand (oben case genannt) in einer Funktion abgelegt - sozusagen der „Funktionskörper“ des Zustandes. Mit einem Pointer auf Funktionen wird auf die aktuelle Funktion referenziert. Ein mühsames Auswerten, welcher Zweig der Staemachine angesprungen werden muss, wie in der switch-Anweisung, bleibt erspart. Bei vielen Zuständen kann das sehr viel schneller gehen. Der Folgezustand wird durch zuweisen der Adresse der neuen Funktion (Zustand) an den Pointer durchgeführt.
Hier wird ähnlich zu Funktionen und Fkt. Pointer ein Pointer auf ein Objekt gesetzt.
Der Objekttyp für den Zustand (state) könnte Methoden definieren wie onEnter(), onLeave().
Der Objekttyp für den Zustandsautomaten (Statemachine) könnte als Klassenvariable den Zeiger auf den Zustand führen. Des weiteren könnte mit mit einer Register-Funktion der Übergang von Zustand zu Zustand definiert werden, dabei könnte eine Transfer-Funktion (als Callback) registriert werden.
Bei einem Übergang werden folgende Schritte ausgeführt:
UrStammVater // Dient als "Vorlage" für 'StammVater'-Klassen/Objekte.
|
+-- StammVater1 // Erste Statemachine, könnte als Klassenvariable den Zeiger auf den aktuellen 'StateX_Y' für diese Statemachine enthalten.
| |
| +-- State1_1 // erter 'State' in dieser Statemachine
| +-- State1_2
: :
| +-- State1_n // letzter 'State' in dieser Statemachine
|
+-- StammVater2 // eine zweite unabhängige Statemachine
|
+-- State2_1
+-- State2_2
:
+-- State2_n