Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2008-08-11 12:58:45


on Mon Aug 11 2008, Andrey Semashev <andrey.semashev-AT-gmail.com> wrote:

> David Abrahams wrote:
>> on Fri Aug 08 2008, Andrey Semashev <andrey.semashev-AT-gmail.com> wrote:
>>
>>> David Abrahams wrote:
>>>> on Tue Aug 05 2008, Andrey Semashev <andrey.semashev-AT-gmail.com> wrote:
>>>>
>>>>> David Abrahams wrote:
>>>>>> on Tue Aug 05 2008, Chris Knight <cknite-AT-gmail.com> wrote:
>>>>>> I don't know if you've seen the FSM examples from "C++ Template
>>>>>> Metaprogramming" or not. It would be interesting for this library's
>>>>>> documentation to explain its advantages over that approach (I can see
>>>>>> some from here already).
>>>>> No, I don't have that book.
>>>> For your perusal:
>>>>
>>>> http://www.boostpro.com/mplbook/examples/player.cpp
>>>> http://www.boostpro.com/mplbook/examples/player2.cpp
>>> Thanks for the info. I guess I'm not the first one who came up with
>>> such approach. :)
>>>
>>> My implementation has similarities to player2.cpp, however, there are
>>> significant advantages in Boost.FSM.
>>> - The library does not take addresses of user's functions, which
>>> allows to use templates and simplifies overloading.
>>
>> Huh? The member function pointers involved in our code are all
>> compile-time constants,
>
> No, they are stored into the dispatching map array and thus there is
> no benefit in passing them as template arguments.

Oh, I wasn't talking about player2.cpp. It's just a proof-of-concept to
show that you can change the dispatching logic to use O(1) lookup.

>> and thus work very well with templates (in fact,
>> they are passed as template arguments).
>
> I mean, I can make an event handler a template. Or overload it. This
> allows to process a subset of events in a similar manner. Another
> application is event layering, like this:
>
> class my_state : public fsm::state< ... >
> {
> // UI-related events processing
> // The event is received when the main window is closed
> void on_process(ui< main_wnd_closed > const& evt);
> // Other user-interface related events go here
> template< typename T >
> void on_process(ui< T > const& evt);
>
> // Network related event processing
> template< typename T >
> void on_process(net< T > const& evt);
> };
>
> The same can be done with transitions. Sure, this can also be done in
> your approach, too, but you'll have to explicitly state template
> arguments, which I find rather inconvenient.

OK.

>>> - States are not an enum values but classes that may have a common
>>> virtual base, which allows to have state-specific and shared data in
>>> the FSM. The events are processed in states.
>>
>> I'm not sure that isn't overkill. In our implementation you are free to
>> add any data you like to the FSM and use it in your transition (member)
>> functions.
>
> Your approach doesn't allow to separate state-specific data from the
> common data.

Yes, but in your approach the common data can't persist across state
transitions. Is that not a serious limitation?

> Besides, using classes for states allows to define base
> classes with default event handlers and data, which can be reused in
> more than one state.
>
>>> - Other minor things, like auto-generated state names, dynamic handler
>>> for unsupported events,
>>
>> Our design lets you make the handler static or dynamic as you please.
>
> Right, I didn't notice you could override the no_transition handler.

It's actually a replacement.

>>> thread-safety issues, etc.
>>
>> Not sure what issues you have in mind.
>
> Your implementation uses global dispatching table, which is non-POD
> and therefore is not thread-safe.

The table is constant once it's been initialized. Regardless, if you're
worried about thread safety during startup you again shouldn't look at
player2.cpp.

> The proposed library solves this and
> additionally provides a locking state machine class.
>
>>> I'd love to put a full comparison to the library documentation, but I
>>> feel this would be not... fair (for the lack of a better word) since I
>>> didn't read the book and only seen a couple of examples.
>>
>> What you're seeing is a little more than everything the book does with
>> FSMs, so I think it would be fair. More importantly, it would supply
>> people familiar with the book with a useful frame of reference. Since
>> the book's example was never meant to be more than a (very usable) toy
>> for demonstrating some principles of DSLs, I wouldn't worry about trying
>> to "be fair."
>
> Ok, then I'll add a new "Boost.FSM vs. ..." section. May I put the
> links you posted in the docs?

Sure thing.

-- 
Dave Abrahams
BoostPro Computing
http://www.boostpro.com

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