state_machine.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #ifndef BOOST_FSM_STATE_MACHINE_INCLUDED
  2. #define BOOST_FSM_STATE_MACHINE_INCLUDED
  3. // Copyright Aleksey Gurtovoy 2002-2004
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/mpl for documentation.
  10. // $Id$
  11. // $Date$
  12. // $Revision$
  13. #include "aux_/event.hpp"
  14. #include "aux_/state.hpp"
  15. #include "aux_/transition.hpp"
  16. #include "aux_/STT_impl_gen.hpp"
  17. #include <boost/shared_ptr.hpp>
  18. #include <queue>
  19. #include <memory>
  20. #include <cassert>
  21. namespace fsm {
  22. template< typename Derived >
  23. class state_machine
  24. {
  25. private:
  26. typedef state_machine self_t;
  27. typedef aux::base_event base_event_t;
  28. typedef boost::shared_ptr<base_event_t const> base_event_ptr_t;
  29. public:
  30. typedef long state_t;
  31. typedef void (Derived::* invariant_func_t)() const;
  32. template< typename DerivedEvent >
  33. struct event
  34. : aux::event<DerivedEvent>
  35. {
  36. };
  37. void process_event(base_event_t const& evt)
  38. {
  39. // all internal events should be handled at this point
  40. assert(!m_events_queue.size());
  41. // process the external event passed
  42. do_transition(evt);
  43. // if the previous transition generated any internal events,
  44. // process those
  45. while (m_events_queue.size())
  46. {
  47. do_transition(*m_events_queue.front());
  48. m_events_queue.pop();
  49. }
  50. }
  51. state_t current_state() const
  52. {
  53. return m_state;
  54. }
  55. protected:
  56. // interface for the derived class
  57. state_machine(state_t const& initial_state)
  58. : m_state(initial_state)
  59. {
  60. }
  61. state_machine()
  62. : m_state(typename Derived::initial_state())
  63. {
  64. }
  65. virtual ~state_machine()
  66. {
  67. }
  68. #if defined(BOOST_NO_CXX11_SMART_PTR)
  69. void post_event(std::auto_ptr<base_event_t const> evt)
  70. #else
  71. void post_event(std::unique_ptr<base_event_t const> evt)
  72. #endif
  73. {
  74. m_events_queue.push(base_event_ptr_t(evt.release()));
  75. }
  76. template<
  77. long State
  78. #if !defined(BOOST_INTEL_CXX_VERSION) && (!defined(__GNUC__) || __GNUC__ >= 3)
  79. , invariant_func_t f = static_cast<invariant_func_t>(0)
  80. #else
  81. , invariant_func_t f = 0
  82. #endif
  83. >
  84. struct state
  85. : fsm::aux::state<Derived,State,f>
  86. {
  87. };
  88. template<
  89. typename From
  90. , typename Event
  91. , typename To
  92. , bool (Derived::* transition_func)(Event const&)
  93. >
  94. struct transition
  95. : aux::transition< Derived,From,Event,To,transition_func >
  96. {
  97. };
  98. private:
  99. void do_transition(base_event_t const& evt)
  100. {
  101. typedef typename Derived::transition_table STT_;
  102. typedef typename aux::STT_impl_gen< STT_ >::type STT_impl_;
  103. m_state = STT_impl_::do_transition(
  104. static_cast<Derived&>(*this)
  105. , m_state
  106. , evt
  107. );
  108. }
  109. state_t m_state;
  110. std::queue< base_event_ptr_t > m_events_queue;
  111. };
  112. } // namespace fsm
  113. #endif // BOOST_FSM_STATE_MACHINE_INCLUDED