2013-03-07 4 views
0

본 사용 사례는이 SSCCE와 유사합니다. 문제는 전환이 발생하지 않으면 다른 직교 영역에서 처리하기 위해 부자연스러워 보이는 이벤트를 전달해야한다는 것입니다. 더 중요한 것은 전환해야 할 경우 이벤트가 다른 지역에 대응할 수있는 방법을 찾을 수 없다는 것입니다. 이 문제를 해결하려면 어떻게 구조 조정해야합니까?boost.statecharts를 사용하여 직교 좌표가 다른 여러 상태의 이벤트에 사용자 정의 반응을 할 수 있습니까?

부스트 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)); 
} 

답변