-
Notifications
You must be signed in to change notification settings - Fork 0
/
Example.cpp
157 lines (126 loc) · 2.85 KB
/
Example.cpp
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Just a small state machine (3 states) as demonstration.
//
// Compile like this:
// g++ Macho.cpp Example.cpp
#include "Macho.hpp"
#include <iostream>
using namespace std;
namespace Example {
////////////////////////////////////////////////////////
// State declarations
// Machine's top state
TOPSTATE(Top) {
// Top state variables (visible to all substates)
struct Box {
Box() : data(0) {}
long data;
};
STATE(Top)
// Machine's event protocol
virtual void event1(int i) {}
virtual void event2(long l) {}
private:
// special actions
void entry();
void exit();
void init();
void init(int);
};
// A superstate
SUBSTATE(Super, Top) {
STATE(Super)
// This state has history
HISTORY()
private:
// Entry and exit actions of state
void entry();
void exit();
};
// A substate
SUBSTATE(StateA, Super) {
// State variables
struct Box {
Box() : data(0) {}
int data;
};
STATE(StateA)
// Event handler
void event1(int i);
private:
void entry();
void init(int);
void exit();
};
// A substate
SUBSTATE(StateB, Super) {
STATE(StateB)
void event2(long l);
private:
void entry();
void exit();
};
////////////////////////////////////////////////////////
// Event handler implementations
// Top state
void Top::entry() { cout << "Top::entry" << endl; }
void Top::exit() { cout << "Top::exit" << endl; }
void Top::init() {
// Initialize state with box
setState<StateA>(44);
}
void Top::init(int i) {
box().data = i;
init();
}
// Super state
void Super::entry() { cout << "Super::entry" << endl; }
void Super::exit() { cout << "Super::exit" << endl; }
// StateA state
void StateA::entry() { cout << "StateA::entry" << endl; }
void StateA::init(int i) { cout << "StateA::init " << i << endl; }
void StateA::exit() { cout << "StateA::exit" << endl; }
void StateA::event1(int i) {
box().data = i;
cout << "StateA::box().data: " << box().data << endl;
setState<StateB>();
}
// StateB state
void StateB::entry() { cout << "StateB::entry" << endl; }
void StateB::exit() { cout << "StateB::exit" << endl; }
void StateB::event2(long l) {
Top::box().data = l;
cout << "Top::box().data: " << Top::box().data << endl;
setState<StateA>(42);
}
} // namespace Example
//////////////////////////////////////////////////////////////////////
// Test run
int main() {
using namespace Macho;
// Initialize state machine with some data
Machine<Example::Top> m(State<Example::Top>(11));
// Dispatch some events
m->event1(42);
m->event2(43);
// Inspect state machine
cout << "m.box().data: " << m.box().data << endl;
return 0;
}
/*
Output is:
Top::entry
Super::entry
StateA::entry
StateA::init 44
StateA::box().data: 42
StateA::exit
StateB::entry
Top::box().data: 43
StateB::exit
StateA::entry
StateA::init 42
m.box().data: 43
StateA::exit
Super::exit
Top::exit
*/