Re: [Boost-users] [MSM] Use events twice
I'm using MSM to implement a client for a simple network application. Basically, the server sends messages and the client changes state and responds to them as appropriate.
One of these messages is THROW. THROW gets two arguments: an identifier (0-3) and a value. My client is supposed to sum up the values for consecutive THROW events with the same identifier, and on a change of identifier, store the sum somewhere and start over for the new identifier.
So I have three states (id0, id1, id2 - there's some special handling, which is why they're separate states) and an event Throw(id, value). The transitions for idN are: Throw(my id, value) -> no switch, state.sum += value Throw(other id, value) -> switch to state of other id, reprocess event, storing the sum is handled by the exit action
In other words, I want the next state to immediately handle the event as well, because there's a value there I need to store. The question is, how do I do this?
Here's a sequence of events and actions that could occur: E1: [init] Throw(0, 4) -> [id0: ?] Entry [id0: ?] -> [id0: 0] [id0: 0] reprocess E1 -> [id0: 4] E2: [id0: 4] Throw(0, 8) -> [id0: 12] E3: [id0: 12] Throw(1, 7) -> [id1: ?] Exit [id0: 12] -> save 12 Entry [id1: ?] -> [id1: 0] [id1: 0] reprocess E3 -> [id1: 7]
Hi Sebastian, Let's see if I get it. Reprocessing is not going to be the problem, I suppose. An action reprocessing an event untouched would be: struct reprocess { template <class Fsm,class Evt,class SourceState,class TargetState> void operator()(Evt const& evt,Fsm& fsm,SourceState& ,TargetState& ) { fsm.process_event(evt); } }; MSM has a message queue by default so you have no risk of deadlocking yourself. Actually you might not even need to reprocess if you use internal actions and transition conflicts, so I suggest a different version. For every Throw event, sou create a conflict between a state internal transition (not necessary but more elegant and with more reuse, see below) and an external one, leading to another state if the id contained in Throw is not the one from the current state. If it is the one from the current state, we add the value from the event. I also added an Init state to make it simpler. Now, all I need to do is make the states template classes and write just one. I attach an example. Please tell me if that's what you're looking for. Christophe
On 09.04.2011 16:56, Christophe Henry wrote:
I attach an example. Please tell me if that's what you're looking for.
Hi Christophe, I solved my problem by simply calling fsm.process_event(e) from the right entry_action functions, but your method looks more elegant. Sebastian
participants (2)
-
Christophe Henry
-
Sebastian Redl