mpl/example/fsm/state_machine.hpp

146 lines
3.1 KiB
C++

#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$
// $Date$
// $Revision$
#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()
{
}
#if defined(BOOST_NO_CXX11_SMART_PTR)
void post_event(std::auto_ptr<base_event_t const> evt)
#else
void post_event(std::unique_ptr<base_event_t const> evt)
#endif
{
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