functor_row.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  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_FUNCTOR_ROW_H
  11. #define BOOST_MSM_FRONT_FUNCTOR_ROW_H
  12. #include <boost/mpl/for_each.hpp>
  13. #include <boost/mpl/has_xxx.hpp>
  14. #include <boost/mpl/count_if.hpp>
  15. #include <boost/fusion/container/set.hpp>
  16. #include <boost/fusion/container/vector.hpp>
  17. #include <boost/typeof/typeof.hpp>
  18. #include <boost/msm/back/common_types.hpp>
  19. #include <boost/msm/row_tags.hpp>
  20. #include <boost/msm/common.hpp>
  21. #include <boost/msm/front/completion_event.hpp>
  22. #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
  23. BOOST_MPL_HAS_XXX_TRAIT_DEF(deferring_action)
  24. BOOST_MPL_HAS_XXX_TRAIT_DEF(some_deferring_actions)
  25. namespace boost { namespace msm { namespace front
  26. {
  27. template <class Func,class Enable=void>
  28. struct get_functor_return_value
  29. {
  30. static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_TRUE;
  31. };
  32. template <class Func>
  33. struct get_functor_return_value<Func,
  34. typename ::boost::enable_if<
  35. typename has_deferring_action<Func>::type
  36. >::type
  37. >
  38. {
  39. static const ::boost::msm::back::HandledEnum value = ::boost::msm::back::HANDLED_DEFERRED;
  40. };
  41. // for sequences
  42. template <class Func>
  43. struct get_functor_return_value<Func,
  44. typename ::boost::enable_if<
  45. typename has_some_deferring_actions<Func>::type
  46. >::type
  47. >
  48. {
  49. static const ::boost::msm::back::HandledEnum value =
  50. (Func::some_deferring_actions::value ? ::boost::msm::back::HANDLED_DEFERRED : ::boost::msm::back::HANDLED_TRUE );
  51. };
  52. template <class SOURCE,class EVENT,class TARGET,class ACTION=none,class GUARD=none>
  53. struct Row
  54. {
  55. typedef SOURCE Source;
  56. typedef EVENT Evt;
  57. typedef TARGET Target;
  58. typedef ACTION Action;
  59. typedef GUARD Guard;
  60. // action plus guard
  61. typedef row_tag row_type_tag;
  62. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  63. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  64. {
  65. // create functor, call it
  66. Action()(evt,fsm,src,tgt);
  67. return get_functor_return_value<Action>::value;
  68. }
  69. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  70. static bool guard_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt,AllStates&)
  71. {
  72. // create functor, call it
  73. return Guard()(evt,fsm,src,tgt);
  74. }
  75. };
  76. template<class SOURCE,class EVENT,class TARGET>
  77. struct Row<SOURCE,EVENT,TARGET,none,none>
  78. {
  79. typedef SOURCE Source;
  80. typedef EVENT Evt;
  81. typedef TARGET Target;
  82. typedef none Action;
  83. typedef none Guard;
  84. // no action, no guard
  85. typedef _row_tag row_type_tag;
  86. };
  87. template<class SOURCE,class EVENT,class TARGET,class ACTION>
  88. struct Row<SOURCE,EVENT,TARGET,ACTION,none>
  89. {
  90. typedef SOURCE Source;
  91. typedef EVENT Evt;
  92. typedef TARGET Target;
  93. typedef ACTION Action;
  94. typedef none Guard;
  95. // no guard
  96. typedef a_row_tag row_type_tag;
  97. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  98. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  99. {
  100. // create functor, call it
  101. Action()(evt,fsm,src,tgt);
  102. return get_functor_return_value<Action>::value;
  103. }
  104. };
  105. template<class SOURCE,class EVENT,class TARGET,class GUARD>
  106. struct Row<SOURCE,EVENT,TARGET,none,GUARD>
  107. {
  108. typedef SOURCE Source;
  109. typedef EVENT Evt;
  110. typedef TARGET Target;
  111. typedef none Action;
  112. typedef GUARD Guard;
  113. // no action
  114. typedef g_row_tag row_type_tag;
  115. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  116. static bool guard_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  117. {
  118. // create functor, call it
  119. return Guard()(evt,fsm,src,tgt);
  120. }
  121. };
  122. // internal transitions
  123. template<class SOURCE,class EVENT,class ACTION>
  124. struct Row<SOURCE,EVENT,none,ACTION,none>
  125. {
  126. typedef SOURCE Source;
  127. typedef EVENT Evt;
  128. typedef Source Target;
  129. typedef ACTION Action;
  130. typedef none Guard;
  131. // no guard
  132. typedef a_irow_tag row_type_tag;
  133. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  134. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  135. {
  136. // create functor, call it
  137. Action()(evt,fsm,src,tgt);
  138. return get_functor_return_value<Action>::value;
  139. }
  140. };
  141. template<class SOURCE,class EVENT,class GUARD>
  142. struct Row<SOURCE,EVENT,none,none,GUARD>
  143. {
  144. typedef SOURCE Source;
  145. typedef EVENT Evt;
  146. typedef Source Target;
  147. typedef none Action;
  148. typedef GUARD Guard;
  149. // no action
  150. typedef g_irow_tag row_type_tag;
  151. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  152. static bool guard_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  153. {
  154. // create functor, call it
  155. return Guard()(evt,fsm,src,tgt);
  156. }
  157. };
  158. template<class SOURCE,class EVENT,class ACTION,class GUARD>
  159. struct Row<SOURCE,EVENT,none,ACTION,GUARD>
  160. {
  161. typedef SOURCE Source;
  162. typedef EVENT Evt;
  163. typedef Source Target;
  164. typedef ACTION Action;
  165. typedef GUARD Guard;
  166. // action + guard
  167. typedef irow_tag row_type_tag;
  168. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  169. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  170. {
  171. // create functor, call it
  172. Action()(evt,fsm,src,tgt);
  173. return get_functor_return_value<Action>::value;
  174. }
  175. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  176. static bool guard_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  177. {
  178. // create functor, call it
  179. return Guard()(evt,fsm,src,tgt);
  180. }
  181. };
  182. template<class SOURCE,class EVENT>
  183. struct Row<SOURCE,EVENT,none,none,none>
  184. {
  185. typedef SOURCE Source;
  186. typedef EVENT Evt;
  187. typedef Source Target;
  188. typedef none Action;
  189. typedef none Guard;
  190. // no action, no guard
  191. typedef _irow_tag row_type_tag;
  192. };
  193. template<class TGT>
  194. struct get_row_target
  195. {
  196. typedef typename TGT::Target type;
  197. };
  198. template <class EVENT,class ACTION=none,class GUARD=none>
  199. struct Internal
  200. {
  201. typedef EVENT Evt;
  202. typedef ACTION Action;
  203. typedef GUARD Guard;
  204. // action plus guard
  205. typedef sm_i_row_tag row_type_tag;
  206. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  207. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  208. {
  209. // create functor, call it
  210. Action()(evt,fsm,src,tgt);
  211. return get_functor_return_value<Action>::value;
  212. }
  213. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  214. static bool guard_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  215. {
  216. // create functor, call it
  217. return Guard()(evt,fsm,src,tgt);
  218. }
  219. };
  220. template<class EVENT,class ACTION>
  221. struct Internal<EVENT,ACTION,none>
  222. {
  223. typedef EVENT Evt;
  224. typedef ACTION Action;
  225. typedef none Guard;
  226. // no guard
  227. typedef sm_a_i_row_tag row_type_tag;
  228. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  229. static ::boost::msm::back::HandledEnum action_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  230. {
  231. // create functor, call it
  232. Action()(evt,fsm,src,tgt);
  233. return get_functor_return_value<Action>::value;
  234. }
  235. };
  236. template<class EVENT,class GUARD>
  237. struct Internal<EVENT,none,GUARD>
  238. {
  239. typedef EVENT Evt;
  240. typedef none Action;
  241. typedef GUARD Guard;
  242. // no action
  243. typedef sm_g_i_row_tag row_type_tag;
  244. template <class EVT,class FSM,class SourceState,class TargetState,class AllStates>
  245. static bool guard_call(FSM& fsm,EVT& evt,SourceState& src,TargetState& tgt, AllStates&)
  246. {
  247. // create functor, call it
  248. return Guard()(evt,fsm,src,tgt);
  249. }
  250. };
  251. template<class EVENT>
  252. struct Internal<EVENT,none,none>
  253. {
  254. typedef EVENT Evt;
  255. typedef none Action;
  256. typedef none Guard;
  257. // no action, no guard
  258. typedef sm__i_row_tag row_type_tag;
  259. };
  260. struct event_tag{};
  261. struct action_tag{};
  262. struct state_action_tag{};
  263. struct flag_tag{};
  264. struct config_tag{};
  265. struct not_euml_tag{};
  266. template <class Sequence>
  267. struct ActionSequence_
  268. {
  269. typedef Sequence sequence;
  270. // if one functor of the sequence defers events, the complete sequence does
  271. typedef ::boost::mpl::bool_<
  272. ::boost::mpl::count_if<sequence,
  273. has_deferring_action< ::boost::mpl::placeholders::_1 >
  274. >::value != 0> some_deferring_actions;
  275. template <class Event,class FSM,class STATE >
  276. struct state_action_result
  277. {
  278. typedef void type;
  279. };
  280. template <class EVT,class FSM,class STATE>
  281. struct Call
  282. {
  283. Call(EVT& evt,FSM& fsm,STATE& state):
  284. evt_(evt),fsm_(fsm),state_(state){}
  285. template <class FCT>
  286. void operator()(::boost::msm::wrap<FCT> const& )
  287. {
  288. FCT()(evt_,fsm_,state_);
  289. }
  290. private:
  291. EVT& evt_;
  292. FSM& fsm_;
  293. STATE& state_;
  294. };
  295. template <class EVT,class FSM,class SourceState,class TargetState>
  296. struct transition_action_result
  297. {
  298. typedef void type;
  299. };
  300. template <class EVT,class FSM,class SourceState,class TargetState>
  301. struct Call2
  302. {
  303. Call2(EVT& evt,FSM& fsm,SourceState& src,TargetState& tgt):
  304. evt_(evt),fsm_(fsm),src_(src),tgt_(tgt){}
  305. template <class FCT>
  306. void operator()(::boost::msm::wrap<FCT> const& )
  307. {
  308. FCT()(evt_,fsm_,src_,tgt_);
  309. }
  310. private:
  311. EVT& evt_;
  312. FSM& fsm_;
  313. SourceState& src_;
  314. TargetState& tgt_;
  315. };
  316. typedef ::boost::fusion::set<state_action_tag,action_tag> tag_type;
  317. template <class EVT,class FSM,class STATE>
  318. void operator()(EVT& evt,FSM& fsm,STATE& state)
  319. {
  320. mpl::for_each<Sequence,boost::msm::wrap< ::boost::mpl::placeholders::_1> >
  321. (Call<EVT,FSM,STATE>(evt,fsm,state));
  322. }
  323. template <class EVT,class FSM,class SourceState,class TargetState>
  324. void operator()(EVT& evt,FSM& fsm,SourceState& src,TargetState& tgt)
  325. {
  326. mpl::for_each<Sequence,boost::msm::wrap< ::boost::mpl::placeholders::_1> >
  327. (Call2<EVT,FSM,SourceState,TargetState>(evt,fsm,src,tgt));
  328. }
  329. };
  330. // functor pre-defined for basic functionality
  331. struct Defer
  332. {
  333. // mark as deferring to avoid stack overflows in certain conditions
  334. typedef int deferring_action;
  335. template <class EVT,class FSM,class SourceState,class TargetState>
  336. void operator()(EVT& evt,FSM& fsm,SourceState& ,TargetState& ) const
  337. {
  338. fsm.defer_event(evt);
  339. }
  340. };
  341. }}}
  342. #endif //BOOST_MSM_FRONT_FUNCTOR_ROW_H