history_policies.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright 2008 Christophe Henry
  2. // henry UNDERSCORE christophe AT hotmail DOT com
  3. // This is an extended version of the state machine available in the boost::mpl library
  4. // Distributed under the same license as the original.
  5. // Copyright for the original version:
  6. // Copyright 2005 David Abrahams and Aleksey Gurtovoy. Distributed
  7. // under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_MSM_BACK_HISTORY_POLICIES_H
  11. #define BOOST_MSM_BACK_HISTORY_POLICIES_H
  12. #include <boost/mpl/contains.hpp>
  13. namespace boost { namespace msm { namespace back
  14. {
  15. // policy classes
  16. // Default: no history used
  17. template <int NumberOfRegions>
  18. class NoHistoryImpl
  19. {
  20. public:
  21. NoHistoryImpl(){}
  22. ~NoHistoryImpl(){}
  23. void set_initial_states(int* const initial_states)
  24. {
  25. for (int i=0;i<NumberOfRegions;++i)
  26. m_initialStates[i] = initial_states[i];
  27. }
  28. void history_exit(int* const )
  29. {
  30. // ignore
  31. }
  32. // returns the state where the state machine should be at start
  33. template <class Event>
  34. const int* history_entry(Event const& )
  35. {
  36. // always come back to the original state
  37. return m_initialStates;
  38. }
  39. NoHistoryImpl<NumberOfRegions>& operator=(NoHistoryImpl<NumberOfRegions> const& rhs)
  40. {
  41. for (int i=0; i<NumberOfRegions;++i)
  42. {
  43. m_initialStates[i] = rhs.m_initialStates[i];
  44. }
  45. return *this;
  46. }
  47. template<class Archive>
  48. void serialize(Archive & ar, const unsigned int)
  49. {
  50. ar & m_initialStates;
  51. }
  52. private:
  53. int m_initialStates[NumberOfRegions];
  54. };
  55. // not UML standard. Always activates history, no matter which event generated the transition
  56. template <int NumberOfRegions>
  57. class AlwaysHistoryImpl
  58. {
  59. public:
  60. AlwaysHistoryImpl(){}
  61. ~AlwaysHistoryImpl(){}
  62. void set_initial_states(int* const initial_states)
  63. {
  64. for (int i=0;i<NumberOfRegions;++i)
  65. m_initialStates[i] = initial_states[i];
  66. }
  67. void history_exit(int* const current_states)
  68. {
  69. for (int i=0;i<NumberOfRegions;++i)
  70. m_initialStates[i] = current_states[i];
  71. }
  72. // returns the state where the state machine should be at start
  73. template <class Event>
  74. const int* history_entry(Event const& )
  75. {
  76. // always load back the last active state
  77. return m_initialStates;
  78. }
  79. AlwaysHistoryImpl<NumberOfRegions>& operator=(AlwaysHistoryImpl<NumberOfRegions> const& rhs)
  80. {
  81. for (int i=0; i<NumberOfRegions;++i)
  82. {
  83. m_initialStates[i] = rhs.m_initialStates[i];
  84. }
  85. return *this;
  86. }
  87. template<class Archive>
  88. void serialize(Archive & ar, const unsigned int)
  89. {
  90. ar & m_initialStates;
  91. }
  92. private:
  93. int m_initialStates[NumberOfRegions];
  94. };
  95. // UML Shallow history. For deep history, just use this policy for all the contained state machines
  96. template <class Events,int NumberOfRegions>
  97. class ShallowHistoryImpl
  98. {
  99. public:
  100. ShallowHistoryImpl(){}
  101. ~ShallowHistoryImpl(){}
  102. void set_initial_states(int* const initial_states)
  103. {
  104. for (int i=0;i<NumberOfRegions;++i)
  105. {
  106. m_currentStates[i] = initial_states[i];
  107. m_initialStates[i] = initial_states[i];
  108. }
  109. }
  110. void history_exit(int* const current_states)
  111. {
  112. for (int i=0;i<NumberOfRegions;++i)
  113. m_currentStates[i] = current_states[i];
  114. }
  115. // returns the state where the state machine should be at start
  116. template <class Event>
  117. const int* history_entry(Event const&)
  118. {
  119. if ( ::boost::mpl::contains<Events,Event>::value)
  120. {
  121. return m_currentStates;
  122. }
  123. // not one of our events, no history
  124. return m_initialStates;
  125. }
  126. ShallowHistoryImpl<Events,NumberOfRegions>& operator=(ShallowHistoryImpl<Events,NumberOfRegions> const& rhs)
  127. {
  128. for (int i=0; i<NumberOfRegions;++i)
  129. {
  130. m_initialStates[i] = rhs.m_initialStates[i];
  131. m_currentStates[i] = rhs.m_currentStates[i];
  132. }
  133. return *this;
  134. }
  135. template<class Archive>
  136. void serialize(Archive & ar, const unsigned int)
  137. {
  138. ar & m_initialStates;
  139. ar & m_currentStates;
  140. }
  141. private:
  142. int m_initialStates[NumberOfRegions];
  143. int m_currentStates[NumberOfRegions];
  144. };
  145. struct NoHistory
  146. {
  147. typedef int history_policy;
  148. template <int NumberOfRegions>
  149. struct apply
  150. {
  151. typedef NoHistoryImpl<NumberOfRegions> type;
  152. };
  153. };
  154. struct AlwaysHistory
  155. {
  156. typedef int history_policy;
  157. template <int NumberOfRegions>
  158. struct apply
  159. {
  160. typedef AlwaysHistoryImpl<NumberOfRegions> type;
  161. };
  162. };
  163. template <class Events>
  164. struct ShallowHistory
  165. {
  166. typedef int history_policy;
  167. template <int NumberOfRegions>
  168. struct apply
  169. {
  170. typedef ShallowHistoryImpl<Events,NumberOfRegions> type;
  171. };
  172. };
  173. } } }//boost::msm::back
  174. #endif //BOOST_MSM_BACK_HISTORY_POLICIES_H