From: Andreas Huber (ah2003_at_[hidden])
Date: 2004-05-26 06:50:06
Johan Nilsson <johan.nilsson <at> esrange.ssc.se> writes:
> > - The sequence of destructor calls is the same as the exit sequence
> In a way, yes. But the exit for the inital inner state is unlikely to be
> immediately followed by the exit for the outer state (unless the initial
> state's also the last inner state).
Yes, that is the main difference between derived classes and inner states.
Making a transition between two inner states is the equivalent of destructing
the derived class portion of the object but leaving the base class portion
intact and then constructing a different derived class object on top of the
base class portion. This is of course not possible in C++ and presumably most
other OO languages and is probably of little use outside the FSM domain.
Apart from that there are not many more differences.
> > - Inner states sometimes define an in-state reaction for an event that an
> > outer state also has a reaction for and delegate to the outer state
> > after doing some stuff internally. Derived and base classes do exactly the
> > same through virtual functions.
> > - The LSP must hold for an outer state and all its inner states (see Miro
> > Samek's articles in CUJ last summer).
> I did read them; I'll have to re-read and get back on that. That implies
> that all inner states must implement the (event handling) interface in the
> same way as the outer state?
Yes, just like derived classes they inherit that interface anyway (one more
similarity), so an inner state that does not define any reactions behaves
exactly like its outer state. The additional reactions an inner state defines
can *refine* the outer states behavior, but it must not fundamentally change
the behavior as that would violate the LSP.
> > > Let me make an alternate suggestion: The states needing 'persistent'
> > > (or functionality, such in the admittedly convoluted TCP example above)
> > > would tell the state machine to maintain a special context object for
> them -
> > > for the entire lifetime of the FSM. This context object could be of any
> > > class -> but should _not_ be the fsm itself or an outer state.
> > Why not?
> That should read "... should _not_ _have_ to be the fsm ..."
Still, why should it not have to?
> > That is all very interesting but I still don't get why putting your
> > into such a context container is better than putting your object in outer
> > states or the state_machine subclass itself?
> "That is all very interesting" sounds like you're fed up with this
No, that's not the case (English isn't my mother tongue either so I'm not
familiar with such subtleties). It *is* genuinely interesting, because I've
never thought about this.
> ... for me it boils down to a cleaner separation of the concepts
> and looser restrictions on how 'context' is implemented; but let me put it
> this way: what's so wrong about it?
It violates the KISS principle. It introduces a facility for something that
can already be done in boost::fsm and quite nicely too. Before I'm going to
even think about such a thing I really need to see compelling real-world use
I hope you agree that simplicity in usage is a key factor in all boost
libraries. Make it as complex as necessary but no more.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk