|
Boost : |
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
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk