returning values in Boost.StateChart
I'm using statechart for a project and I'm trying to do the following without success. I want to get a new event for the statechart when an event is processed. I mean, call process_event with an event and get another event as a result. We tried with different approaches. For example, modifying the passed event (but it's const) and trying to do a custom reaction that returns something (but I had problems too.. don't remember exactly now). The solution for now was to call an interface that it is implemented in all the states.. so I have to do two calls, one for process_event and other for this interface that returns the new event.... and the question is... Is there a better way to do this? Thanks!
Federico J. Fernández wrote:
I'm using statechart for a project and I'm trying to do the following without success.
I want to get a new event for the statechart when an event is processed. I mean, call process_event with an event and get another event as a result.
Ok, what will happen with this event? Should it be processed by the same state machine object or a different one? I guess a different one, correct? (If its the same FSM object then you should call post_event from an action).
We tried with different approaches. For example, modifying the passed event (but it's const) and trying to do a custom reaction that returns something (but I had problems too.. don't remember exactly now).
The easiest way to get back a result from a state_machine is to add a boost::function object as a member of the event: 1. Add either an in_state_reaction or a transition with a transition action to your state_machine. The triggering event should contain a boost::function object as member. The action should call this object. 2. Construct the event and set the boost::function member to a suitable callback function. In your case that function would accept an event parameter. 3. Call process_event, passing the event object. 4. Your callback function is called. This is the easiest way to do it but also the most dangerous, please see "Why asynchronous state machines are necessary": http://www.boost-consulting.com/boost/libs/statechart/doc/tutorial.html#Asyn... IOW, you might want to use an asynchronous state machine instead of your synchronous one.
and the question is... Is there a better way to do this?
Yes, see above. Hope that makes sense... Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.
Ok, what will happen with this event? Should it be processed by the same state machine object or a different one? I guess a different one, correct? (If its the same FSM object then you should call post_event from an action).
In this particular case using the same event for both places is only to simplify the approach. To be concrete, this returned event will be used not for another FSM but for pushing it in an event queue... maybe there is a way to implement this event queue with FSMs but this is the current approach.. the idea of the event queue is to communicate different threads of a multithreaded program (related to communications).
We tried with different approaches. For example, modifying the passed event (but it's const) and trying to do a custom reaction that returns something (but I had problems too.. don't remember exactly now).
The easiest way to get back a result from a state_machine is to add a boost::function object as a member of the event:
1. Add either an in_state_reaction or a transition with a transition action to your state_machine. The triggering event should contain a boost::function object as member. The action should call this object. 2. Construct the event and set the boost::function member to a suitable callback function. In your case that function would accept an event parameter. 3. Call process_event, passing the event object. 4. Your callback function is called.
Sounds good.
This is the easiest way to do it but also the most dangerous, please see "Why asynchronous state machines are necessary":
http://www.boost-consulting.com/boost/libs/statechart/doc/tutorial.html#Asyn...
IOW, you might want to use an asynchronous state machine instead of your synchronous one.
I am not sure about that. I evaluated using that kind of FSM but as the other use of the state is not in a FSM (and is something simpler that not synchronizes) maybe this is enough. I recall, using the event in another place is only to reuse the struct, no more than that. Thanks!
participants (3)
-
Andreas Huber
-
Federico J. Fernández
-
Federico J. Fernández