history_policies.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. // this policy deletes all waiting deferred events
  48. template <class Event>
  49. bool process_deferred_events(Event const&)const
  50. {
  51. return false;
  52. }
  53. template<class Archive>
  54. void serialize(Archive & ar, const unsigned int)
  55. {
  56. ar & m_initialStates;
  57. }
  58. private:
  59. int m_initialStates[NumberOfRegions];
  60. };
  61. // not UML standard. Always activates history, no matter which event generated the transition
  62. template <int NumberOfRegions>
  63. class AlwaysHistoryImpl
  64. {
  65. public:
  66. AlwaysHistoryImpl(){}
  67. ~AlwaysHistoryImpl(){}
  68. void set_initial_states(int* const initial_states)
  69. {
  70. for (int i=0;i<NumberOfRegions;++i)
  71. m_initialStates[i] = initial_states[i];
  72. }
  73. void history_exit(int* const current_states)
  74. {
  75. for (int i=0;i<NumberOfRegions;++i)
  76. m_initialStates[i] = current_states[i];
  77. }
  78. // returns the state where the state machine should be at start
  79. template <class Event>
  80. const int* history_entry(Event const& )
  81. {
  82. // always load back the last active state
  83. return m_initialStates;
  84. }
  85. AlwaysHistoryImpl<NumberOfRegions>& operator=(AlwaysHistoryImpl<NumberOfRegions> const& rhs)
  86. {
  87. for (int i=0; i<NumberOfRegions;++i)
  88. {
  89. m_initialStates[i] = rhs.m_initialStates[i];
  90. }
  91. return *this;
  92. }
  93. // the history policy keeps all deferred events until next reentry
  94. template <class Event>
  95. bool process_deferred_events(Event const&)const
  96. {
  97. return true;
  98. }
  99. template<class Archive>
  100. void serialize(Archive & ar, const unsigned int)
  101. {
  102. ar & m_initialStates;
  103. }
  104. private:
  105. int m_initialStates[NumberOfRegions];
  106. };
  107. // UML Shallow history. For deep history, just use this policy for all the contained state machines
  108. template <class Events,int NumberOfRegions>
  109. class ShallowHistoryImpl
  110. {
  111. public:
  112. ShallowHistoryImpl(){}
  113. ~ShallowHistoryImpl(){}
  114. void set_initial_states(int* const initial_states)
  115. {
  116. for (int i=0;i<NumberOfRegions;++i)
  117. {
  118. m_currentStates[i] = initial_states[i];
  119. m_initialStates[i] = initial_states[i];
  120. }
  121. }
  122. void history_exit(int* const current_states)
  123. {
  124. for (int i=0;i<NumberOfRegions;++i)
  125. m_currentStates[i] = current_states[i];
  126. }
  127. // returns the state where the state machine should be at start
  128. template <class Event>
  129. const int* history_entry(Event const&)
  130. {
  131. if ( ::boost::mpl::contains<Events,Event>::value)
  132. {
  133. return m_currentStates;
  134. }
  135. // not one of our events, no history
  136. return m_initialStates;
  137. }
  138. ShallowHistoryImpl<Events,NumberOfRegions>& operator=(ShallowHistoryImpl<Events,NumberOfRegions> const& rhs)
  139. {
  140. for (int i=0; i<NumberOfRegions;++i)
  141. {
  142. m_initialStates[i] = rhs.m_initialStates[i];
  143. m_currentStates[i] = rhs.m_currentStates[i];
  144. }
  145. return *this;
  146. }
  147. // the history policy keeps deferred events until next reentry if coming from our history event
  148. template <class Event>
  149. bool process_deferred_events(Event const&)const
  150. {
  151. return ::boost::mpl::contains<Events,Event>::value;
  152. }
  153. template<class Archive>
  154. void serialize(Archive & ar, const unsigned int)
  155. {
  156. ar & m_initialStates;
  157. ar & m_currentStates;
  158. }
  159. private:
  160. int m_initialStates[NumberOfRegions];
  161. int m_currentStates[NumberOfRegions];
  162. };
  163. struct NoHistory
  164. {
  165. typedef int history_policy;
  166. template <int NumberOfRegions>
  167. struct apply
  168. {
  169. typedef NoHistoryImpl<NumberOfRegions> type;
  170. };
  171. };
  172. struct AlwaysHistory
  173. {
  174. typedef int history_policy;
  175. template <int NumberOfRegions>
  176. struct apply
  177. {
  178. typedef AlwaysHistoryImpl<NumberOfRegions> type;
  179. };
  180. };
  181. template <class Events>
  182. struct ShallowHistory
  183. {
  184. typedef int history_policy;
  185. template <int NumberOfRegions>
  186. struct apply
  187. {
  188. typedef ShallowHistoryImpl<Events,NumberOfRegions> type;
  189. };
  190. };
  191. } } }//boost::msm::back
  192. #endif //BOOST_MSM_BACK_HISTORY_POLICIES_H