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));
}
감사합니다. 나는 합리적으로 그 부분을 놓쳤다. – odinthenerd