boost::fsm, parameters to DestinationState
Hi, when doing a transition using transit<myDestinationState>, I would like to pass some parameters to myDestination. Problem is, those parameter-values will not be known at compile time, so I can't just pass them in as template-parameters to myDestinationState. Of course I could just set some global (or static member member) variable and read that from myDestinationState's constructor but this doesn't feel like a very clean design. Any suggestions? Jan Eickmann
Hi Jan
when doing a transition using transit<myDestinationState>, I would like to pass some parameters to myDestination.
What is the ctor of myDestination going to do with them? Where do these arguments come from? What did you do with them in the react function?
Problem is, those parameter-values will not be known at compile time, so I can't just pass them in as template-parameters to myDestinationState. Of course I could just set some global (or static member member) variable and read that from myDestinationState's constructor but this doesn't feel like a very clean design.
Any suggestions?
There are various ways: Have a variable in an outer state, have one in the FSM, use a transition action or avoid the problem altogether. What exactly the best one is really depends on the source of your problem. Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.
Andreas Huber wrote:
Hi Jan
when doing a transition using transit<myDestinationState>, I would like to pass some parameters to myDestination.
What is the ctor of myDestination going to do with them? Where do these arguments come from? What did you do with them in the react function?
Problem is, those parameter-values will not be known at compile time, so I can't just pass them in as template-parameters to myDestinationState. Of course I could just set some global (or static member member) variable and read that from myDestinationState's constructor but this doesn't feel like a very clean design.
Any suggestions?
There are various ways: Have a variable in an outer state, have one in the FSM, use a transition action or avoid the problem altogether. What exactly the best one is really depends on the source of your problem.
Regards, Andreas Huber
Thanks for the help so far, I'll try to give some more information. In the application we are developing, we have a screen that is kind of like an encyclopedia. This screen is usually shown after the user presses a "more information" button in a popup dialog, etc. That encyclopedia-screen is the state I want to transit to. Now what I want to do is tell that screen what entry to show. In order to be able to get back to the original state, I put the "normal" GUI of the application in a state that has a deep-history. So the common outer state would basicly be the FSM but I would rather avoid having a variable there as this would require changing the FSM itself everytime I want to add a similar screen that gets told from the outside what to do exactly. I currently don't really see how I can avoid the problem altogether... Regards, Jan Eickmann
Jan Eickmann
I'll try to give some more information. In the application we are developing, we have a screen that is kind of like an encyclopedia. This screen is usually shown after the user presses a "more information" button in a popup dialog, etc. That encyclopedia-screen is the state I want to transit to. Now what I want to do is tell that screen what entry to show. In order to be able to get back to the original state, I put the "normal" GUI of the application in a state that has a deep-history.
So the common outer state would basicly be the FSM but I would rather avoid having a variable there as this would require changing the FSM itself everytime I want to add a similar screen that gets told from the outside what to do exactly.
Hmmm, I not sure whether I already have enough information to help but you might consider posting an event containing the necessary information before making the transition. Of course, this does not help you accessing the information from the ctor of the state but the reaction that follows can then access this info, as follows: // untested struct EvButtonClicked : fsm::event< EvButtonClicked > {}; struct EvEntryInfo : fsm::event< EvEntryInfo > { // Whatever you need to send goes here }; struct Init; struct Application : fsm::state_machine< Application, Init > {}; struct ShowEntry : fsm::simple_state< ShowEntry, Application > { fsm::result react( const EvEntryInfo & info ) { /* display info here */ } }; struct Init : fsm::simple_state< Init, Application, fsm::custom_reaction< EvButtonClicked > > { fsm::result react( const EvButtonClicked & ) { post_event( boost::intrusive_ptr( new EvEntryInfo() ) ); return transit< ShowEntry >(); } }; I assume that you have a good reason not to use a GUI framework, which I expect to be better suited to implement the functionality you need than a general FSM framework. HTH & Regards, Andreas
Andreas Huber wrote:
Jan Eickmann
writes: I'll try to give some more information. In the application we are developing, we have a screen that is kind of like an encyclopedia. This screen is usually shown after the user presses a "more information" button in a popup dialog, etc. That encyclopedia-screen is the state I want to transit to. Now what I want to do is tell that screen what entry to show. In order to be able to get back to the original state, I put the "normal" GUI of the application in a state that has a deep-history.
So the common outer state would basicly be the FSM but I would rather avoid having a variable there as this would require changing the FSM itself everytime I want to add a similar screen that gets told from the outside what to do exactly.
Hmmm, I not sure whether I already have enough information to help but you might consider posting an event containing the necessary information before making the transition. Of course, this does not help you accessing the information from the ctor of the state but the reaction that follows can then access this info, as follows:
// untested struct EvButtonClicked : fsm::event< EvButtonClicked > {};
struct EvEntryInfo : fsm::event< EvEntryInfo > { // Whatever you need to send goes here };
struct Init; struct Application : fsm::state_machine< Application, Init > {};
struct ShowEntry : fsm::simple_state< ShowEntry, Application > { fsm::result react( const EvEntryInfo & info ) { /* display info here */ } };
struct Init : fsm::simple_state< Init, Application, fsm::custom_reaction< EvButtonClicked > > { fsm::result react( const EvButtonClicked & ) { post_event( boost::intrusive_ptr( new EvEntryInfo() ) ); return transit< ShowEntry >(); } };
I assume that you have a good reason not to use a GUI framework, which I expect to be better suited to implement the functionality you need than a general FSM framework.
HTH & Regards,
Andreas
Thanks for the hint. I think the posting of a second event sounds like a good idea. The reason I'm not using a "normal" GUI framework is that this is integrated into a 3D-Engine and the Framework we are using for the GUI doesn't have all the features you would expect of something like MFC or GTK. Greetings, Rincewind
Andreas Huber wrote:
struct ShowEntry : fsm::simple_state< ShowEntry, Application > { fsm::result react( const EvEntryInfo & info ) { /* display info here */ } };
This is of course nonsense, there must also be a reaction, as follows: struct ShowEntry : fsm::simple_state< ShowEntry, Application, fsm::custom_reaction< EvEntryInfo > > { fsm::result react( const EvEntryInfo & info ) { /* display info here */ } }; But I'm sure you got the idea... Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.
Andreas Huber wrote:
Andreas Huber wrote:
struct ShowEntry : fsm::simple_state< ShowEntry, Application > { fsm::result react( const EvEntryInfo & info ) { /* display info here */ } };
This is of course nonsense, there must also be a reaction, as follows:
struct ShowEntry : fsm::simple_state< ShowEntry, Application, fsm::custom_reaction< EvEntryInfo > > { fsm::result react( const EvEntryInfo & info ) { /* display info here */ } };
But I'm sure you got the idea...
Regards,
:-), yes I got the idea. Thanks again, Jan Eickmann
participants (2)
-
Andreas Huber
-
Jan Eickmann