Go to the documentation of this file.00001 #ifndef _H_STATEMAP
00002 #define _H_STATEMAP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
00048 #include <iostream>
00049 #if defined(SMC_NO_EXCEPTIONS)
00050 #include <cassert>
00051 #endif // SMC_NO_EXCEPTIONS
00052 #include <cstdio>
00053 #elif defined(WIN32)
00054 #include <iostream>
00055 #include <windows.h>
00056 #if defined(SMC_NO_EXCEPTIONS)
00057 #include <cassert>
00058 #endif // SMC_NO_EXCEPTIONS
00059 #else
00060 #include <iostream.h>
00061 #if defined(SMC_NO_EXCEPTIONS)
00062 #include <assert.h>
00063 #endif // SMC_NO_EXCEPTIONS
00064 #include <stdio.h>
00065 #endif
00066 #if ! defined(SMC_NO_EXCEPTIONS)
00067 #include <stdexcept>
00068 #include <cstring>
00069 #endif
00070
00071
00072
00073 #define MAX_NAME_LEN 100
00074
00075 namespace statemap
00076 {
00077
00078
00079
00080
00081 inline char* copyString(const char *s)
00082 {
00083 char *retval = NULL;
00084
00085 if (s != NULL)
00086 {
00087 retval = new char[MAX_NAME_LEN + 1];
00088 retval[MAX_NAME_LEN] = '\0';
00089 (void) std::strncpy(retval, s, MAX_NAME_LEN);
00090 }
00091
00092 return (retval);
00093 }
00094
00095
00096
00097
00098
00099 #ifndef SMC_NO_EXCEPTIONS
00100
00101 class SmcException :
00102 public std::runtime_error
00103 {
00104
00105
00106
00107 public:
00108
00109
00110 virtual ~SmcException() throw()
00111 {};
00112
00113 protected:
00114
00115
00116 SmcException(const std::string& reason)
00117 : std::runtime_error(reason)
00118 {};
00119
00120 private:
00121
00122
00123 SmcException();
00124
00125
00126
00127
00128 public:
00129 protected:
00130 private:
00131 };
00132
00133
00134
00135 class PopOnEmptyStateStackException :
00136 public SmcException
00137 {
00138
00139
00140
00141 public:
00142
00143
00144 PopOnEmptyStateStackException()
00145 : SmcException("no state to pop from state stack")
00146 {};
00147
00148
00149 virtual ~PopOnEmptyStateStackException() throw()
00150 {};
00151
00152 protected:
00153 private:
00154
00155
00156
00157
00158 public:
00159 protected:
00160 private:
00161 };
00162
00163
00164
00165
00166
00167 class StateUndefinedException :
00168 public SmcException
00169 {
00170
00171
00172
00173 public:
00174
00175
00176 StateUndefinedException()
00177 : SmcException("transition invoked while in transition")
00178 {};
00179
00180
00181 virtual ~StateUndefinedException() throw()
00182 {};
00183
00184 protected:
00185 private:
00186
00187
00188
00189
00190 public:
00191 protected:
00192 private:
00193 };
00194
00195
00196
00197 class TransitionUndefinedException :
00198 public SmcException
00199 {
00200
00201
00202
00203 public:
00204
00205
00206 TransitionUndefinedException()
00207 : SmcException("no such transition in current state"),
00208 _state(NULL),
00209 _transition(NULL)
00210 {};
00211
00212
00213
00214 TransitionUndefinedException(const char *state,
00215 const char *transition)
00216 : SmcException("no such transition in current state"),
00217 _state(copyString(state)),
00218 _transition(copyString(transition))
00219 {};
00220
00221
00222 TransitionUndefinedException(
00223 const TransitionUndefinedException& ex)
00224 : SmcException("no such transition in current state"),
00225 _state(copyString(ex._state)),
00226 _transition(copyString(ex._transition))
00227 {};
00228
00229
00230 virtual ~TransitionUndefinedException() throw()
00231 {
00232 if (_state != NULL)
00233 {
00234 delete[] _state;
00235 _state = NULL;
00236 }
00237
00238 if (_transition != NULL)
00239 {
00240 delete[] _transition;
00241 _transition = NULL;
00242 }
00243 };
00244
00245
00246 const TransitionUndefinedException&
00247 operator=(const TransitionUndefinedException& ex)
00248 {
00249
00250 if (this != &ex)
00251 {
00252 if (_state != NULL)
00253 {
00254 delete[] _state;
00255 _state = NULL;
00256 }
00257
00258 if (_transition != NULL)
00259 {
00260 delete[] _transition;
00261 _transition = NULL;
00262 }
00263
00264 _state = copyString(ex._state);
00265 _transition = copyString(ex._transition);
00266 }
00267
00268 return (*this);
00269 };
00270
00271
00272 const char* getState() const
00273 {
00274 return(_state);
00275 };
00276
00277
00278 const char* getTransition() const
00279 {
00280 return (_transition);
00281 };
00282
00283 protected:
00284 private:
00285
00286
00287
00288
00289 public:
00290 protected:
00291 private:
00292
00293 char *_state;
00294 char *_transition;
00295 };
00296
00297
00298
00299 class IndexOutOfBoundsException :
00300 public SmcException
00301 {
00302
00303
00304
00305 public:
00306
00307
00308 IndexOutOfBoundsException()
00309 : SmcException("index out of bounds"),
00310 _index(0),
00311 _minIndex(0),
00312 _maxIndex(0)
00313 {};
00314
00315
00316
00317 IndexOutOfBoundsException(const int index,
00318 const int minIndex,
00319 const int maxIndex)
00320 : SmcException("index out of bounds"),
00321 _index(index),
00322 _minIndex(minIndex),
00323 _maxIndex(maxIndex)
00324 {};
00325
00326
00327 IndexOutOfBoundsException(
00328 const IndexOutOfBoundsException& ex)
00329 : SmcException("index out of bounds"),
00330 _index(ex._index),
00331 _minIndex(ex._minIndex),
00332 _maxIndex(ex._maxIndex)
00333 {};
00334
00335
00336 virtual ~IndexOutOfBoundsException() throw()
00337 {};
00338
00339
00340 const IndexOutOfBoundsException&
00341 operator=(const IndexOutOfBoundsException& ex)
00342 {
00343
00344 if (this != &ex)
00345 {
00346 _index = ex._index;
00347 _minIndex = ex._minIndex;
00348 _maxIndex = ex._maxIndex;
00349 }
00350
00351 return (*this);
00352 };
00353
00354
00355 int getIndex() const
00356 {
00357 return(_index);
00358 };
00359
00360
00361 int getMinIndex() const
00362 {
00363 return (_minIndex);
00364 };
00365
00366
00367 int getMaxIndex() const
00368 {
00369 return (_maxIndex);
00370 };
00371
00372 protected:
00373 private:
00374
00375
00376
00377
00378 public:
00379 protected:
00380 private:
00381
00382 int _index;
00383 int _minIndex;
00384 int _maxIndex;
00385 };
00386 #endif // !SMC_NO_EXCEPTIONS
00387
00388
00389
00390
00391
00392 class State
00393 {
00394
00395
00396
00397 public:
00398
00399 const char* getName() const
00400 {
00401 return (_name);
00402 };
00403
00404 int getId() const
00405 {
00406 return (_stateId);
00407 }
00408
00409 protected:
00410
00411 State(const char *name, int stateId)
00412 : _name(NULL),
00413 _stateId(stateId)
00414 {
00415 if (name != NULL)
00416 {
00417 _name = copyString(name);
00418 }
00419 else
00420 {
00421 _name = copyString("NAME NOT SET");
00422 }
00423 };
00424
00425 virtual ~State()
00426 {
00427 if (_name != NULL)
00428 {
00429 delete[] _name;
00430 _name = NULL;
00431 }
00432 };
00433
00434 private:
00435
00436
00437
00438 State() {};
00439 State(const State&) {};
00440
00441
00442
00443
00444 public:
00445 protected:
00446
00447
00448 char *_name;
00449
00450
00451 int _stateId;
00452
00453 private:
00454 };
00455
00456 class FSMContext
00457 {
00458
00459
00460
00461 public:
00462 protected:
00463 private:
00464
00465
00466 class StateEntry
00467 {
00468
00469
00470
00471 public:
00472 StateEntry(State *state, StateEntry *next)
00473 : _state(state),
00474 _next(next)
00475 {};
00476
00477 ~StateEntry()
00478 {
00479 _state = NULL;
00480 _next = NULL;
00481 };
00482
00483 State* getState()
00484 {
00485 return(_state);
00486 };
00487
00488 StateEntry* getNext()
00489 {
00490 return(_next);
00491 };
00492
00493 protected:
00494 private:
00495
00496
00497
00498
00499 public:
00500 protected:
00501 private:
00502 State *_state;
00503 StateEntry *_next;
00504
00505
00506
00507
00508 friend class FSMContext;
00509 };
00510
00511
00512
00513
00514 public:
00515
00516
00517 virtual ~FSMContext()
00518 {
00519 StateEntry *state;
00520
00521 if (_transition != NULL)
00522 {
00523 delete[] _transition;
00524 _transition = NULL;
00525 }
00526
00527
00528 while (_state_stack != NULL)
00529 {
00530 state = _state_stack;
00531 _state_stack = _state_stack->_next;
00532 delete state;
00533 }
00534 };
00535
00536
00537
00538 FSMContext& operator=(const FSMContext& fsm)
00539 {
00540
00541
00542 if (this != &fsm)
00543 {
00544 _state = fsm._state;
00545 }
00546
00547 return(*this);
00548 };
00549
00550
00551
00552 virtual void enterStartState()=0;
00553
00554
00555 int same(const FSMContext& fsm) const
00556 {
00557 return(this == &fsm);
00558 };
00559
00560
00561 bool getDebugFlag()
00562 {
00563 return(_debug_flag);
00564 };
00565
00566
00567
00568 void setDebugFlag(bool flag)
00569 {
00570 _debug_flag = flag;
00571 return;
00572 };
00573
00574 #ifdef SMC_USES_IOSTREAMS
00575
00576 std::ostream& getDebugStream()
00577 {
00578 return (*_debug_stream);
00579 };
00580
00581
00582 void setDebugStream(std::ostream& debug_stream)
00583 {
00584 _debug_stream = &debug_stream;
00585 return;
00586 }
00587 #endif // SMC_USES_IOSTREAMS
00588
00589
00590
00591 bool isInTransition() const
00592 {
00593 return(_state == NULL ? true : false);
00594 };
00595
00596
00597
00598 char* getTransition()
00599 {
00600 return (_transition);
00601 };
00602
00603
00604
00605 void setTransition(const char *transition)
00606 {
00607 if (_transition != NULL)
00608 {
00609 delete[] _transition;
00610 _transition = NULL;
00611 }
00612
00613 _transition = copyString(transition);
00614
00615 return;
00616 };
00617
00618
00619 void clearState()
00620 {
00621 _previous_state = _state;
00622 _state = NULL;
00623 };
00624
00625
00626
00627 State* getPreviousState()
00628 {
00629 return (_previous_state);
00630 }
00631
00632
00633 void setState(const State& state)
00634 {
00635 _state = const_cast<State *>(&state);
00636
00637 if (_debug_flag == true)
00638 {
00639 #ifdef SMC_USES_IOSTREAMS
00640 *_debug_stream << "ENTER STATE : "
00641 << _state->getName()
00642 << std::endl;
00643 #else
00644 TRACE("ENTER STATE : %s\n\r",
00645 _state->getName());
00646 #endif // SMC_USES_IOSTREAMS
00647 }
00648 };
00649
00650
00651
00652 bool isStateStackEmpty() const
00653 {
00654 return (_state_stack == NULL);
00655 }
00656
00657
00658 int getStateStackDepth() const
00659 {
00660 StateEntry *state_ptr;
00661 int retval;
00662
00663 for (state_ptr = _state_stack, retval = 0;
00664 state_ptr != NULL;
00665 state_ptr = state_ptr->getNext(), ++retval)
00666 ;
00667
00668 return (retval);
00669 }
00670
00671
00672
00673 void pushState(const State& state)
00674 {
00675 StateEntry *new_entry;
00676
00677
00678
00679 if (_state != NULL)
00680 {
00681 new_entry = new StateEntry(_state, _state_stack);
00682 _state_stack = new_entry;
00683 }
00684
00685 _state = const_cast<State *>(&state);
00686
00687 if (_debug_flag == true)
00688 {
00689 #ifdef SMC_USES_IOSTREAMS
00690 *_debug_stream << "PUSH TO STATE : "
00691 << _state->getName()
00692 << std::endl;
00693 #else
00694 TRACE("PUSH TO STATE : %s\n\r",
00695 _state->getName());
00696 #endif // SMC_USES_IOSTREAMS
00697 }
00698 };
00699
00700
00701
00702 void popState()
00703 {
00704 StateEntry *entry;
00705
00706
00707 #ifdef SMC_NO_EXCEPTIONS
00708 assert(_state_stack != NULL);
00709 #else
00710 if (_state_stack == NULL)
00711 {
00712 throw PopOnEmptyStateStackException();
00713 }
00714 #endif // SMC_NO_EXCEPTIONS
00715
00716 _state = _state_stack->getState();
00717 entry = _state_stack;
00718 _state_stack = _state_stack->getNext();
00719 delete entry;
00720
00721 if (_debug_flag == true)
00722 {
00723 #ifdef SMC_USES_IOSTREAMS
00724 *_debug_stream << "POP TO STATE : "
00725 << _state->getName()
00726 << std::endl;
00727 #else
00728 TRACE("POP TO STATE : %s\n\r",
00729 _state->getName());
00730 #endif // SMC_USES_IOSTREAMS
00731 }
00732 };
00733
00734
00735 void emptyStateStack()
00736 {
00737 StateEntry *state_ptr,
00738 *next_ptr;
00739
00740 for (state_ptr = _state_stack;
00741 state_ptr != NULL;
00742 state_ptr = next_ptr)
00743 {
00744 next_ptr = state_ptr->getNext();
00745 delete state_ptr;
00746 }
00747
00748 _state_stack = NULL;
00749 };
00750
00751 protected:
00752
00753
00754 FSMContext(const State& state)
00755 : _state(const_cast<State *>(&state)),
00756 _previous_state(NULL),
00757 _state_stack(NULL),
00758 _transition(NULL),
00759 #ifdef SMC_USES_IOSTREAMS
00760 _debug_flag(false),
00761 _debug_stream(&std::cerr)
00762 #else
00763 _debug_flag(false)
00764 #endif
00765 {};
00766
00767 private:
00768
00769
00770
00771
00772
00773
00774
00775
00776 FSMContext(const FSMContext&)
00777 {};
00778
00779
00780
00781
00782 public:
00783 protected:
00784
00785
00786 State *_state;
00787
00788
00789 State *_previous_state;
00790
00791
00792 StateEntry *_state_stack;
00793
00794
00795
00796 char *_transition;
00797
00798 private:
00799
00800
00801
00802 bool _debug_flag;
00803
00804
00805 #ifdef SMC_USES_IOSTREAMS
00806
00807
00808
00809 std::ostream *_debug_stream;
00810 #endif // SMC_USES_IOSTREAMS
00811
00812 };
00813 }
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879 #endif