boost [msm] deferring event by base type.

I try to use the following code struct base {}; struct event1 : public base {}; struct MyState1 : public msm::front::state<> { typedef mpl::vector<base> deferred_events; }; than MySm.process_event(event1()); when state machine in MyState1 causes that event gets dispatched and not deferred the same code works if I replace typedef mpl::vector<base> deferred_events; with typedef mpl::vector<event1> deferred_events; than it works fine and event1 is deferred in MyState1; It would be nice to able to defer event by it's base types it would make code maintenance easier not have to declare all events one by one for deferring. Br. Richie

On 24.6.2010 22:02, Richard Szabo wrote:
It would be nice to able to defer event by it's base types it would make code maintenance easier not have to declare all events one by one for deferring.
Did you try activating deferred events and adding a 'Defer' row in the transition table like described here http://tinyurl.com/36sp4a8 I think this will allow deferral by base type.

On 24 June 2010 22:46, Juraj Ivančić <juraj.ivancic@gmail.com> wrote:
On 24.6.2010 22:02, Richard Szabo wrote:
It would be nice to able to defer event by it's base types it would make code maintenance easier not have to declare all events one by one for deferring.
Did you try activating deferred events and adding a 'Defer' row in the transition table like described here
No I did not try I will. Thanks for the tipp.
I think this will allow deferral by base type.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 24 June 2010 22:56, Richard Szabo <sz.richard@googlemail.com> wrote:
On 24 June 2010 22:46, Juraj Ivančić <juraj.ivancic@gmail.com> wrote:
On 24.6.2010 22:02, Richard Szabo wrote:
It would be nice to able to defer event by it's base types it would make code maintenance easier not have to declare all events one by one for deferring.
Did you try activating deferred events and adding a 'Defer' row in the transition table like described here
No I did not try I will.
I'm now using Row and Defer functor I have now an other problem whit the : void defer_event(Event const& e) { // to call this function, you need either a state with a deferred_events typedef // or that the fsm provides the activate_deferred_events typedef BOOST_MPL_ASSERT(( has_fsm_deferred_events<library_sm> )); execute_return (library_sm::*pf) (Event const& evt)= &library_sm::process_event; Event temp (e); ::boost::function<execute_return () > f= ::boost::bind(pf, this,temp); post_deferred_event(f); } actually it tries to instantiate the base class ( Event temp (e); ) but in my case the base class is an abstract class -> compiler error; and after deferring I want to dispatch the original derived event not the copy constructed base class instance of the event.
Thanks for the tipp.
I think this will allow deferral by base type.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 25.6.2010 10:40, Richard Szabo wrote:
I'm now using Row and Defer functor I have now an other problem whit the :
void defer_event(Event const& e) { // to call this function, you need either a state with a deferred_events typedef // or that the fsm provides the activate_deferred_events typedef BOOST_MPL_ASSERT(( has_fsm_deferred_events<library_sm> )); execute_return (library_sm::*pf) (Event const& evt)= &library_sm::process_event; Event temp (e); ::boost::function<execute_return ()> f= ::boost::bind(pf, this,temp); post_deferred_event(f); }
actually it tries to instantiate the base class ( Event temp (e); ) but in my case the base class is an abstract class -> compiler error; and after deferring I want to dispatch the original derived event not the copy constructed base class instance of the event.
You might try the following: Instead of making your event class polymorphic, you add a shared pointer to polymorphic data. E.g. struct deferred_event { boost::shared_ptr<deferred_event_data_base> event_data; }; This would solve both issues as you would have a single event to be deferred, and it would be copyable but would still retain polymorphic data needed to process event. HTH

On 25 June 2010 12:59, Juraj Ivančić <juraj.ivancic@gmail.com> wrote:
On 25.6.2010 10:40, Richard Szabo wrote:
I'm now using Row and Defer functor I have now an other problem whit the :
void defer_event(Event const& e) { // to call this function, you need either a state with a deferred_events typedef // or that the fsm provides the activate_deferred_events typedef BOOST_MPL_ASSERT(( has_fsm_deferred_events<library_sm> )); execute_return (library_sm::*pf) (Event const& evt)= &library_sm::process_event; Event temp (e); ::boost::function<execute_return ()> f= ::boost::bind(pf, this,temp); post_deferred_event(f); }
actually it tries to instantiate the base class ( Event temp (e); ) but in my case the base class is an abstract class -> compiler error; and after deferring I want to dispatch the original derived event not the copy constructed base class instance of the event.
You might try the following:
Instead of making your event class polymorphic, you add a shared pointer to polymorphic data. E.g.
struct deferred_event { boost::shared_ptr<deferred_event_data_base> event_data; };
I don't understand how this would help me with the differing based on base type ? Can you please provide a little example based on something like this ? struct BaseEvent { virtual ~BaseEvent() = 0; }; BaseEvent::~BaseEvent() {} struct AEvent : public BaseEvent { }; struct BEvent : public BaseEvent { }; will not compile : Row < State1, BaseEvent, none, Defer, none > you suggesting : struct deferred_event { boost::shared_ptr<BaseEvent> event_data; }; now as soon as I assign AEvent to sharedPointer to BaseEvent I loose the event type and I have to use static cast to actually get back the AEvent. and I don't see how deferred_event would fit together with other rows which are using AEvent of BEvent ? I think he only think it would solve is avoiding the copy of even_data during event queuing. And gives us problems with deletion if the object is created by a factory and removed by a recycle. because you can create the shared pointer like this : boost::shared_ptr<AEvent> mySPtrAEvent(myFactory::factory<AEvent>()); when there is a static factory method exist and returning a pointer to the AEvent for event creation. but how you call instead of delete whit shared pointers something like myFactory::recycle(pAEevent) ? thanks for your help !!!. Br. Richie
This would solve both issues as you would have a single event to be deferred, and it would be copyable but would still retain polymorphic data needed to process event.
HTH
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (2)
-
Juraj Ivančić
-
Richard Szabo