|
Boost Users : |
Subject: Re: [Boost-users] [MSM] How to access event-attributes through a"kleene"-event?
From: Deniz Bahadir (deniz.bahadir_at_[hidden])
Date: 2013-02-21 08:47:22
OK, hopefully last fix. (I still had a typo in the new member-function
"getEventNumber" when creating the events by calling macro
MY_BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES_AND_MEMBERS):
BOOST_TYPE_ERASURE_MEMBER((has_getNumber), getNumber, 0);
//type erasure event
typedef ::boost::mpl::vector<
has_getNumber<int(), const boost::type_erasure::_self>,
boost::type_erasure::relaxed_match,
boost::type_erasure::copy_constructible<>,
boost::type_erasure::typeid_<>
> any_number_event_concept;
struct any_number_event :
boost::type_erasure::any<any_number_event_concept>,
msm::front::euml::euml_event<any_number_event>
{
template <class U>
any_number_event(U const& u):
boost::type_erasure::any<any_number_event_concept> (u){}
any_number_event():
boost::type_erasure::any<any_number_event_concept> (){}
};
namespace boost { namespace msm{
template<>
struct is_kleene_event< any_number_event >
{
typedef boost::mpl::true_ type;
};
}}
// Macro which is identical to BOOST_MSM_EUML_EVENT but with
// additional parameter "members_list" which are all additional
// members surrounded by one pair of parentheses.
// The members from "members_list" will be inserted verbatim!
#define MY_BOOST_MSM_EUML_EVENT_WITH_MEMBERS(instance_name, \
members_list) \
struct instance_name ## _helper : \
msm::front::euml::euml_event<instance_name ## _helper> \
{ \
instance_name ## _helper(){} \
BOOST_PP_EXPAND members_list \
instance_name ## _helper const& operator()() const \
{return *this;} \
}; \
static instance_name ## _helper instance_name;
// Macro which is identical to
// BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES but with additional
// parameter "members_list" which are all additional members
// surrounded by one pair of parentheses.
// The members from "members_list" will be inserted verbatim!
#define \
MY_BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES_AND_MEMBERS( \
instance_name, attributes_name, members_list) \
struct instance_name ## _helper : \
msm::front::euml::euml_event<instance_name ## _helper>, \
public attributes_name \
{ \
template <class T,int checked_size> struct size_helper \
{ \
typedef typename ::boost::mpl::less_equal< \
typename ::boost::fusion::result_of::size<T>::type, \
::boost::mpl::int_<checked_size> >::type type; \
}; \
BOOST_PP_CAT(instance_name,_helper()) : \
attributes_name(){} \
typedef attributes_name::attributes_type attribute_map; \
typedef ::boost::fusion::result_of:: \
as_vector<attribute_map>::type attribute_vec; \
BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD( \
FUSION_MAX_MAP_SIZE ,1), \
MSM_EUML_EVENT_HELPER_CONSTRUCTORS, \
(instance_name,attributes_name)) \
BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD( \
FUSION_MAX_MAP_SIZE ,1), \
MSM_EUML_EVENT_INSTANCE_HELPER_ATTRIBUTE_MAP, ~) \
BOOST_PP_CAT(instance_name,_helper) operator()(){ \
return BOOST_PP_CAT(instance_name,_helper)();} \
BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD( \
FUSION_MAX_MAP_SIZE ,1), \
MSM_EUML_EVENT_INSTANCE_HELPER_OPERATOR_IMPL, \
instance_name) \
BOOST_PP_EXPAND members_list \
}; \
static instance_name ## _helper instance_name;
// Action that checks if event-number is "greater than" the
// number provided as template-argument.
template <int Val>
struct IsEventNumberGT_ : euml_action<IsEventNumberGT_<Val> >
{
using euml_action<IsEventNumberGT_<Val> >::operator=;
typedef ::boost::mpl::int_<Val> value_type;
enum {value = Val};
template <class EVT,class FSM,
class SourceState,class TargetState>
bool operator()(EVT const& evt, FSM&,
SourceState&, TargetState&)
{
return (evt.getNumber() > Val);
}
template <class Event,class FSM,class STATE>
bool operator()(Event const& evt, FSM&, STATE& )
{
return (evt.getNumber() > Val);
}
};
// Todo: Make similar actions for "greater or equal",
// "lesser than", "lesser or equal" and "equal".
// An action which returns the event's number.
BOOST_MSM_EUML_ACTION(GetEventNumber_)
{
template <class Fsm, class Evt,
class SourceState, class TargetState>
int operator()(Evt const& evt, Fsm&,
SourceState&, TargetState&)
{
return evt.getNumber();
}
};
// The attribute:
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, EventNo)
BOOST_MSM_EUML_ATTRIBUTES((attributes_ << EventNo), EventNoAttr)
// All events that contain this attribute:
MY_BOOST_MSM_EUML_EVENT_WITH_ATTRIBUTES_AND_MEMBERS(event1,
EventNoAttr,
(int getEventNumber() const {
return get_attribute(EventNo);
}) // <-- members_list
)
/* ... more events with same scheme ... */
// Creating an instance of the new "kleene"-event which has
// a "getNumber" member-function.
any_number_event number_event;
// The transitions table
BOOST_MSM_EUML_TRANSITION_TABLE((
State1 + number_event
[IsEventNumberGT_<7>()] == State2,
State1 + event1
/ (fsm_(lastEventNo) = event_(EventNo)) == State3
State2 + kleene
/ (fsm_(lastEventNo) = GetEventNumber_)) == State3
), stt)
Ciao,
Deniz
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net