Boost logo

Boost :

From: David Cattarin (ditto_at_[hidden])
Date: 2002-09-08 09:58:10


Beman Dawes wrote:

> At 09:48 AM 9/6/2002, David Cattarin wrote:
>
> > In my approach, I've almost entirely discarded

[snip]

> I found the above fascinating. Would it be too much to ask you to
> expand on it a bit? Particularly how the BGL is used to define a
> state machine, and what a state container looks like.

Hi Berman,

Here's a link to Andreas's original requirements for a State Machine
Framework.

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=3d3abf94%40news.swissonline.ch&rnum=1&prev=/groups%3Fq%3DAndreas%2BHuber%2Bgroup:comp.lang.c%252B%252B.moderated%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3D3d3abf94%2540news.swissonline.ch%26rnum%3D1

These are pretty good requirements, and if they lead to a useful,
generic, state machine framework, I'd be happy to use it. I think,
however, that I go over his requirements.

Item 1: Code generation. I agree with Andreas that code generation is
not a good approach. Most of these solutions provide poor support for
round-trip engineering.

Item 2: Mapping to UML state diagrams. I agree it should be easy, but I
don't think it has to be a 1:1 correspondence between diagram element
and class.

Item 3: Compile-time checking: This is really where I disagree with
Andres. I'll explain why below.

Item 4a: Complete support for UML state diagrams. I think this is just a
more strict restating of Item 2.

Item 4b: Storage for state variables: I agree with concept, but not
proposed implementation. I believe construction and destruction of state
objects during transitioning is an unnecessary performance penalty.

Item 5: State machine is fixed at compile time: I totally disagree with
this. I think it is unnessecarily restrictive and elminates a large
class of implementations. More on this below.

Item 6: Resource allocation is user's responsibility. I agree with this.

Item 7: Useful reactions to exceptions: I agree with this too.

As you can see, I agree with most of Andres's requirements. As a useful
note, requirements should not mandate a particular implementation.
Restrictions, however, are a different story. During the design of my
framework, I placed the following restrictions on my implementation: A)
dynamic_cast is verboten; B) object construction/destruction must be
minimized; C) memory footprint must be kept as small as possible. These
restrictions are all related to performance.

I can see why Andreas likes items 3 & 5. I, however, have run into
situations where such an implementation would be useless. For instance,
I currently use my state machine framework to load state machines during
runtime. Also, I don't believe that compile-time validation of the state
machine buys you much. If you've botherd to diagram you state machine
and using requirement 2, you should have a pretty good version of a
state machine. After the first few debugging episodes, then your state
machine should be nearly correct--aside from the Actions, that is, which
can't be compile-time checked anyway. Compile-time checking helps, but
it doesn't ensure anything in this case. BTW, I'm not saying that we
can't do this, I'm saying compile-time construction and checking of
state machines should not be the only way to build a state machine.

When you only have one state machine in an application, event delivery
is easy. Two different state machines only slightly complicate the
situation. With twenty different state machines, you have to use a
factory to instantiate you state machines and you need to use an event
dispatcher. For simplicity, the client should only deal with generic
objects; after all, once you have an event, all you want to do is
transition. Right? So, from the client point-of-view, it makes no
difference what kind of state machine is being used (as long as it is
the right one). If transitioning, or in other words, iterating over a
state machine is all you want to do, then the factory need only return
an iterator to the correct state machine. So, you can construct one
(stateless) state machine that all the iterators iterate over. ;)

Now, I've been taking a closer look at the BGL. It will take me some
time and experimentation to understand it. But, it looks like I can
dynamically construct state machines (which makes me happy :). States
would just be nodes that contain lists of Action functors. I still need
to figure out the iteration side of things and how guards are
incorporated into the BGL.

That's about it for now.
Thoughts?
Dave


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk