Boost logo

Boost Users :

From: Dave (pplppp_at_[hidden])
Date: 2005-07-14 20:35:55


> Why do you think that the transition/reaction specification interface is a
> problem? The FAQ item shows that you can have a base FSM that uses a virtual
> function to delay the decision where to transit from a given state (Idle) when
> a specific event occurs (EvStart). The base FSM (PumpBase) would be compiled
> into the main exe. If you want to modify the behavior in a dll, all you need
> to do is to derive from the base FSM and inside the virtual function override
> you transit to the desired state.
> Of course, for all this to work the main exe would need to have a means of
> constructing an object of the derived class (MyPump) that was loaded from the
> dll. This is easy enough to do with a factory.

You're right, it's possible to do so. I have yet to spend more time on writing
test programs but right now I see some limitations.

Say for the PumpBase example, the designer of the main Fsm decides to allow
customization for the Idle state and Running state. In the example illustrated
in the FAQ a MyRunning state (and inner states added to it) is defined and the
MyPump Fsm derives from PumpBase to specify a state transition to the new
MyRunning state.

Suppose now I want to add some inner states for the Idle state. I can define a
new MyIdle state but I cannot make it the initial state of MyPump since Idle was
specified as a template parameter in PumpBase and MyPump derives from PumpBase.

Let's put that aside and now let's suppose there's a third state in PumpBase
Fsm: Stopped, and a state transition from Running to Stopped is triggered by
event EvStop. and the following "point of customization" is defined in PumpBase

virtual sc::result react(Running& running, const EvStop &) const;

To add inner states to Stopped I can define MyStopped and have MyPump transition
from Running to MyStopped. However in MyPump Running is replaced by MyRunning,
so I need to have my own react method to transit to MyStopped, and I'm not even
using the "point of customization" in PumpBase because it has a different
signature. Up till now it looks like I'm defining a new Fsm to replace PumpBase
rather than customizing it.

All this is fine if PumpBase has few states. Yet consider the case when 2
developers work on PumpBase, one responsible for customizing the Running state,
the other for customizing the Stopped state. The developers should be able to
work on the state machine without knowing each other. Yet as I've illustrated
above, there can only be one MyPump class and whoever writes that class has to
be aware of the MyRunning and MyStopped class and write the react functions
accordingly.

btw, I think there's a typo in the FAQ code snippet. "sc::custom_reaction<
EvStart >" should not be the third template argument for struct Idle.

> Maybe there's just a terminology misunderstanding but I don't see the benefit
> of the context object. In fact, the use of a context object here looks like a
> common antipattern, a "winnebago" object (stolen from Jeff Garland). You'll
> find more on this here (search for the first occurrence of "heuristic" and
> read what follows):
>
> http://lists.boost.org/MailArchives/boost/msg79540.php

Yes it is an antipattern if the object requires modification everytime a new
field is needed, but with a property map the new field can simply be inserted
into the map. Moreover, since a state class is destroyed after a state is
exited, any state information stored within that state is lost. Information that
needs to persist throughout the execution of the state machine has to be stored
in the state machine class, which in effect becomes the winnebago object.

thanks

Dave

p.s. thanks for showing me how to post on this list, I kept looking in the
gmane.org site for instructions...


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