Boost logo

Boost Users :

Subject: Re: [Boost-users] [MSM] how to use a compilation firewall around inner state machines
From: christophe.j.henry_at_[hidden]
Date: 2014-07-31 03:30:20


Hi Mark,

>I have a state machine implemented with MSM (eUML) that currently has 80
>transitions, there are two inner state machines.
>
>Compilation time is not great, but I have been dealing with it by
>BOOST_MSM_FAVOR_COMPILE_TIME and using parallel compilation where possible.

It's quite a hard combination for a compiler, 80 transitions, submachines
and eUML.
Maybe you could consider the functor front-end for such a case? It'll
compile much faster.

>So I would like to use a compilation firewall around the inner state
>machines.
>My plan is to implement concrete types for the inner state machines, with
>a process_event function:
>
>
> boost::msm::back::HandledEnum process_event( const boost::any & event );

Yes, it would likely work. But quite hard to maintain after you add a couple
of events. Why not divide your big fsm into several classes (as you
suggest), each with their own fsm, but with a real interface with member
names. And you should also, if you can, hide the full submachine into the
cpp:

struct InnerFsm
{

  void handleEventX();

  private:
  stuct Fsm_;
  boost::shared_ptr<Fsm_> fsm_; // definition in cpp file
};

>Then within this function test for each event type to be handled by the
>inner state machine, and forward to a regular MSM
> state machine contained within the inner concrete type. I am
>hoping that this, plus on_entry and on_exit functions is about all I need
>to do. I expect that I will be able to get this to work,
>although an example on how to put a concrete wrapper around an inner state
>machine would be great,
>and importantly a list of limitations and work arounds for this technique
>would be helpful.

I think you'd also lose the flag state for these submachines, though it's
easily implemented. And transition conflicts (if you have one on the same
event: once with the submachine as source state, one being another state in
the same outer fsm). This can be implemented by adding bool member functions
in the inner fsm, then adding an extra transition in your outer fsm for each
conflict originating from the inner fsm, with an action calling the
corresponding process_event member of the inner fsm.

>My problem is that the outer state machine transition table has rows like
>this:
>
>
> exit_pt_( inner_state, inner_state_some_pseudo_exit_state ) /
> do_some_stuff() == outer_s2,
>
> exit_pt_( inner_state, inner_state_other_pseudo_exit_state ) /
> do_other_stuff() == outer_s3,
>
>
>If inner_state becomes a concrete type, then I don't know if this can be
>handled, and if so how?
>
>My best idea so far is for the inner_state to call process_event on the
>outer state machine and rewrite the outer machine's state transition table
>thus:
>
>
> inner_state + some_synthetic_event / do_some_stuff() == outer_s2,
>
> inner_state + other_synthetic_event / do_other_stuff() == outer_s3
>The xxxx_synthetic_event's would be generated from within the inner state
>machine when it reaches one of the pseudo exit states.

If you have your own class, as shown above, you can pass from the outer to
the InnerFsm class a functor (std/boost::function) or a type_erasure for a
callback, thus hiding the event itself from the InnerFsm class.
The callback can be a simple lambda (if you move to a C++11 compiler)
[this](){this->process_event(other_synthetic_event());}

>So in summary I would like to know:
>
>
>1) Is there a documented example of putting a concrete wrapper around a
>inner state machine.

No. I will add this.

>2) What is the list of limitations of doing this. e.g. exit_pt_ not
>working.

As said, flags, transition conflicts. I don't see more at the moment.

>3) How should I deal with transitions in the outer state machine that were
>making use of exit_pt_

As said above, provide at construction of the inner fsm a callback.

>P.S. I've got to say that I think MSM is great!

thanks :)

>thanks

>- - Mark

HTH,
Christophe


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