Boost logo

Boost :

From: Johan Nilsson (johan.nilsson_at_[hidden])
Date: 2004-05-26 05:56:08

"Andreas Huber" <ah2003_at_[hidden]> wrote in message
> Johan Nilsson <johan.nilsson <at>> writes:
> > > I guess we agree that you have to modify some code somewhere to
> > this
> > > behavior change. What's so bad about changing the code of the state
> > the
> > > new transition originates? I think this is superior to having a global
> > > transition table. Such a global table inevitably becomes a change
> > in
> > > large FSMs and leads to frequent recompilations.
> > >
> >
> > Are we convinced that the only thing we're discussing now is static
FSMs? If
> > so, you are correct and I believe you've made a correct design decision
> > this particular respect.
> Yes, I am ;-). Seriously, I hope I have convinced you that we need two
> libraries: One for static FSMs and one for dynamic FSMs. I don't have
> domain-knowledge to implement a dynamic FSM, so I can't really discuss
> with you without making assumptions that might well be false.

To be honest, when it comes to details I probably haven't either.

> > > Ok, but I still don't understand your question/suggestion/proposal.
> > you
> > > please expand?
> >
> > It's neither; we're comparing apples and pears (well, that might be a
> > swedish idiom only .
> >
> > If a static FSM would have complete control over all transitions,
> > to the dynamic example I provided below, the static FSM would need to
> > all inner states. If a dynamic FSM would have complete control over all
> > transition it doesn't need to know the exact type of all inner states.
Am I
> > correct?
> Yes, I believe that is correct.
> [snip]
> > > > I just meant that the state is dependent on its "container" to
> > > > non-volatile data.
> > >
> > > Yes, what's so bad about that? An inner state always depends on the
> > behavior
> > > implemented by its outer state. Just like a derived class always
> > on
> > > the implementation of its base class.
> >
> > For me, an inner state "is-not-a" outer state (regardless of the name
> > 'superstate' in the UML docs).
> Well, I think you have the wrong model of inner and outer states then.

Actually, it's more of a gut feeling.

> The
> correspondence between subclasses and inner states is really quite
> - The sequence of base and derived class constructor calls is the same as
> outer and inner state entry sequence

For the inital inner state, yes.

> - 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).

> - 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?

> > The outer state <-> inner state relation
> > feels more analogous to an association (or perhaps an aggregation). So
> > comparison to base and derived feels a bit out of hand. That's why I
> > like the dependency on the "container". Two way associations generally
> > with them too much coupling, IMHO.
> The only sort of two-way association exists between an outer state and its
> inner *initial* state. Even there it is not exactly two-way because the
> initial state is an incomplete type when the outer state is defined.
> The outer state does not have any knowledge of any of its other inner
> > 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 ..."

> > The context
> > object could inherit from a specific base just so that the fsm could
> > them conveniently. The type of the context object could be specified as
> > template parameter to the e.g. simple_state<> template. I'll try to
> > an example, just to give you an idea (I won't consider the exact steps
> > needed to actually implement this):
> >
> > namespace fsm { struct no_context : fsm::context<no_context>{}; }
> >
> > struct my_state_context : public fsm::context<my_state_context, ...>
> > {
> > };
> >
> > struct my_state
> > : public fsm::simple_state<
> > my_state, ...,
> > my_state_context /* defaults to fsm::no_context */
> > >
> > {
> > };
> >
> > Access to the context should be made easy by providing the 'context()'
> > method in simple state, now returning a reference to the FSMs only
> > of the context -> implemented in simple_state. The 'context' method
> > be unavailable if the context template argument equals no_context;
> > doable through PTS.
> >
> > What would also be needed is the ability for several (closely related)
> > states to share the same context, but _still_ without the need for the
> > context to be the outer state or fsm - needs some consideration on how
> > implement this.
> 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
discussion ... 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?

> > As you see I really haven't concrete examples on how to implement this -
> > given this or similar implementation I could leave out the requirements
> > the actual state objects to remain live for the lifetime of the FSM
> > Now I could even make the context object an "active" object (i.e. run by
> > private thread).
> As I have already pointed out: I don't see why this should not be possible
> with boost::fsm as it is now. If your really need that thread to outlive
> your states then make the thread object a member of the state_machine

True. Same as above holds here.

> > We'd still have the benefits of your basic FSM design; we'd have looser
> > coupling between outer, inner states and the FSM.
> No, we wouldn't. Inner states will always need to directly know their
> states, there's no way around that (e.g. see the StopWatch example, where
> inner state accesses its outer state).

Got me there.

// Johan

Boost list run by bdawes at, gregod at, cpdaniel at, john at