mirror of
https://github.com/boostorg/mpl.git
synced 2025-10-07 21:20:59 +02:00
134 lines
3.3 KiB
C++
134 lines
3.3 KiB
C++
![]() |
//-----------------------------------------------------------------------------
|
||
|
// boost fsm/state_machine.hpp header file
|
||
|
// See http://www.boost.org for updates, documentation, and revision history.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Copyright (c) 2002
|
||
|
// Aleksey Gurtovoy
|
||
|
//
|
||
|
// Permission to use, copy, modify, distribute and sell this software
|
||
|
// and its documentation for any purpose is hereby granted without fee,
|
||
|
// provided that the above copyright notice appears in all copies and
|
||
|
// that both the copyright notice and this permission notice appear in
|
||
|
// supporting documentation. No representations are made about the
|
||
|
// suitability of this software for any purpose. It is provided "as is"
|
||
|
// without express or implied warranty.
|
||
|
|
||
|
#ifndef BOOST_FSM_STATE_MACHINE_INCLUDED
|
||
|
#define BOOST_FSM_STATE_MACHINE_INCLUDED
|
||
|
|
||
|
#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;
|
||
|
|
||
|
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
|
||
|
, void (Derived::* invariant_func)() const = 0
|
||
|
>
|
||
|
struct state
|
||
|
: fsm::aux::state<Derived,State,invariant_func>
|
||
|
{
|
||
|
};
|
||
|
|
||
|
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
|