From: Andreas Huber (spam2002_at_[hidden])
Date: 2002-09-09 13:20:27


Dave,

> > I tried to make the approaches coexist as Aleksey pointed out, but I
have
> > yet to find a clean way to do this while supporting guards, hierarchical
> > states and concurrent states.
> >
>
>
> You might look to the Spirit Parser Framework (http://spirit.sf.net) for
> inspiration. The rules-vs-subrules distinction allows one to express
> parsers that use both runtime and compile-time dispatching. Sounds like a
> similar problem.

I haven't had a look at Spirit because I think the following argumentation
is independent of implementation techniques. I agree that the current
approach spreads the state machine logic more than necessary. However,
partitioning the state code into .hpp and .cpp files and introducing a new
base class boost::fsm::transition clears things up considerably:

// file LockImpl.hpp, shows the states of our Lock state machine

class Open;
class Locked : public boost::fsm::state< Locked, Lock >,
               public boost::fsm::transition< Locked, Lock::EvUnlock, Open >
{
  public:
    Locked( context_ptr_type pContext ) : base_type( pContext ) {}
};

class Open : public boost::fsm::state< Open, Lock >,
                public boost::fsm::transition< Open, Lock::EvLock, Locked >
{
  public:
    Open( context_ptr_type pContext ) : base_type( pContext ) {}
};

Please note that class boost::fsm::transition which is used whenever an
_unguarded_ transition should be made when a particular event is received.
All the information about a state is still concentrated in the state class
itself (entry- and exit-actions, outgoing unguarded transitions, guarded
transitions, initial inner state (if any)). Moreover, state constructors are
only required because this allowed for a particularly easy implementation. A
submission candidate would no longer mandate these which allows for a more
compact listing, especially if the states are mostly trivial (no entry- and
exit-actions).

Agreed, a table based approach (where each non-innermost state contains a
table) is even more compact but it has a disadvantage, which I think can not
be justified by the gain in "compactness": Outgoing transitions are listed
in the outer states' transition table while entry and exit actions must be
looked up in the state class itself.

Thoughts?

Regards,

Andreas