• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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