/usr/include/boost/msm/back
Edit: /usr/include/boost/msm/back/state_machine.hpp (124809B)
// Copyright 2008 Christophe Henry
// henry UNDERSCORE christophe AT hotmail DOT com
// This is an extended version of the state machine available in the boost::mpl library
// Distributed under the same license as the original.
// Copyright for the original version:
// Copyright 2005 David Abrahams and Aleksey Gurtovoy. 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)
#ifndef BOOST_MSM_BACK_STATEMACHINE_H
#define BOOST_MSM_BACK_STATEMACHINE_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifndef BOOST_NO_RTTI
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
BOOST_MPL_HAS_XXX_TRAIT_DEF(accept_sig)
BOOST_MPL_HAS_XXX_TRAIT_DEF(no_automatic_create)
BOOST_MPL_HAS_XXX_TRAIT_DEF(non_forwarding_flag)
BOOST_MPL_HAS_XXX_TRAIT_DEF(direct_entry)
BOOST_MPL_HAS_XXX_TRAIT_DEF(initial_event)
BOOST_MPL_HAS_XXX_TRAIT_DEF(final_event)
BOOST_MPL_HAS_XXX_TRAIT_DEF(do_serialize)
BOOST_MPL_HAS_XXX_TRAIT_DEF(history_policy)
BOOST_MPL_HAS_XXX_TRAIT_DEF(fsm_check)
BOOST_MPL_HAS_XXX_TRAIT_DEF(compile_policy)
BOOST_MPL_HAS_XXX_TRAIT_DEF(queue_container_policy)
BOOST_MPL_HAS_XXX_TRAIT_DEF(using_declared_table)
BOOST_MPL_HAS_XXX_TRAIT_DEF(event_queue_before_deferred_queue)
#ifndef BOOST_MSM_CONSTRUCTOR_ARG_SIZE
#define BOOST_MSM_CONSTRUCTOR_ARG_SIZE 5 // default max number of arguments for constructors
#endif
namespace boost { namespace msm { namespace back
{
// event used internally for wrapping a direct entry
template
struct direct_entry_event
{
typedef int direct_entry;
typedef StateType active_state;
typedef Event contained_event;
direct_entry_event(Event const& evt):m_event(evt){}
Event const& m_event;
};
// This declares the statically-initialized dispatch_table instance.
template
const boost::msm::back::dispatch_table
dispatch_table::instance;
BOOST_PARAMETER_TEMPLATE_KEYWORD(front_end)
BOOST_PARAMETER_TEMPLATE_KEYWORD(history_policy)
BOOST_PARAMETER_TEMPLATE_KEYWORD(compile_policy)
BOOST_PARAMETER_TEMPLATE_KEYWORD(fsm_check_policy)
BOOST_PARAMETER_TEMPLATE_KEYWORD(queue_container_policy)
typedef ::boost::parameter::parameters<
::boost::parameter::required< ::boost::msm::back::tag::front_end >
, ::boost::parameter::optional<
::boost::parameter::deduced< ::boost::msm::back::tag::history_policy>, has_history_policy< ::boost::mpl::_ >
>
, ::boost::parameter::optional<
::boost::parameter::deduced< ::boost::msm::back::tag::compile_policy>, has_compile_policy< ::boost::mpl::_ >
>
, ::boost::parameter::optional<
::boost::parameter::deduced< ::boost::msm::back::tag::fsm_check_policy>, has_fsm_check< ::boost::mpl::_ >
>
, ::boost::parameter::optional<
::boost::parameter::deduced< ::boost::msm::back::tag::queue_container_policy>,
has_queue_container_policy< ::boost::mpl::_ >
>
> state_machine_signature;
// just here to disable use of proto when not needed
template
struct make_euml_terminal;
template
struct make_euml_terminal >::type>
{};
template
struct make_euml_terminal >::type>
: public proto::extends::type, T, boost::msm::state_domain>
{};
// library-containing class for state machines. Pass the actual FSM class as
// the Concrete parameter.
// A0=Derived,A1=NoHistory,A2=CompilePolicy,A3=FsmCheckPolicy >
template <
class A0
, class A1 = parameter::void_
, class A2 = parameter::void_
, class A3 = parameter::void_
, class A4 = parameter::void_
>
class state_machine : //public Derived
public ::boost::parameter::binding<
typename state_machine_signature::bind::type, ::boost::msm::back::tag::front_end
>::type
, public make_euml_terminal,
typename ::boost::parameter::binding<
typename state_machine_signature::bind::type, ::boost::msm::back::tag::front_end
>::type
>
{
public:
// Create ArgumentPack
typedef typename
state_machine_signature::bind::type
state_machine_args;
// Extract first logical parameter.
typedef typename ::boost::parameter::binding<
state_machine_args, ::boost::msm::back::tag::front_end>::type Derived;
typedef typename ::boost::parameter::binding<
state_machine_args, ::boost::msm::back::tag::history_policy, NoHistory >::type HistoryPolicy;
typedef typename ::boost::parameter::binding<
state_machine_args, ::boost::msm::back::tag::compile_policy, favor_runtime_speed >::type CompilePolicy;
typedef typename ::boost::parameter::binding<
state_machine_args, ::boost::msm::back::tag::fsm_check_policy, no_fsm_check >::type FsmCheckPolicy;
typedef typename ::boost::parameter::binding<
state_machine_args, ::boost::msm::back::tag::queue_container_policy,
queue_container_deque >::type QueueContainerPolicy;
private:
typedef boost::msm::back::state_machine<
A0,A1,A2,A3,A4> library_sm;
typedef ::boost::function<
execute_return ()> transition_fct;
typedef ::boost::function<
execute_return () > deferred_fct;
typedef typename QueueContainerPolicy::
template In<
std::pair >::type deferred_events_queue_t;
typedef typename QueueContainerPolicy::
template In::type events_queue_t;
typedef typename boost::mpl::eval_if<
typename is_active_state_switch_policy::type,
get_active_state_switch_policy,
// default
::boost::mpl::identity
>::type active_state_switching;
typedef bool (*flag_handler)(library_sm const&);
// all state machines are friend with each other to allow embedding any of them in another fsm
template friend class boost::msm::back::state_machine;
// helper to add, if needed, visitors to all states
// version without visitors
template
struct visitor_fct_helper
{
public:
visitor_fct_helper(){}
void fill_visitors(int)
{
}
template
void insert(int,FCT)
{
}
template
void execute(int,VISITOR)
{
}
};
// version with visitors
template
struct visitor_fct_helper >::type>
{
public:
visitor_fct_helper():m_state_visitors(){}
void fill_visitors(int number_of_states)
{
m_state_visitors.resize(number_of_states);
}
template
void insert(int index,FCT fct)
{
m_state_visitors[index]=fct;
}
void execute(int index)
{
m_state_visitors[index]();
}
#define MSM_VISITOR_HELPER_EXECUTE_SUB(z, n, unused) ARG ## n vis ## n
#define MSM_VISITOR_HELPER_EXECUTE(z, n, unused) \
template \
void execute(int index BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM(n, MSM_VISITOR_HELPER_EXECUTE_SUB, ~ ) ) \
{ \
m_state_visitors[index](BOOST_PP_ENUM_PARAMS(n,vis)); \
}
BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(BOOST_MSM_VISITOR_ARG_SIZE,1), MSM_VISITOR_HELPER_EXECUTE, ~)
#undef MSM_VISITOR_HELPER_EXECUTE
#undef MSM_VISITOR_HELPER_EXECUTE_SUB
private:
typedef typename StateType::accept_sig::type visitor_fct;
typedef std::vector visitors;
visitors m_state_visitors;
};
template
struct deferred_msg_queue_helper
{
void clear(){}
};
template
struct deferred_msg_queue_helper::type,int >::type>
{
public:
deferred_msg_queue_helper():m_deferred_events_queue(),m_cur_seq(0){}
void clear()
{
m_deferred_events_queue.clear();
}
deferred_events_queue_t m_deferred_events_queue;
char m_cur_seq;
};
public:
// tags
typedef int composite_tag;
// in case someone needs to know
typedef HistoryPolicy history_policy;
struct InitEvent { };
struct ExitEvent { };
// flag handling
struct Flag_AND
{
typedef std::logical_and type;
};
struct Flag_OR
{
typedef std::logical_or type;
};
typedef typename Derived::BaseAllStates BaseState;
typedef Derived ConcreteSM;
// if the front-end fsm provides an initial_event typedef, replace InitEvent by this one
typedef typename ::boost::mpl::eval_if<
typename has_initial_event::type,
get_initial_event,
::boost::mpl::identity
>::type fsm_initial_event;
// if the front-end fsm provides an exit_event typedef, replace ExitEvent by this one
typedef typename ::boost::mpl::eval_if<
typename has_final_event::type,
get_final_event,
::boost::mpl::identity
>::type fsm_final_event;
template
struct exit_pt : public ExitPoint
{
// tags
typedef ExitPoint wrapped_exit;
typedef int pseudo_exit;
typedef library_sm owner;
typedef int no_automatic_create;
typedef typename
ExitPoint::event Event;
typedef ::boost::function
forwarding_function;
// forward event to the higher-level FSM
template
void forward_event(ForwardEvent const& incomingEvent)
{
// use helper to forward or not
ForwardHelper< ::boost::is_convertible::value>::helper(incomingEvent,m_forward);
}
void set_forward_fct(::boost::function fct)
{
m_forward = fct;
}
exit_pt():m_forward(){}
// by assignments, we keep our forwarding functor unchanged as our containing SM did not change
template
exit_pt(RHS&):m_forward(){}
exit_pt& operator= (const exit_pt& )
{
return *this;
}
private:
forwarding_function m_forward;
// using partial specialization instead of enable_if because of VC8 bug
template
struct ForwardHelper
{
template
static void helper(ForwardEvent const& ,forwarding_function& )
{
// Not our event, assert
BOOST_ASSERT(false);
}
};
template
struct ForwardHelper
{
template
static void helper(ForwardEvent const& incomingEvent,forwarding_function& forward_fct)
{
// call if handler set, if not, this state is simply a terminate state
if (forward_fct)
forward_fct(incomingEvent);
}
};
};
template
struct entry_pt : public EntryPoint
{
// tags
typedef EntryPoint wrapped_entry;
typedef int pseudo_entry;
typedef library_sm owner;
typedef int no_automatic_create;
};
template
struct direct : public EntryPoint
{
// tags
typedef EntryPoint wrapped_entry;
typedef int explicit_entry_state;
typedef library_sm owner;
typedef int no_automatic_create;
};
typedef typename get_number_of_regions::type nr_regions;
// Template used to form rows in the transition table
template<
typename ROW
>
struct row_
{
//typedef typename ROW::Source T1;
typedef typename make_entry::type T1;
typedef typename make_exit::type T2;
typedef typename ROW::Evt transition_event;
// if the source is an exit pseudo state, then
// current_state_type becomes the result of get_owner
// meaning the containing SM from which the exit occurs
typedef typename ::boost::mpl::eval_if<
typename has_pseudo_exit::type,
get_owner,
::boost::mpl::identity >::type current_state_type;
// if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
// else if Target is an explicit_entry, next_state_type becomes the result of get_owner
// meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
typedef typename ::boost::mpl::eval_if<
typename ::boost::mpl::is_sequence::type,
get_fork_owner,
::boost::mpl::eval_if<
typename has_no_automatic_create::type,
get_owner,
::boost::mpl::identity >
>::type next_state_type;
// if a guard condition is here, call it to check that the event is accepted
static bool check_guard(library_sm& fsm,transition_event const& evt)
{
if ( ROW::guard_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list ) )
return true;
return false;
}
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
{
BOOST_STATIC_CONSTANT(int, current_state = (get_state_id::type::value));
BOOST_STATIC_CONSTANT(int, next_state = (get_state_id::type::value));
BOOST_ASSERT(state == (current_state));
// if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
if (has_pseudo_exit::type::value &&
!is_exit_state_active >(fsm))
{
return HANDLED_FALSE;
}
if (!check_guard(fsm,evt))
{
// guard rejected the event, we stay in the current one
return HANDLED_GUARD_REJECT;
}
fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
// the guard condition has already been checked
execute_exit
(::boost::fusion::at_key(fsm.m_substate_list),evt,fsm);
fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
// then call the action method
HandledEnum res = ROW::action_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list);
fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
// and finally the entry method of the new current state
convert_event_and_execute_entry
(::boost::fusion::at_key(fsm.m_substate_list),evt,fsm);
fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
return res;
}
};
// row having only a guard condition
template<
typename ROW
>
struct g_row_
{
//typedef typename ROW::Source T1;
typedef typename make_entry::type T1;
typedef typename make_exit::type T2;
typedef typename ROW::Evt transition_event;
// if the source is an exit pseudo state, then
// current_state_type becomes the result of get_owner
// meaning the containing SM from which the exit occurs
typedef typename ::boost::mpl::eval_if<
typename has_pseudo_exit::type,
get_owner,
::boost::mpl::identity >::type current_state_type;
// if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
// else if Target is an explicit_entry, next_state_type becomes the result of get_owner
// meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
typedef typename ::boost::mpl::eval_if<
typename ::boost::mpl::is_sequence::type,
get_fork_owner,
::boost::mpl::eval_if<
typename has_no_automatic_create::type,
get_owner,
::boost::mpl::identity >
>::type next_state_type;
// if a guard condition is defined, call it to check that the event is accepted
static bool check_guard(library_sm& fsm,transition_event const& evt)
{
if ( ROW::guard_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list ))
return true;
return false;
}
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
{
BOOST_STATIC_CONSTANT(int, current_state = (get_state_id::type::value));
BOOST_STATIC_CONSTANT(int, next_state = (get_state_id::type::value));
BOOST_ASSERT(state == (current_state));
// if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
if (has_pseudo_exit::type::value &&
!is_exit_state_active >(fsm))
{
return HANDLED_FALSE;
}
if (!check_guard(fsm,evt))
{
// guard rejected the event, we stay in the current one
return HANDLED_GUARD_REJECT;
}
fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
// the guard condition has already been checked
execute_exit
(::boost::fusion::at_key(fsm.m_substate_list),evt,fsm);
fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
// and finally the entry method of the new current state
convert_event_and_execute_entry
(::boost::fusion::at_key(fsm.m_substate_list),evt,fsm);
fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
return HANDLED_TRUE;
}
};
// row having only an action method
template<
typename ROW
>
struct a_row_
{
//typedef typename ROW::Source T1;
typedef typename make_entry::type T1;
typedef typename make_exit::type T2;
typedef typename ROW::Evt transition_event;
// if the source is an exit pseudo state, then
// current_state_type becomes the result of get_owner
// meaning the containing SM from which the exit occurs
typedef typename ::boost::mpl::eval_if<
typename has_pseudo_exit::type,
get_owner,
::boost::mpl::identity >::type current_state_type;
// if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
// else if Target is an explicit_entry, next_state_type becomes the result of get_owner
// meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
typedef typename ::boost::mpl::eval_if<
typename ::boost::mpl::is_sequence::type,
get_fork_owner,
::boost::mpl::eval_if<
typename has_no_automatic_create::type,
get_owner,
::boost::mpl::identity >
>::type next_state_type;
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
{
BOOST_STATIC_CONSTANT(int, current_state = (get_state_id::type::value));
BOOST_STATIC_CONSTANT(int, next_state = (get_state_id::type::value));
BOOST_ASSERT(state == (current_state));
// if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
if (has_pseudo_exit::type::value &&
!is_exit_state_active >(fsm))
{
return HANDLED_FALSE;
}
fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
// no need to check the guard condition
// first call the exit method of the current state
execute_exit
(::boost::fusion::at_key(fsm.m_substate_list),evt,fsm);
fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
// then call the action method
HandledEnum res = ROW::action_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list);
fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
// and finally the entry method of the new current state
convert_event_and_execute_entry
(::boost::fusion::at_key(fsm.m_substate_list),evt,fsm);
fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
return res;
}
};
// row having no guard condition or action, simply transitions
template<
typename ROW
>
struct _row_
{
//typedef typename ROW::Source T1;
typedef typename make_entry::type T1;
typedef typename make_exit::type T2;
typedef typename ROW::Evt transition_event;
// if the source is an exit pseudo state, then
// current_state_type becomes the result of get_owner
// meaning the containing SM from which the exit occurs
typedef typename ::boost::mpl::eval_if<
typename has_pseudo_exit::type,
get_owner,
::boost::mpl::identity >::type current_state_type;
// if Target is a sequence, then we have a fork and expect a sequence of explicit_entry
// else if Target is an explicit_entry, next_state_type becomes the result of get_owner
// meaning the containing SM if the row is "outside" the containing SM or else the explicit_entry state itself
typedef typename ::boost::mpl::eval_if<
typename ::boost::mpl::is_sequence::type,
get_fork_owner,
::boost::mpl::eval_if<
typename has_no_automatic_create::type,
get_owner,
::boost::mpl::identity >
>::type next_state_type;
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int region_index, int state, transition_event const& evt)
{
BOOST_STATIC_CONSTANT(int, current_state = (get_state_id::type::value));
BOOST_STATIC_CONSTANT(int, next_state = (get_state_id::type::value));
BOOST_ASSERT(state == (current_state));
// if T1 is an exit pseudo state, then take the transition only if the pseudo exit state is active
if (has_pseudo_exit::type::value &&
!is_exit_state_active >(fsm))
{
return HANDLED_FALSE;
}
fsm.m_states[region_index] = active_state_switching::after_guard(current_state,next_state);
// first call the exit method of the current state
execute_exit
(::boost::fusion::at_key(fsm.m_substate_list),evt,fsm);
fsm.m_states[region_index] = active_state_switching::after_exit(current_state,next_state);
fsm.m_states[region_index] = active_state_switching::after_action(current_state,next_state);
// and finally the entry method of the new current state
convert_event_and_execute_entry
(::boost::fusion::at_key(fsm.m_substate_list),evt,fsm);
fsm.m_states[region_index] = active_state_switching::after_entry(current_state,next_state);
return HANDLED_TRUE;
}
};
// "i" rows are rows for internal transitions
template<
typename ROW
>
struct irow_
{
typedef typename make_entry::type T1;
typedef typename make_exit::type T2;
typedef typename ROW::Evt transition_event;
typedef typename ROW::Source current_state_type;
typedef T2 next_state_type;
// if a guard condition is here, call it to check that the event is accepted
static bool check_guard(library_sm& fsm,transition_event const& evt)
{
if ( ROW::guard_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list))
return true;
return false;
}
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
{
BOOST_STATIC_CONSTANT(int, current_state = (get_state_id::type::value));
BOOST_ASSERT(state == (current_state));
if (!check_guard(fsm,evt))
{
// guard rejected the event, we stay in the current one
return HANDLED_GUARD_REJECT;
}
// call the action method
HandledEnum res = ROW::action_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list);
return res;
}
};
// row having only a guard condition
template<
typename ROW
>
struct g_irow_
{
typedef typename make_entry::type T1;
typedef typename make_exit::type T2;
typedef typename ROW::Evt transition_event;
typedef typename ROW::Source current_state_type;
typedef T2 next_state_type;
// if a guard condition is defined, call it to check that the event is accepted
static bool check_guard(library_sm& fsm,transition_event const& evt)
{
if ( ROW::guard_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list) )
return true;
return false;
}
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
{
BOOST_STATIC_CONSTANT(int, current_state = (get_state_id::type::value));
BOOST_ASSERT(state == (current_state));
if (!check_guard(fsm,evt))
{
// guard rejected the event, we stay in the current one
return HANDLED_GUARD_REJECT;
}
return HANDLED_TRUE;
}
};
// row having only an action method
template<
typename ROW
>
struct a_irow_
{
typedef typename make_entry::type T1;
typedef typename make_exit::type T2;
typedef typename ROW::Evt transition_event;
typedef typename ROW::Source current_state_type;
typedef T2 next_state_type;
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int , int state, transition_event const& evt)
{
BOOST_STATIC_CONSTANT(int, current_state = (get_state_id::type::value));
BOOST_ASSERT(state == (current_state));
// call the action method
HandledEnum res = ROW::action_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list);
return res;
}
};
// row simply ignoring the event
template<
typename ROW
>
struct _irow_
{
typedef typename make_entry::type T1;
typedef typename make_exit::type T2;
typedef typename ROW::Evt transition_event;
typedef typename ROW::Source current_state_type;
typedef T2 next_state_type;
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& , int , int state, transition_event const& )
{
BOOST_STATIC_CONSTANT(int, current_state = (get_state_id::type::value));
BOOST_ASSERT(state == (current_state));
return HANDLED_TRUE;
}
};
// transitions internal to this state machine (no substate involved)
template<
typename ROW,
typename StateType
>
struct internal_
{
typedef StateType current_state_type;
typedef StateType next_state_type;
typedef typename ROW::Evt transition_event;
// if a guard condition is here, call it to check that the event is accepted
static bool check_guard(library_sm& fsm,transition_event const& evt)
{
if ( ROW::guard_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list) )
return true;
return false;
}
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int , int , transition_event const& evt)
{
if (!check_guard(fsm,evt))
{
// guard rejected the event, we stay in the current one
return HANDLED_GUARD_REJECT;
}
// then call the action method
HandledEnum res = ROW::action_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list);
return res;
}
};
template<
typename ROW
>
struct internal_
{
typedef library_sm current_state_type;
typedef library_sm next_state_type;
typedef typename ROW::Evt transition_event;
// if a guard condition is here, call it to check that the event is accepted
static bool check_guard(library_sm& fsm,transition_event const& evt)
{
if ( ROW::guard_call(fsm,evt,
fsm,
fsm,
fsm.m_substate_list) )
return true;
return false;
}
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int , int , transition_event const& evt)
{
if (!check_guard(fsm,evt))
{
// guard rejected the event, we stay in the current one
return HANDLED_GUARD_REJECT;
}
// then call the action method
HandledEnum res = ROW::action_call(fsm,evt,
fsm,
fsm,
fsm.m_substate_list);
return res;
}
};
template<
typename ROW,
typename StateType
>
struct a_internal_
{
typedef StateType current_state_type;
typedef StateType next_state_type;
typedef typename ROW::Evt transition_event;
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
{
// then call the action method
HandledEnum res = ROW::action_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list);
return res;
}
};
template<
typename ROW
>
struct a_internal_
{
typedef library_sm current_state_type;
typedef library_sm next_state_type;
typedef typename ROW::Evt transition_event;
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
{
// then call the action method
HandledEnum res = ROW::action_call(fsm,evt,
fsm,
fsm,
fsm.m_substate_list);
return res;
}
};
template<
typename ROW,
typename StateType
>
struct g_internal_
{
typedef StateType current_state_type;
typedef StateType next_state_type;
typedef typename ROW::Evt transition_event;
// if a guard condition is here, call it to check that the event is accepted
static bool check_guard(library_sm& fsm,transition_event const& evt)
{
if ( ROW::guard_call(fsm,evt,
::boost::fusion::at_key(fsm.m_substate_list),
::boost::fusion::at_key(fsm.m_substate_list),
fsm.m_substate_list) )
return true;
return false;
}
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
{
if (!check_guard(fsm,evt))
{
// guard rejected the event, we stay in the current one
return HANDLED_GUARD_REJECT;
}
return HANDLED_TRUE;
}
};
template<
typename ROW
>
struct g_internal_
{
typedef library_sm current_state_type;
typedef library_sm next_state_type;
typedef typename ROW::Evt transition_event;
// if a guard condition is here, call it to check that the event is accepted
static bool check_guard(library_sm& fsm,transition_event const& evt)
{
if ( ROW::guard_call(fsm,evt,
fsm,
fsm,
fsm.m_substate_list) )
return true;
return false;
}
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int, int, transition_event const& evt)
{
if (!check_guard(fsm,evt))
{
// guard rejected the event, we stay in the current one
return HANDLED_GUARD_REJECT;
}
return HANDLED_TRUE;
}
};
template<
typename ROW,
typename StateType
>
struct _internal_
{
typedef StateType current_state_type;
typedef StateType next_state_type;
typedef typename ROW::Evt transition_event;
static HandledEnum execute(library_sm& , int , int , transition_event const& )
{
return HANDLED_TRUE;
}
};
template<
typename ROW
>
struct _internal_
{
typedef library_sm current_state_type;
typedef library_sm next_state_type;
typedef typename ROW::Evt transition_event;
static HandledEnum execute(library_sm& , int , int , transition_event const& )
{
return HANDLED_TRUE;
}
};
// Template used to form forwarding rows in the transition table for every row of a composite SM
template<
typename T1
, class Evt
>
struct frow
{
typedef T1 current_state_type;
typedef T1 next_state_type;
typedef Evt transition_event;
// tag to find out if a row is a forwarding row
typedef int is_frow;
// Take the transition action and return the next state.
static HandledEnum execute(library_sm& fsm, int region_index, int , transition_event const& evt)
{
// false as second parameter because this event is forwarded from outer fsm
execute_return res =
(::boost::fusion::at_key(fsm.m_substate_list)).process_event_internal(evt);
fsm.m_states[region_index]=get_state_id::type::value;
return res;
}
// helper metafunctions used by dispatch table and give the frow a new event
// (used to avoid double entries in a table because of base events)
template
struct replace_event
{
typedef frow type;
};
};
template
struct create_backend_stt
{
};
template
struct create_backend_stt
{
typedef g_row_ type;
};
template
struct create_backend_stt
{
typedef a_row_ type;
};
template
struct create_backend_stt<_row_tag,Transition,StateType>
{
typedef _row_ type;
};
template
struct create_backend_stt
{
typedef row_ type;
};
// internal transitions
template
struct create_backend_stt
{
typedef g_irow_ type;
};
template
struct create_backend_stt
{
typedef a_irow_ type;
};
template
struct create_backend_stt
{
typedef irow_ type;
};
template
struct create_backend_stt<_irow_tag,Transition,StateType>
{
typedef _irow_ type;
};
template
struct create_backend_stt
{
typedef a_internal_ type;
};
template
struct create_backend_stt
{
typedef g_internal_ type;
};
template
struct create_backend_stt
{
typedef internal_ type;
};
template
struct create_backend_stt
{
typedef _internal_ type;
};
template
struct make_row_tag
{
typedef typename create_backend_stt::type type;
};
// add to the stt the initial states which could be missing (if not being involved in a transition)
template
struct create_real_stt
{
//typedef typename BaseType::transition_table stt_simulated;
typedef typename ::boost::mpl::fold<
stt_simulated,mpl::vector0<>,
::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
make_row_tag< ::boost::mpl::placeholders::_2 , BaseType > >
>::type type;
};
template
struct add_forwarding_row_helper
{
typedef typename generate_event_set::type all_events;
typedef typename ::boost::mpl::fold<
all_events, Intermediate,
::boost::mpl::push_back< ::boost::mpl::placeholders::_1,
frow