我可以使用boost.statecharts自定义对不同正交reigions中的多个状态的事件做出反应吗?

时间:2013-03-07 14:31:09

标签: c++ boost state-machine boost-statechart

我的用例与此SSCCE类似。问题在于,如果没有发生转变,我需要转发看似不自然的事件,以便由其他正交区域处理。更重要的是,虽然在我需要转换的情况下,我找不到允许事件在其他地区作出反应的方法。我应该如何重组以解决这个问题?

我正在使用boost 1.53,以防这很重要。

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 个答案:

答案 0 :(得分:1)

这个问题是图书馆作者的answered。 他的意思是Event dispatch to orthogonal regions