statemachine.cpp

// State machine
// 
// Simplified code as example for a state machine.
//
// by feyd//godX.de
 
#include <string>
#include <stdio.h>
 
// State class waiting for "hello" followed by username "user" and password "mypassword"
// if everything was correct the state will reach "authenticated"
// if the chain is broken (in "hello" or "password" state) the state will enter "disconnected"
// after valid authentication the state machine will wait for "disconnect" keyword and enter the "disconnected" state
 
class CStateMachine
{
    enum {
        STATE_CONNECT = 0,
        STATE_USERNAME,
        STATE_PASSWORD,
        STATE_AUTHENTICATED,
        STATE_DISCONNECTED,
        STATE_MAX
    };
public:
    CStateMachine() : m_nCurrentState(STATE_CONNECT) {}
    virtual ~CStateMachine() {}
 
    void Input(const std::string& sInput)
    {
        switch(m_nCurrentState)
        {
            case STATE_CONNECT:
                if(sInput.compare("hello")==0)
                {
                    m_nCurrentState = STATE_USERNAME;
                } else {
                    m_nCurrentState = STATE_DISCONNECTED;
                }
                break;
            case STATE_USERNAME:
                // store username
                m_sUsername = sInput;
                m_nCurrentState = STATE_PASSWORD;
                break;
            case STATE_PASSWORD:
                // check username and password
                if(m_sUsername=="user" && sInput=="mypassword")
                {
                    m_nCurrentState = STATE_AUTHENTICATED;
                } else {
                    m_nCurrentState = STATE_DISCONNECTED;
                }
                break;
            case STATE_AUTHENTICATED:
                if(sInput.compare("disconnect")==0)
                {
                    m_nCurrentState = STATE_DISCONNECTED;
                }
            case STATE_DISCONNECTED:
                break;
            default:;
        };
    }
 
    void Output()
    {
        switch(m_nCurrentState)
        {
            case STATE_CONNECT:         printf("CONNECT      "); break;
            case STATE_USERNAME:        printf("USERNAME     "); break;
            case STATE_PASSWORD:        printf("PASSWORD     "); break;
            case STATE_AUTHENTICATED:   printf("AUTHENTICATED"); break;
            case STATE_DISCONNECTED:    printf("DISCONNECTED "); break;
            default:                    printf("Unknown State"); break;
        };
    }
 
    int GetCurrentState() const 
    {
        return m_nCurrentState;
    }
protected:
    int m_nCurrentState;
 
    std::string m_sUsername;
};
 
// Application entry point (from libc)
int main(int argc, const char* argv[])
{
    printf("State machine example...\r\n\r\n");
 
    {
        CStateMachine stateMachine;
        for(int n=1; n<argc; n++)
        {
            printf("    (%3d) %10s: ", n, argv[n]);
            stateMachine.Output();
            printf(" -> ");
            stateMachine.Input(argv[n]);
            stateMachine.Output();
            printf("\r\n");
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106