Boost logo

Boost Users :

Subject: Re: [Boost-users] [statechart] forward_event()
From: Commander Pirx (CmdPirx_at_[hidden])
Date: 2009-10-12 08:59:01


Hi,

first thanks for the fast reply. Your description was helpfull:

> It depends :-). Seriously, e.g. in your demo program, there's *no*
> guarantee that the reaction in state X is called first. Whether it is or
> it isn't depends on which innermost states is checked first for a suitable
> reaction. If X is checked first, then you get the behavior of your demo
> program. If either Y or Z is checked first then you get the behavior you
> observe in your application. Exactly which innermost state is checked
> first is *arbitrary*. More importantly, if the first checked innermost
> state does not define a reaction for the event, then its direct *outer*
> state is checked next (state A in your example prog). Hope this clears
> things up, if not please let me know.

Now I get it. This is, was I saw in the debugger. OK. It's a little messy
for me. I'm afraid that there is no way, to change this. I'm thinking about
a special reaction in these orthogonal states to route the event "sidewards"
instead of downwards. Any chance?

Second the wishlist:

>> 2. Calling the state constructor with an event. something like
>> transit<S>( event );
>
> You already can pass the event to the transit function, but the event is
> never passed to any state constructor (only to the transition action).
> This is a very popular request, but I'm afraid this will not be possible.
> The problem is that the state constructor can be called as a result of a
> number of different events. However, I plan to support a work-around
> (triggering_event, see to-do list) for the next release.

I'm curious.

>> 3. A process_event() method that acceepts an intrusive pointer. Currently
>> each event will be duplicated (clone()).
>
> No, it should only be cloned if the machine defers the event. Also, if you
> allocate your event with new and assign it to an intrusive_ptr p and then
> pass *p to process_event() then the event should not be cloned.

Good point. It never occurred to me.

>> 4. A thread safe scheduler. It's hard to use hundreds of instances of the
>> asynchronous_state_machine because each instance needs a thread. Correct
>> me if I am wrong here.
>
> ? A single fifo_scheduler can service as many asynchronous state machines
> as you like.

Yes, you're right. I was thinking about a state machine that isn't bound to
one thread. I had the strand concept from the asio library in mind. You can
post a work item (event) asynchonous but have a guarantee that execution is
serialized.

>> 5. Macros to define events, where all memebers are const. I've found that
>> it's error prone to write it by hand again and again.
>
> You mean the macro would save you from having to write const for each
> member?

Something like this:

#define DECLARE_SIMPLE_EVENT(e) \
 struct e : boost::statechart::event< e > \
 { event_tracer tracer_; \
 e() : tracer_("event."#e) {}};

// declare an event with 1 parameter
#define DECLARE_EVENT_1(e,v) \
 struct e : boost::statechart::event< e > \
 { e(v); e(const e&); \
  const v v_; \
  event_tracer tracer_; \
 };

#define DEFINE_EVENT_1(e,v) \
 e::e(v p) \
 : v_(p) \
 , tracer_("event."#e) {} \
 e::e(const e& copy) \
 : v_(copy.v_) \
 , tracer_("event.copy."#e) {}

Ignore the tracer_. This is only a helper object to trace the event
ctor/dtor. I think it's a good idea to keep all members of an event const.

Pirx!


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