From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2008-08-11 10:52:16
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:
>> 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.
> 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.
>> - 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)
Your approach doesn't allow to separate state-specific data from the
common data. 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.
>> 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 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?
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk