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