Boost logo

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