Subject: Re: [boost] [MSM] Interrupt anonymous transitions or blocking process_events?
From: anlmat (anlmat_at_[hidden])
Date: 2011-04-19 16:27:15
Thank you for the helpful reply!
>> Perhaps I am going about this the wrong here and please tell me if it
>> can be done in some other much better way! I want to be able to have
>> automatic transitions that I can interrupt.
> You have to use run-to-completion. Base your design on short-terms
> events fed to the state machine, which triggers work and reacts to
> changes in forms of other events.
> In your case, one possibility would be to have the state machine
> delegate (post) some work upon state entry or transition action to a
> thread, then posting a new task upon state exit, etc.
> Make your state machine be serviced by only one thread, triggering
> work and reacting to events. Trust me on that one, having a state
> machine serviced by 2 threads is a good receipt for headaches ;-)
> If you know boost::asio, it's a bit like the async_xxx methods,
> trigger some work and get ready for the next action (which would be a
> callback, to continue with this asio example).
That helped me alot doing it that way. Thank you! It was a struggle
before I realized how to call a process_event(...) from within a member
function. I hope I am doing it the right way :-)
I also tried adding
boost::signals2::signal<void ()> sig;
to the statemachine but my compiler did not like that at all
(noncopyable errors). So I stayed with a mutex and a condition variable.
The way I did it can be improved I am sure...
Anyway, you can see an outline below of how I did this. Perhaps this is
an ok way doing it?
struct player_ : ...
//I choose to start the thread in the ctor...
template <class EVT,class FSM,class SourceState,class TargetState>
void operator()(EVT const& ,FSM& fsm,SourceState& ,TargetState& )
std::cout << "starting to play song "<< current_name_ <<std::endl;
//triggers the thread to leave its waiting state
//NextSong event is generated in the playing_thread
Row < Playing , NextSong , Playing , play_song , exists_next >,
Row < Playing , NextSong , Stopped , stop_playing , no_more_songs >,
Row < Playing , Stop , Stopped , stop_playing >,
// Pick a back-end
typedef msm::back::state_machine<player_> player;
trigger_ = true;
trigger_ = false;
//Simulate playing song...
//The state machine can now react to other events like Stop()
//This is how you post a process_event from a member function.
// note: the "player" here is not the same as "player_" !!
// this "player" is the typedef choosen back-end name.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk