state_machine_def.hpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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_FRONT_STATEMACHINE_DEF_H
  11. #define BOOST_MSM_FRONT_STATEMACHINE_DEF_H
  12. #include <exception>
  13. #include <boost/assert.hpp>
  14. #include <boost/fusion/include/vector.hpp>
  15. #include <boost/mpl/vector.hpp>
  16. #include <boost/msm/row_tags.hpp>
  17. #include <boost/msm/back/common_types.hpp>
  18. #include <boost/msm/front/states.hpp>
  19. #include <boost/msm/front/completion_event.hpp>
  20. #include <boost/msm/front/common_states.hpp>
  21. #include <boost/msm/front/history_policies.hpp>
  22. namespace boost { namespace msm { namespace front
  23. {
  24. template<class Derived,class BaseState = default_base_state>
  25. struct state_machine_def : public boost::msm::front::detail::state_base<BaseState>
  26. {
  27. // tags
  28. struct internal
  29. {
  30. typedef detail::composite_state_tag tag;
  31. };
  32. // default: no flag
  33. typedef ::boost::fusion::vector0<> flag_list;
  34. typedef ::boost::fusion::vector0<> internal_flag_list;
  35. //default: no deferred events
  36. typedef ::boost::fusion::vector0<> deferred_events;
  37. // customization (message queue, exceptions)
  38. typedef ::boost::fusion::vector0<> configuration;
  39. // history policy (required in the front-end for backmp11)
  40. typedef no_history history;
  41. typedef BaseState BaseAllStates;
  42. template<
  43. typename T1
  44. , class Event
  45. , typename T2
  46. , void (Derived::*action)(Event const&)
  47. >
  48. struct a_row
  49. {
  50. typedef a_row_tag row_type_tag;
  51. typedef T1 Source;
  52. typedef T2 Target;
  53. typedef Event Evt;
  54. template <class FSM,class SourceState,class TargetState,class AllStates>
  55. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&, AllStates&)
  56. {
  57. // in this front-end, we don't need to know source and target states
  58. (fsm.*action)(evt);
  59. return ::boost::msm::back::HANDLED_TRUE;
  60. }
  61. };
  62. template<
  63. typename T1
  64. , class Event
  65. , typename T2
  66. >
  67. struct _row
  68. {
  69. typedef _row_tag row_type_tag;
  70. typedef T1 Source;
  71. typedef T2 Target;
  72. typedef Event Evt;
  73. };
  74. template<
  75. typename T1
  76. , class Event
  77. , typename T2
  78. , void (Derived::*action)(Event const&)
  79. , bool (Derived::*guard)(Event const&)
  80. >
  81. struct row
  82. {
  83. typedef row_tag row_type_tag;
  84. typedef T1 Source;
  85. typedef T2 Target;
  86. typedef Event Evt;
  87. template <class FSM,class SourceState,class TargetState, class AllStates>
  88. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
  89. {
  90. // in this front-end, we don't need to know source and target states
  91. (fsm.*action)(evt);
  92. return ::boost::msm::back::HANDLED_TRUE;
  93. }
  94. template <class FSM,class SourceState,class TargetState,class AllStates>
  95. static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
  96. {
  97. // in this front-end, we don't need to know source and target states
  98. return (fsm.*guard)(evt);
  99. }
  100. };
  101. template<
  102. typename T1
  103. , class Event
  104. , typename T2
  105. , bool (Derived::*guard)(Event const&)
  106. >
  107. struct g_row
  108. {
  109. typedef g_row_tag row_type_tag;
  110. typedef T1 Source;
  111. typedef T2 Target;
  112. typedef Event Evt;
  113. template <class FSM,class SourceState,class TargetState,class AllStates>
  114. static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
  115. {
  116. // in this front-end, we don't need to know source and target states
  117. return (fsm.*guard)(evt);
  118. }
  119. };
  120. // internal transitions
  121. template<
  122. typename T1
  123. , class Event
  124. , void (Derived::*action)(Event const&)
  125. >
  126. struct a_irow
  127. {
  128. typedef a_irow_tag row_type_tag;
  129. typedef T1 Source;
  130. typedef T1 Target;
  131. typedef Event Evt;
  132. template <class FSM,class SourceState,class TargetState,class AllStates>
  133. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
  134. {
  135. // in this front-end, we don't need to know source and target states
  136. (fsm.*action)(evt);
  137. return ::boost::msm::back::HANDLED_TRUE;
  138. }
  139. };
  140. template<
  141. typename T1
  142. , class Event
  143. , void (Derived::*action)(Event const&)
  144. , bool (Derived::*guard)(Event const&)
  145. >
  146. struct irow
  147. {
  148. typedef irow_tag row_type_tag;
  149. typedef T1 Source;
  150. typedef T1 Target;
  151. typedef Event Evt;
  152. template <class FSM,class SourceState,class TargetState,class AllStates>
  153. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
  154. {
  155. // in this front-end, we don't need to know source and target states
  156. (fsm.*action)(evt);
  157. return ::boost::msm::back::HANDLED_TRUE;
  158. }
  159. template <class FSM,class SourceState,class TargetState,class AllStates>
  160. static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
  161. {
  162. // in this front-end, we don't need to know source and target states
  163. return (fsm.*guard)(evt);
  164. }
  165. };
  166. template<
  167. typename T1
  168. , class Event
  169. , bool (Derived::*guard)(Event const&)
  170. >
  171. struct g_irow
  172. {
  173. typedef g_irow_tag row_type_tag;
  174. typedef T1 Source;
  175. typedef T1 Target;
  176. typedef Event Evt;
  177. template <class FSM,class SourceState,class TargetState,class AllStates>
  178. static bool guard_call(FSM& fsm,Event const& evt,SourceState&,TargetState&,AllStates&)
  179. {
  180. // in this front-end, we don't need to know source and target states
  181. return (fsm.*guard)(evt);
  182. }
  183. };
  184. // internal row withou action or guard. Does nothing except forcing the event to be ignored.
  185. template<
  186. typename T1
  187. , class Event
  188. >
  189. struct _irow
  190. {
  191. typedef _irow_tag row_type_tag;
  192. typedef T1 Source;
  193. typedef T1 Target;
  194. typedef Event Evt;
  195. };
  196. protected:
  197. // Default no-transition handler. Can be replaced in the Derived SM class.
  198. template <class FSM,class Event>
  199. void no_transition(Event const& ,FSM&, int )
  200. {
  201. BOOST_ASSERT(false);
  202. }
  203. // default exception handler. Can be replaced in the Derived SM class.
  204. template <class FSM,class Event>
  205. void exception_caught (Event const&,FSM&,std::exception& )
  206. {
  207. BOOST_ASSERT(false);
  208. }
  209. };
  210. } } }// boost::msm::front
  211. #endif //BOOST_MSM_FRONT_STATEMACHINE_DEF_H