reaction_dispatcher.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #ifndef BOOST_STATECHART_REACTION_DISPATCHER_HPP_INCLUDED
  2. #define BOOST_STATECHART_REACTION_DISPATCHER_HPP_INCLUDED
  3. //////////////////////////////////////////////////////////////////////////////
  4. // Copyright 2008 Andreas Huber Doenni
  5. // Distributed under the Boost Software License, Version 1.0. (See accompany-
  6. // ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. //////////////////////////////////////////////////////////////////////////////
  8. #include <boost/statechart/result.hpp>
  9. #include <boost/mpl/if.hpp>
  10. #include <boost/polymorphic_cast.hpp> // boost::polymorphic_downcast
  11. #include <boost/type_traits/is_same.hpp>
  12. namespace boost
  13. {
  14. namespace statechart
  15. {
  16. namespace detail
  17. {
  18. //////////////////////////////////////////////////////////////////////////////
  19. template< class Event >
  20. struct no_context
  21. {
  22. void no_function( const Event & );
  23. };
  24. //////////////////////////////////////////////////////////////////////////////
  25. template<
  26. class Reactions, class State, class EventBase, class Event,
  27. class ActionContext, class IdType >
  28. class reaction_dispatcher
  29. {
  30. private:
  31. struct without_action
  32. {
  33. static result react( State & stt, const EventBase & )
  34. {
  35. return Reactions::react_without_action( stt );
  36. }
  37. };
  38. struct base_with_action
  39. {
  40. static result react( State & stt, const EventBase & evt )
  41. {
  42. return Reactions::react_with_action( stt, evt );
  43. }
  44. };
  45. struct base
  46. {
  47. static result react(
  48. State & stt, const EventBase & evt, const IdType & )
  49. {
  50. typedef typename mpl::if_<
  51. is_same< ActionContext, detail::no_context< Event > >,
  52. without_action, base_with_action
  53. >::type reaction;
  54. return reaction::react( stt, evt );
  55. }
  56. };
  57. struct derived_with_action
  58. {
  59. static result react( State & stt, const EventBase & evt )
  60. {
  61. return Reactions::react_with_action(
  62. stt, *polymorphic_downcast< const Event * >( &evt ) );
  63. }
  64. };
  65. struct derived
  66. {
  67. static result react(
  68. State & stt, const EventBase & evt, const IdType & eventType )
  69. {
  70. if ( eventType == Event::static_type() )
  71. {
  72. typedef typename mpl::if_<
  73. is_same< ActionContext, detail::no_context< Event > >,
  74. without_action, derived_with_action
  75. >::type reaction;
  76. return reaction::react( stt, evt );
  77. }
  78. else
  79. {
  80. return detail::result_utility::make_result( detail::no_reaction );
  81. }
  82. }
  83. };
  84. public:
  85. static reaction_result react(
  86. State & stt, const EventBase & evt, const IdType & eventType )
  87. {
  88. typedef typename mpl::if_<
  89. is_same< Event, EventBase >, base, derived
  90. >::type reaction;
  91. return result_utility::get_result(
  92. reaction::react( stt, evt, eventType ) );
  93. }
  94. };
  95. } // namespace detail
  96. } // namespace statechart
  97. } // namespace boost
  98. #endif