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