1 | #include <iostream>
|
2 | #include <vector>
|
3 |
|
4 | using namespace std;
|
5 |
|
6 | // *********************************************************
|
7 | // Funktor, Basisklasse
|
8 | //
|
9 | // Ein Funktor ist ein Objekt, welches einen Funktionsaufruf kapselt
|
10 | //
|
11 | class TFunctor
|
12 | {
|
13 | public:
|
14 | virtual unsigned char operator()() = 0;
|
15 | };
|
16 |
|
17 | // Funktor, konkrete Klasse die auf die aufzurufende Klasse geht
|
18 | //
|
19 | // Diese Klasse verbindet den Funktionspointer mit dem konkreten Objekt
|
20 | // welches aufgerufen werden soll
|
21 | template <class T> class FSMFunctor : public TFunctor
|
22 | {
|
23 | private:
|
24 | unsigned char (T::*fpt)(); // pointer to member function
|
25 | T* pObject; // pointer to object
|
26 |
|
27 | public:
|
28 | FSMFunctor(T* pObject_, unsigned char(T::*fpt_)())
|
29 | : pObject( pObject_ ),
|
30 | fpt( fpt_ )
|
31 | {
|
32 | }
|
33 |
|
34 | virtual unsigned char operator()()
|
35 | {
|
36 | return (*pObject.*fpt)();
|
37 | }
|
38 | };
|
39 |
|
40 | // *********************************************************
|
41 | // FSMDispatchFunction verbindet einen Status mit einer aufzurufenden
|
42 | // Funktion (über einen Funktor)
|
43 | //
|
44 | class FSMDispatchFunction
|
45 | {
|
46 | public:
|
47 | FSMDispatchFunction( int State_, TFunctor* pFunc_ )
|
48 | : State( State_ ),
|
49 | pFunction( pFunc_ )
|
50 | {
|
51 | }
|
52 |
|
53 | virtual unsigned char operator()()
|
54 | {
|
55 | return (*pFunction)();
|
56 | }
|
57 |
|
58 | int GetState() const { return State; }
|
59 |
|
60 | protected:
|
61 | int State; // der Status des Objektes
|
62 | TFunctor* pFunction; // Funktion die fuer diesen Status gerufen werden soll
|
63 | };
|
64 |
|
65 | // *********************************************************
|
66 | // Basisklasse für eine Statemachine
|
67 | //
|
68 | class FSM
|
69 | {
|
70 | public:
|
71 | virtual ~FSM() = 0 { };
|
72 |
|
73 | unsigned char Trigger();
|
74 | void RegisterDispatch( int State, TFunctor* Function );
|
75 |
|
76 | protected:
|
77 | virtual void FSMSwitch();
|
78 | virtual void FSMPolling();
|
79 | virtual unsigned char FSMDispatch();
|
80 |
|
81 | unsigned char State;
|
82 | unsigned char NextState;
|
83 |
|
84 | std::vector<FSMDispatchFunction*> Functions;
|
85 | };
|
86 |
|
87 | void FSM::RegisterDispatch( int State, TFunctor* Function )
|
88 | {
|
89 | Functions.push_back( new FSMDispatchFunction( State, Function ) );
|
90 | }
|
91 |
|
92 | void FSM::FSMSwitch()
|
93 | {
|
94 | State = NextState;
|
95 | }
|
96 |
|
97 | void FSM::FSMPolling()
|
98 | {
|
99 | }
|
100 |
|
101 | unsigned char FSM::FSMDispatch()
|
102 | {
|
103 | for( size_t i = 0; i < Functions.size(); ++i ) {
|
104 | if( Functions[i]->GetState() == State ) {
|
105 | return (*Functions[i])();
|
106 | }
|
107 | }
|
108 |
|
109 | return 0;
|
110 | }
|
111 |
|
112 | unsigned char FSM::Trigger()
|
113 | {
|
114 | unsigned char ReturnVal;
|
115 |
|
116 | FSMSwitch();
|
117 | ReturnVal = FSMDispatch();
|
118 | FSMPolling();
|
119 |
|
120 | return ReturnVal;
|
121 | }
|
122 |
|
123 | // *********************************************************
|
124 |
|
125 | class Disp : public FSM
|
126 | {
|
127 | public:
|
128 | Disp();
|
129 |
|
130 | private:
|
131 | unsigned char Init();
|
132 | unsigned char PowerDown();
|
133 | unsigned char PowerUp();
|
134 |
|
135 | static const int IdleState = 0;
|
136 | static const int InitState = 1;
|
137 | static const int PowerUpState = 2;
|
138 | static const int PowerDownState = 3;
|
139 | };
|
140 |
|
141 | Disp::Disp()
|
142 | {
|
143 | State = IdleState;
|
144 | NextState = InitState;
|
145 |
|
146 | RegisterDispatch( InitState, new FSMFunctor<Disp>( this, &Disp::Init ) );
|
147 | RegisterDispatch( PowerUpState, new FSMFunctor<Disp>( this, &Disp::PowerUp ) );
|
148 | RegisterDispatch( PowerDownState, new FSMFunctor<Disp>( this, &Disp::PowerDown ) );
|
149 | }
|
150 |
|
151 | unsigned char Disp::Init()
|
152 | {
|
153 | cout << "Disp: Init" << std::endl;
|
154 |
|
155 | NextState = PowerUpState;
|
156 |
|
157 | return 0;
|
158 | }
|
159 |
|
160 | unsigned char Disp::PowerUp()
|
161 | {
|
162 | cout << "Disp: Power up" << std::endl;
|
163 |
|
164 | NextState = PowerDownState;
|
165 |
|
166 | return 0;
|
167 | }
|
168 |
|
169 | unsigned char Disp::PowerDown()
|
170 | {
|
171 | cout << "Disp: Power down" << std::endl;
|
172 |
|
173 | NextState = InitState;
|
174 |
|
175 | return 0;
|
176 | }
|
177 |
|
178 | // ******************************************
|
179 | class RS232 : public FSM
|
180 | {
|
181 | public:
|
182 | RS232();
|
183 |
|
184 | private:
|
185 | unsigned char Init();
|
186 | unsigned char Dial();
|
187 | unsigned char HangUp();
|
188 |
|
189 | static const int IdleState = 0;
|
190 | static const int InitState = 1;
|
191 | static const int DialState = 2;
|
192 | static const int HangUpState = 3;
|
193 | };
|
194 |
|
195 | RS232::RS232()
|
196 | {
|
197 | State = IdleState;
|
198 | NextState = InitState;
|
199 |
|
200 | RegisterDispatch( InitState, new FSMFunctor<RS232>( this, &RS232::Init ) );
|
201 | RegisterDispatch( DialState, new FSMFunctor<RS232>( this, &RS232::Dial ) );
|
202 | RegisterDispatch( HangUpState, new FSMFunctor<RS232>( this, &RS232::HangUp ) );
|
203 | }
|
204 |
|
205 | unsigned char RS232::Init()
|
206 | {
|
207 | cout << "RS232: Init\n";
|
208 | NextState = RS232::DialState;
|
209 |
|
210 | return 1;
|
211 | }
|
212 |
|
213 | unsigned char RS232::Dial()
|
214 | {
|
215 | cout << "RS232: Dial\n";
|
216 | NextState = RS232::HangUpState;
|
217 |
|
218 | return 1;
|
219 | }
|
220 |
|
221 | unsigned char RS232::HangUp()
|
222 | {
|
223 | cout << "RS232: Hanging up\n";
|
224 | NextState = RS232::InitState;
|
225 |
|
226 | return 1;
|
227 | }
|
228 |
|
229 | // ******************************************
|
230 | int main()
|
231 | {
|
232 | Disp* pMyDisp = new Disp();
|
233 | RS232* pMyRS232 = new RS232();
|
234 |
|
235 | while(true) {
|
236 | pMyDisp->Trigger();
|
237 | pMyRS232->Trigger();
|
238 | }
|
239 | }
|