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