Boost logo

Boost Users :

Subject: Re: [Boost-users] [MSM] Use events twice
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2011-04-09 10:56:45


> 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




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