00001
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef StateMachine_h
00032 #define StateMachine_h
00033
00034 #include <ace/Guard_T.h>
00035 #include <ace/Thread_Mutex.h>
00036
00037 template <class State>
00038 struct StateHolder
00039 {
00040 State curr;
00041 State prev;
00042 State next;
00043 };
00044
00137 template <class State, class Result,
00138 class Listener,
00139 class States = StateHolder<State>,
00140 class Callback = Result (Listener::*)(const States& states)
00141 >
00142 class StateMachine
00143 {
00144 public:
00152 StateMachine(int num_of_state)
00153 : m_num(num_of_state),
00154 m_entry (new Callback[m_num]),
00155 m_predo (new Callback[m_num]),
00156 m_do (new Callback[m_num]),
00157 m_postdo(new Callback[m_num]),
00158 m_exit (new Callback[m_num])
00159 {
00160 setNullFunc(m_entry, NULL);
00161 setNullFunc(m_do, NULL);
00162 setNullFunc(m_exit, NULL);
00163 setNullFunc(m_predo, NULL);
00164 setNullFunc(m_postdo, NULL);
00165 m_transit = NULL;
00166 };
00167
00168
00176 void setNOP(Callback call_back)
00177 {
00178 setNullFunc(m_entry, call_back);
00179 setNullFunc(m_do, call_back);
00180 setNullFunc(m_exit, call_back);
00181 setNullFunc(m_predo, call_back);
00182 setNullFunc(m_postdo, call_back);
00183 m_transit = call_back;
00184 }
00185
00186
00194 void setListener(Listener* listener)
00195 {
00196 m_listener = listener;
00197 }
00198
00199
00207 bool setEntryAction(State state, Callback call_back)
00208 {
00209 m_entry[state] = call_back;
00210 return true;
00211 }
00212
00213
00221 bool setPreDoAction(State state, Callback call_back)
00222 {
00223 m_predo[state] = call_back;
00224 return true;
00225 }
00226
00227
00235 bool setDoAction(State state, Callback call_back)
00236 {
00237 m_do[state] = call_back;
00238 return true;
00239
00240 }
00241
00242
00250 bool setPostDoAction(State state, Callback call_back)
00251 {
00252 m_postdo[state] = call_back;
00253 return true;
00254 }
00255
00256
00264 bool setExitAction(State state, Callback call_back)
00265 {
00266 m_exit[state] = call_back;
00267 return true;
00268 }
00269
00270
00278 bool setTransitionAction(Callback call_back)
00279 {
00280 m_transit = call_back;
00281 return true;
00282 }
00283
00284
00292 void setStartState(States states)
00293 {
00294 m_states.curr = states.curr;
00295 m_states.prev = states.prev;
00296 m_states.next = states.next;
00297 }
00298
00299
00307 States getStates()
00308 {
00309 ACE_Guard<ACE_Thread_Mutex> guard(m_mutex);
00310 return m_states;
00311 }
00312
00313 State getState()
00314 {
00315 ACE_Guard<ACE_Thread_Mutex> guard(m_mutex);
00316 return m_states.curr;
00317 }
00318
00319
00327 bool isIn(State state)
00328 {
00329 ACE_Guard<ACE_Thread_Mutex> guard(m_mutex);
00330 return m_states.curr == state ? true : false;
00331 }
00332
00333
00341 void goTo(State state)
00342 {
00343 ACE_Guard<ACE_Thread_Mutex> guard(m_mutex);
00344 m_states.next = state;
00345 if (m_states.curr == state)
00346 {
00347 m_selftrans = true;
00348 }
00349 }
00350
00351
00359 Result worker()
00360 {
00361 Result res;
00362 States state;
00363 bool selftrans;
00364
00365 {
00366 ACE_Guard<ACE_Thread_Mutex> guard(m_mutex);
00367 state = m_states;
00368 selftrans = m_selftrans;
00369 m_selftrans = false;
00370 }
00371
00372
00373
00374
00375 if ((state.prev != state.curr) || selftrans)
00376 {
00377
00378 if (m_entry[state.curr] != NULL)
00379 res = (m_listener->*m_entry[state.curr])(state);
00380 }
00381
00382
00383
00384
00385
00386
00387 if (state.curr == state.next)
00388 {
00389 if (m_predo[state.curr] != NULL)
00390 res = (m_listener->*m_predo [state.curr])(state);
00391 if (m_do[state.curr] != NULL)
00392 res = (m_listener->*m_do [state.curr])(state);
00393 if (m_postdo[state.curr] != NULL)
00394 res = (m_listener->*m_postdo[state.curr])(state);
00395 }
00396
00397
00398
00399
00400 {
00401 ACE_Guard<ACE_Thread_Mutex> guard(m_mutex);
00402
00403 state.next = m_states.next;
00404 selftrans = m_selftrans;
00405 }
00406
00407
00408 if ((state.curr != state.next) || selftrans)
00409 {
00410
00411 if (m_exit[state.curr] != NULL)
00412 res = (m_listener->*m_exit[state.curr])(state);
00413 if (m_transit != NULL)
00414 res = (m_listener->*m_transit)(state);
00415 }
00416
00417 {
00418 ACE_Guard<ACE_Thread_Mutex> guard(m_mutex);
00419
00420 m_states.prev = m_states.curr;
00421 m_states.curr = m_states.next;
00422 }
00423
00424 return res;
00425 }
00426
00427 protected:
00428 void setNullFunc(Callback* s, Callback nullfunc)
00429 {
00430 for (int i = 0; i < m_num; ++i) s[i] = nullfunc;
00431 }
00432
00433
00434 int m_num;
00435 Listener* m_listener;
00436 Callback* m_entry;
00437 Callback* m_predo;
00438 Callback* m_do;
00439 Callback* m_postdo;
00440 Callback* m_exit;
00441 Callback m_transit;
00442
00443 States m_states;
00444 bool m_selftrans;
00445 ACE_Thread_Mutex m_mutex;
00446 };
00447
00448 #endif // StateMachine_h