| |
| #ifndef BOOST_FSM_STATE_MACHINE_INCLUDED |
| #define BOOST_FSM_STATE_MACHINE_INCLUDED |
| |
| // Copyright Aleksey Gurtovoy 2002-2004 |
| // |
| // Distributed under the Boost Software License, Version 1.0. |
| // (See accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| // |
| // See http://www.boost.org/libs/mpl for documentation. |
| |
| // $Id: state_machine.hpp 49268 2008-10-11 06:26:17Z agurtovoy $ |
| // $Date: 2008-10-11 02:26:17 -0400 (Sat, 11 Oct 2008) $ |
| // $Revision: 49268 $ |
| |
| #include "aux_/event.hpp" |
| #include "aux_/state.hpp" |
| #include "aux_/transition.hpp" |
| #include "aux_/STT_impl_gen.hpp" |
| #include <boost/shared_ptr.hpp> |
| |
| #include <queue> |
| #include <memory> |
| #include <cassert> |
| |
| namespace fsm { |
| |
| template< typename Derived > |
| class state_machine |
| { |
| private: |
| typedef state_machine self_t; |
| typedef aux::base_event base_event_t; |
| typedef boost::shared_ptr<base_event_t const> base_event_ptr_t; |
| |
| public: |
| typedef long state_t; |
| typedef void (Derived::* invariant_func_t)() const; |
| |
| template< typename DerivedEvent > |
| struct event |
| : aux::event<DerivedEvent> |
| { |
| }; |
| |
| void process_event(base_event_t const& evt) |
| { |
| // all internal events should be handled at this point |
| assert(!m_events_queue.size()); |
| |
| // process the external event passed |
| do_transition(evt); |
| |
| // if the previous transition generated any internal events, |
| // process those |
| while (m_events_queue.size()) |
| { |
| do_transition(*m_events_queue.front()); |
| m_events_queue.pop(); |
| } |
| } |
| |
| state_t current_state() const |
| { |
| return m_state; |
| } |
| |
| protected: |
| // interface for the derived class |
| |
| state_machine(state_t const& initial_state) |
| : m_state(initial_state) |
| { |
| } |
| |
| state_machine() |
| : m_state(typename Derived::initial_state()) |
| { |
| } |
| |
| virtual ~state_machine() |
| { |
| } |
| |
| void post_event(std::auto_ptr<base_event_t const> evt) |
| { |
| m_events_queue.push(base_event_ptr_t(evt.release())); |
| } |
| |
| template< |
| long State |
| #if !defined(BOOST_INTEL_CXX_VERSION) && (!defined(__GNUC__) || __GNUC__ >= 3) |
| , invariant_func_t f = static_cast<invariant_func_t>(0) |
| #else |
| , invariant_func_t f = 0 |
| #endif |
| > |
| struct state |
| : fsm::aux::state<Derived,State,f> |
| { |
| }; |
| |
| template< |
| typename From |
| , typename Event |
| , typename To |
| , bool (Derived::* transition_func)(Event const&) |
| > |
| struct transition |
| : aux::transition< Derived,From,Event,To,transition_func > |
| { |
| }; |
| |
| private: |
| |
| void do_transition(base_event_t const& evt) |
| { |
| typedef typename Derived::transition_table STT_; |
| typedef typename aux::STT_impl_gen< STT_ >::type STT_impl_; |
| |
| m_state = STT_impl_::do_transition( |
| static_cast<Derived&>(*this) |
| , m_state |
| , evt |
| ); |
| } |
| |
| state_t m_state; |
| std::queue< base_event_ptr_t > m_events_queue; |
| }; |
| |
| } // namespace fsm |
| |
| #endif // BOOST_FSM_STATE_MACHINE_INCLUDED |