Can I custom react to a event in multiple states in different orthogonal reigions using boost.statecharts?

1k Views Asked by At

My use case is similar to this SSCCE. The problem is that if no transition occurs I need to forward the events, which seems unnatural, for them to be processed by the other orthogonal regions. More importantly though in the case I need to transition I can't find a way to allow the event to be reacted to in other regions. How should I restructure to work around this?

I am using boost 1.53 in case this is important.

namespace sc = boost::statechart;
struct Active;
struct Keyboard : sc::state_machine< Keyboard, Active > {};

struct NumLockOff;
struct CapsLockOff;
struct ScrollLockOff;
struct Active: sc::simple_state< Active, Keyboard, boost::mpl::list< NumLockOff, CapsLockOff, ScrollLockOff > > {};

struct EvNumLockPressed : sc::event< EvNumLockPressed > {};
struct EvCapsLockPressed : sc::event< EvCapsLockPressed > {};
struct EvScrollLockPressed : sc::event< EvScrollLockPressed > {};
struct EvAllLocksOffPressed : sc::event< EvAllLocksOffPressed > {
    int i_;
    EvAllLocksOffPressed(int i):sc::event< EvAllLocksOffPressed >(),i_(i){}
};

struct NumLockOn : sc::simple_state< NumLockOn, Active::orthogonal< 0 > >
{
    typedef boost::mpl::list<sc::transition< EvNumLockPressed, NumLockOff >, sc::custom_reaction<EvAllLocksOffPressed>> reactions;
    sc::result react( const EvAllLocksOffPressed & e)
    {
        if(e.i_ == 42)
            return transit< NumLockOff >();
        return forward_event();
    }
};

struct NumLockOff : sc::simple_state< NumLockOff, Active::orthogonal< 0 > >
{
    typedef sc::transition< EvNumLockPressed, NumLockOn > reactions;
};

struct CapsLockOn : sc::simple_state< CapsLockOn, Active::orthogonal< 1 > >
{
    typedef boost::mpl::list<sc::transition< EvCapsLockPressed, CapsLockOff >, sc::custom_reaction<EvAllLocksOffPressed>> reactions;
    sc::result react( const EvAllLocksOffPressed & e)
    {
        if(e.i_ == 42)
            return transit< CapsLockOff >();
        return forward_event();
    }
};

struct CapsLockOff : sc::simple_state< CapsLockOff, Active::orthogonal< 1 > >
{
    typedef sc::transition< EvCapsLockPressed, CapsLockOn > reactions;
};

struct ScrollLockOn : sc::simple_state< ScrollLockOn, Active::orthogonal< 2 > >
{
    typedef boost::mpl::list<sc::transition< EvScrollLockPressed, ScrollLockOff >, sc::custom_reaction<EvAllLocksOffPressed>> reactions;
    sc::result react( const EvAllLocksOffPressed & e)
    {
        if(e.i_ == 42)
            return transit< ScrollLockOff >();
        return forward_event();
    }
};

struct ScrollLockOff : sc::simple_state< ScrollLockOff, Active::orthogonal< 2 > >
{
    typedef sc::transition< EvScrollLockPressed, ScrollLockOn > reactions; 
};

int main(){
    Keyboard k;
    k.initiate();
    k.process_event(EvNumLockPressed());
    k.process_event(EvCapsLockPressed());
    k.process_event(EvScrollLockPressed());
    k.process_event(EvAllLocksOffPressed(1));
    k.process_event(EvAllLocksOffPressed(42));
}
1

There are 1 best solutions below

1
On BEST ANSWER

This question was answered by the library author. The reference he meant is Event dispatch to orthogonal regions.