[FSM] request for tips on fsm code project.

Hello, I am currently trying to develop a project using the Boost::FSM library. I really hope that it will be accepted in Boost. This is not a review or vote (that will come after ;) ). I need some practical tips on how to realize the design that I have in mind. I have experience in State Machine coding, but until now I have used some ad-hoc coding following the Gamma et al examples. I find boost::fsm library really interesting and clean. But, back to my request. I need to handle the states of a process. The process will be implemented in a class containing all required methods and data. Think for example to sensor management. Init (connect the device). Setup (configuration). Idle (nop). AcquireSingleData, AcquireMultiData ... etc. I need a unique instance of the sensor object. How can I make all the states aware of this unique instance? Avoiding singletons ... if possible. Is there some way in boost::fsm to automatically realize this design? I know, this is more a C++ design question, but I think that it is a common problem in FSM coding anyway. Thanks for all your suggestions. andrea -- View this message in context: http://www.nabble.com/-FSM--request-for-tips-on-fsm-code-project.-tp19146253... Sent from the Boost - Dev mailing list archive at Nabble.com.

andrea carbone wrote:
Hello,
I need to handle the states of a process. The process will be implemented in a class containing all required methods and data. Think for example to sensor management. Init (connect the device). Setup (configuration). Idle (nop). AcquireSingleData, AcquireMultiData ... etc.
I need a unique instance of the sensor object.
How can I make all the states aware of this unique instance? Avoiding singletons ... if possible.
Is there some way in boost::fsm to automatically realize this design?
No, the library does not provide any way to control instancing of FSM or other objects, if that is what you mean. However, if you already have a singleton of your object that represents the sensor, you can pass a reference or pointer to it in an initialization event to the FSM. struct Sensor : noncopyable { // Returns the singleton instance static Sensor* get(); private: Sensor(); }; struct InitEvent { Sensor* pSensor; }; typedef mpl::vector< Uninitialized, Init, Setup, ...
::type States_t;
// The struct contains common data for all states struct Common { Sensor* m_pSensor; }; struct Uninitialized : fsm::state< Uninitialized, States_t >, virtual Common { void on_process(InitEvent const& evt) { m_pSensor = evt.pSensor; switch_to< Init >(); } }; ... fsm::state_machine< States_t > fsm; fsm.process(InitEvent(Sensor::get())); Alternatively, you can set the pointer directly in the FSM by using the "get" method of the state machine. fsm.get< Common >().m_pSensor = Sensor::get(); But I would prefer the former way since it expresses the intent more clearly. Note that the pointer to the sensor is stored in a virtual base class of all states, which means that every state uses the single m_pSensor pointer. I hope that helps.

Dear Andrey, yes this is what I have in mind. I will apply for the virtual base solution. I will do some test .... but ..I have a doubt: does it need to be a singleton instance? Or a plain pointer to an object instance will do the trick as well? Thanks for your answer! And good luck for the review!! andrea Andrey Semashev-2 wrote:
andrea carbone wrote:
Hello,
I need to handle the states of a process. The process will be implemented in a class containing all required methods and data. Think for example to sensor management. Init (connect the device). Setup (configuration). Idle (nop). AcquireSingleData, AcquireMultiData ... etc.
I need a unique instance of the sensor object.
How can I make all the states aware of this unique instance? Avoiding singletons ... if possible.
Is there some way in boost::fsm to automatically realize this design?
No, the library does not provide any way to control instancing of FSM or other objects, if that is what you mean. However, if you already have a singleton of your object that represents the sensor, you can pass a reference or pointer to it in an initialization event to the FSM.
struct Sensor : noncopyable { // Returns the singleton instance static Sensor* get();
private: Sensor(); };
struct InitEvent { Sensor* pSensor; };
typedef mpl::vector< Uninitialized, Init, Setup, ...
::type States_t;
// The struct contains common data for all states struct Common { Sensor* m_pSensor; };
struct Uninitialized : fsm::state< Uninitialized, States_t >, virtual Common { void on_process(InitEvent const& evt) { m_pSensor = evt.pSensor; switch_to< Init >(); } };
...
fsm::state_machine< States_t > fsm; fsm.process(InitEvent(Sensor::get()));
Alternatively, you can set the pointer directly in the FSM by using the "get" method of the state machine.
fsm.get< Common >().m_pSensor = Sensor::get();
But I would prefer the former way since it expresses the intent more clearly.
Note that the pointer to the sensor is stored in a virtual base class of all states, which means that every state uses the single m_pSensor pointer.
I hope that helps. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- View this message in context: http://www.nabble.com/-FSM--request-for-tips-on-fsm-code-project.-tp19146253... Sent from the Boost - Dev mailing list archive at Nabble.com.

andrea carbone wrote:
Dear Andrey, yes this is what I have in mind. I will apply for the virtual base solution.
I will do some test .... but ..I have a doubt: does it need to be a singleton instance? Or a plain pointer to an object instance will do the trick as well?
It depends on what you want to achieve. If the FSM models some kind of session and there can be multiple sessions attached to a single sensor, then, obviously, the FSM should not be a singleton. If the FSM models the sensor itself, then it should be a singleton as well. However, in the latter case I would made the sensor a member of the FSM.
participants (2)
-
andrea carbone
-
Andrey Semashev