[msm] extending msm::back::state_machine

Hi, I tried to enhance the backend of boost::msm by inheriting from boost::msm::back::state_machine. When doing so, I cannot access members of my subclass in the states. When compiling the attached example, I get this error message: *error: ‘class boost::msm::back::state_machine<fsm_, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_>’ has no member named ‘test’* How can I "inject" extended_back_machine as the type being passed as "FSM" to the state? Bye Manuel #################################### template<typename FrontMachine> struct extended_back_machine : public boost::msm::back::state_machine<FrontMachine> { void test() { std::cout << "test" << std::endl; } }; struct fsm_ : public boost::msm::front::state_machine_def<fsm_> { struct State : public boost::msm::front::state<> { template <class Event,class FSM> void on_entry(Event const&, FSM& fsm) { fsm.test(); } }; typedef State initial_state; }; int main() { typedef extended_back_machine<fsm_> fsm; fsm m; m.start(); return 0; } ####################################

Hi,
When compiling the attached example, I get this error message error: ‘class boost::msm::back::state_machine<fsm_, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_>’ has no member named ‘test’
How can I "inject" extended_back_machine as the type being passed as "FSM" to the state?
The argument passed to on_entry is not extended_back_machine because MSM does not know about it. You can either: - implement test() within the fsm_ front-end - provide a virtual, empty implemented test() within the front end and let the compiler find out itself about the overriden one: virtual void test(){} HTH, Christophe

Hi Christophe, thanks for the reply. The reason I want to extend the backend is that I need to maintain a separate event queue (a job queue). In reality, "test()" is a function template, so I cannot use virtual functions. If I implement this function template in the frontend, I need to static_cast to the backend, which I try to avoid: struct fsm_ : public boost::msm::front::state_machine_def<fsm_> { typedef msmb::state_machine<fsm_> BackMachine; template <typename EventType> void enqueue_job(const EventType& evt) { job_queue.push( std::bind(&BackMachine::template process_event<EventType>, static_cast<BackMachine*>(this), evt) ); } // ... }; Is there any third option? Bye, Manuel 2014-09-07 21:42 GMT+02:00 <christophe.j.henry@googlemail.com>:
Hi,
When compiling the attached example, I get this error message
*>error: ‘class boost::msm::back::state_machine<fsm_, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_, boost::parameter::void_>’ has no member named ‘test’*
How can I "inject" extended_back_machine as the type being passed as
"FSM" to the state? The argument passed to on_entry is not extended_back_machine because MSM does not know about it. You can either:
- implement test() within the fsm_ front-end - provide a virtual, empty implemented test() within the front end and let the compiler find out itself about the overriden one: virtual void test(){}
HTH, Christophe
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Hi Manuel,
The reason I want to extend the backend is that I need to maintain a separate event queue (a job queue).
In reality, "test()" is a function template, so I cannot use virtual functions.
If I implement this function template in the frontend, I need to static_cast to the backend, which I try to avoid struct fsm_ : public boost::msm::front::state_machine_def<fsm_> {
typedef msmb::state_machine<fsm_> BackMachine;
template <typename EventType> void enqueue_job(const EventType& evt) { job_queue.push( std::bind(&BackMachine::template process_event<EventType>, static_cast<BackMachine*>(this), evt) ); }
};
Is there any third option?
Unfortunately not in the general case. But in your use case, maybe. There is already in state_machine<> an enqueue_event() and an execute_queued_events(). Could this help? HTH, Christophe
participants (3)
-
christophe.j.henry@gmail.com
-
christophe.j.henry@googlemail.com
-
Manuel Schiller