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 | // $Source: /cvsroot/boost/boost/libs/mpl/example/fsm/state_machine.hpp,v $ |
---|
14 | // $Date: 2004/09/02 15:41:29 $ |
---|
15 | // $Revision: 1.5 $ |
---|
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 | |
---|
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 | |
---|
64 | state_t current_state() const |
---|
65 | { |
---|
66 | return m_state; |
---|
67 | } |
---|
68 | |
---|
69 | protected: |
---|
70 | // interface for the derived class |
---|
71 | |
---|
72 | state_machine(state_t const& initial_state) |
---|
73 | : m_state(initial_state) |
---|
74 | { |
---|
75 | } |
---|
76 | |
---|
77 | state_machine() |
---|
78 | : m_state(typename Derived::initial_state()) |
---|
79 | { |
---|
80 | } |
---|
81 | |
---|
82 | virtual ~state_machine() |
---|
83 | { |
---|
84 | } |
---|
85 | |
---|
86 | void post_event(std::auto_ptr<base_event_t const> evt) |
---|
87 | { |
---|
88 | m_events_queue.push(base_event_ptr_t(evt.release())); |
---|
89 | } |
---|
90 | |
---|
91 | template< |
---|
92 | long State |
---|
93 | #if !defined(BOOST_INTEL_CXX_VERSION) && (!defined(__GNUC__) || __GNUC__ >= 3) |
---|
94 | , invariant_func_t f = static_cast<invariant_func_t>(0) |
---|
95 | #else |
---|
96 | , invariant_func_t f = 0 |
---|
97 | #endif |
---|
98 | > |
---|
99 | struct state |
---|
100 | : fsm::aux::state<Derived,State,f> |
---|
101 | { |
---|
102 | }; |
---|
103 | |
---|
104 | template< |
---|
105 | typename From |
---|
106 | , typename Event |
---|
107 | , typename To |
---|
108 | , bool (Derived::* transition_func)(Event const&) |
---|
109 | > |
---|
110 | struct transition |
---|
111 | : aux::transition< Derived,From,Event,To,transition_func > |
---|
112 | { |
---|
113 | }; |
---|
114 | |
---|
115 | private: |
---|
116 | |
---|
117 | void do_transition(base_event_t const& evt) |
---|
118 | { |
---|
119 | typedef typename Derived::transition_table STT_; |
---|
120 | typedef typename aux::STT_impl_gen< STT_ >::type STT_impl_; |
---|
121 | |
---|
122 | m_state = STT_impl_::do_transition( |
---|
123 | static_cast<Derived&>(*this) |
---|
124 | , m_state |
---|
125 | , evt |
---|
126 | ); |
---|
127 | } |
---|
128 | |
---|
129 | state_t m_state; |
---|
130 | std::queue< base_event_ptr_t > m_events_queue; |
---|
131 | }; |
---|
132 | |
---|
133 | } // namespace fsm |
---|
134 | |
---|
135 | #endif // BOOST_FSM_STATE_MACHINE_INCLUDED |
---|