Question

I'd like to define a base class, derived from statechart::simple_state, which has "predefined" reactions which themselves call virtual functions (which have to be implemented in the deriving classes). What I'd like to have is that some states automatically react to certain events if they derive from my base class.

Like this (sc is boost::statechart):

struct EvHeartBeat : sc::event<EvHeartBeat> {};

template< class MostDerived,
      class Context,
      class InnerInitial = boost::mpl::list<>,
      sc::history_mode historyMode = sc::has_no_history >
class BaseState : public sc::simple_state<
    MostDerived, Context, InnerInitial, historyMode >
{
public:
    typedef sc::custom_reaction<EvHeartBeat> reactions;

    sc::result react (const EvHeartBeat& )
    {
        // maybe check some conditions here ...
        return react_heartbeat();
    }

protected:
    virtual sc::result react_heartbeat() = 0;
};

Then, in the deriving class:

struct MyState :
    BaseState<MyState, MyChart>
{

   // there are also other reactions
   typedef sc::custom_reaction<OtherEvent> reactions;

    sc::result react_heartbeat()
    {       
        std::cout << "foo" << std::endl;       
    }

    sc::result react (const OtherEvent&) { /* ... */ }

};

The typedef in the derived class will "overwrite" the one in the base class I assume, so maybe I need to define a custon_reaction to the heart beat event as a list in the derived class as well. But maybe this design is not like the designers of this library thought it should be, anyone who can help me out with that?

EDIT

In the meantime I gained some additional knowledge. A workaround for the typedef would be to just define it in the derived class instead of the base class. But then, a strange problem occurs: The compiler will not find a method for react (const EvHeartBeat& ) although it's defined in the base class, if I remove the other reaction (react (const OtherEvent& )) it works. But of course that is not what I want, I want to be able to react to multiple events.

Was it helpful?

Solution

I asked this also on the boost-users ml and got an answer which helped a lot. The problem is, that the method definition in the subclass shaddows the definition in the parent class although the parameter list differs (OtherEvent vs. EvHeartBeat). The solution is to explicitly re-use the method from the super class:

using BaseState::react;

result react ( const OtherEvent& );

This one works like it should.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top