Boost logo

Boost Users :

Subject: Re: [Boost-users] [msm] euml submachine with non-default constructor
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2012-05-16 15:33:26


> Hello, having trouble getting this to work.
>
> Here’s a simplification of what I’m trying:
>
> //states and events defined elsewhere
>
> struct sub_fsm : public msm::front::state_machine_def<sub_fsm,
> state_base>
> {
> typedef entry_state_impl initial_state;
>
> BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
> entry_state + some_event() / action1
> == next_state
> ), transition_table)
>
> sub_fsm() : pctx_(nullptr) {}
> sub_fsm(context *p) : pctx_(p) {}
>
> context *pctx_;
> };
>
> typedef msm::back::state_machine<sub_fsm> sub_helper;
> struct sub_machine : public sub_helper, public
> msm::front::euml::euml_state<sub_helper>
> {
> sub_machine() {}
> sub_machine(context *p) : sub_helper(p) {}
> };
> sub_machine const sub;
>
> struct outer_fsm : public msm::front::state_machine_def<outer_fsm,
> state_base>
> {
> typedef outer_entry_state_impl initial_state;
>
> BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
> outer_entry_state + another_event() / action2 == sub
> ), transition_table)
>
> outer_fsm() : pctx_(nullptr) {}
> outer_fsm(context *p) : pctx_(p) {}
>
> context *pctx_;
> };
> typedef msm::back::state_machine<outer_fsm> outer_machine;
>
>
> int main()
> {
> context ctx;
> outer_machine fsm(msm::back::states_ << sub_machine(&ctx), &ctx);
> }
>
> This doesn’t compile under VC2010, it can’t deduce the template
> arguments for operator <<().
>
> Am I on the right track here? Should the template parameter of
> euml_state<> really be sub_helper and not sub_machine (I got that chunk
> of code from here:
> http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/examples/CompositeTutorialWithEumlTable.cpp)?
>
> What am I doing wrong?
>
> Thanks for any help,
> Mark

Hi Mark,

you're not doing anything wrong, VC has been giving me a hard time with eUML
and submachines.
I corrected this in the trunk a while ago but we had no boost version since
then, so you'll need to get the current version (the 1.50 will have this
change when it comes out).
There is a small breaking change (the first since the official release) but
the syntax is now actually better and easier, you won't need the helper
class. I attach a corrected version of your example, I tested it with VC10
and g++4.5.

HTH,
Christophe

struct context{};

struct entry_state_impl : public msm::front::state<> , public
msm::front::euml::euml_state<entry_state_impl>
{
};
entry_state_impl const entry_state;

struct next_state_impl : public msm::front::state<> , public
msm::front::euml::euml_state<next_state_impl>
{
};
next_state_impl const next_state;

struct some_event : msm::front::euml::euml_event<some_event>{};

BOOST_MSM_EUML_ACTION(action1)
{
    template <class FSM,class EVT,class SourceState,class TargetState>
    void operator()(EVT const& ,FSM& ,SourceState& ,TargetState& )
    {
    }
};

struct sub_fsm : public msm::front::state_machine_def<sub_fsm>
{
   typedef entry_state_impl initial_state;

   BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
     entry_state + some_event() / action1
      == next_state
   ), transition_table)

   sub_fsm() : pctx_(0) {}
   sub_fsm(context *p) : pctx_(p) {}

   context *pctx_;
};

typedef msm::back::state_machine<sub_fsm> sub_helper;
sub_helper const sub;

// no more needed
/*struct sub_machine : public sub_helper, public
msm::front::euml::euml_state<sub_helper>
{
   sub_machine() {}
   sub_machine(context *p) : sub_helper(p) {}
};
sub_machine const sub;
*/

struct outer_entry_state_impl : public msm::front::state<> , public
msm::front::euml::euml_state<outer_entry_state_impl>
{
};
outer_entry_state_impl const outer_entry_state;

struct another_event : msm::front::euml::euml_event<another_event>{};

BOOST_MSM_EUML_ACTION(action2)
{
    template <class FSM,class EVT,class SourceState,class TargetState>
    void operator()(EVT const& ,FSM& ,SourceState& ,TargetState& )
    {
    }
};

struct outer_fsm : public msm::front::state_machine_def<outer_fsm>
{
typedef outer_entry_state_impl initial_state;

   BOOST_MSM_EUML_DECLARE_TRANSITION_TABLE((
     outer_entry_state + another_event() / action2 == sub
   ), transition_table)

   outer_fsm() : pctx_(0) {}
   outer_fsm(context *p) : pctx_(p) {}

   context *pctx_;
};
typedef msm::back::state_machine<outer_fsm> outer_machine;

int main()
{
   context ctx;
   outer_machine fsm(msm::back::states_ << sub_helper(&ctx), &ctx);
}


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