던져

2014-02-20 2 views
0
내가 부스트 : 상태 차트를 상속하는 상태 머신을 구현 한

. 내가 fsm.process_event(some_event())를 호출 할 때 반응은 그것이 내가 시도 - 캐치와 예외를 처리 한 후 fsm이 종료 내 상태 기 인스턴스를 차단하는 것이 밝혀 예외를 던질 것으로 예상된다. 즉 fsm.terminated() 반환 true이다. 어떤 경우에는 해지되기를 원하지 않습니다. 나는 상태 기 비 처리 이벤트에 대한 fsm.process_event(irrelevant_event())의 호출을 통보하고 현재 이전 이벤트 상태를 유지하기 위해 예외를 throw 할 때처럼. 나는 그것이 예외가 발생 전에 예외 상태의 유지 후 종료에서 boost::statechart을 방지 할 수있는 방법 -던져

한마디로

?

예제 코드 :

namespace sc = boost::statechart; 
class State; 
struct some_event : public sc::event<some_event> { }; 

class FSM 
    : public sc::state_machine< FSM, State, std::allocator<void>, sc::exception_translator<> > 
{ 
public: 
    FSM() 
    { 
     cout<<"FSM::FSM()"<<endl; 
    } 
    virtual ~FSM() 
    { 
     cout<<"FSM::~FSM()"<<endl; 
    } 
}; 


class State : public sc::simple_state< State, FSM > 
{ 
public: 
    State() 
    { 
     cout<<"State::State()"<<endl; 
    } 
    virtual ~State() 
    { 
     cout<<"State::~State()"<<endl; 
    } 

    typedef boost::mpl::list< 
     sc::custom_reaction<some_event>, 
     sc::custom_reaction<sc::exception_thrown> 
    > reactions; 
    sc::result react(const some_event & e) 
    { 
     cout<<"State::react(const some_event &)"<<endl; 
     throw std::exception(); 
     return this->discard_event(); 
    } 
    sc::result react(const sc::exception_thrown & e) 
    { 
     cout<<"State::react(const sc::exception_thrown &)"<<endl; 
     throw; 
     return this->discard_event(); 
    } 
}; 

int main() 
{ 
    FSM fsm; 
    fsm.initiate(); 

    try 
    { 
     fsm.process_event(some_event()); 
    } 
    catch(...) 
    { 
     cout<<"Exception caught"<<endl; 
    } 


    if(fsm.terminated()) 
    { 
     cout<<"fsm2 is TERMINATED"<<endl; 
    } 
    else 
    { 
     cout<<"fsm2 is RUNNING"<<endl; 
    } 
    return 0; 
} 

코드 출력 :

FSM::FSM() 
State::State() 
State::react(const some_event &) 
State::react(const sc::exception_thrown &) 
State::~State() 
Exception caught 
fsm2 is TERMINATED 

나는 출력을 원하는 :

FSM::FSM() 
State::State() 
State::react(const some_event &) 
State::react(const sc::exception_thrown &) 
State::~State() 
Exception caught 
fsm2 is RUNNING 

답변

0

당신은 당신의 상태 머신에 사용자 정의 예외 처리기를 제공해야합니다. 여기에 boost 문서를 참고하십시오 : http://www.boost.org/doc/libs/1_55_0/libs/statechart/doc/tutorial.html#ExceptionHandling

예외 처리의 기본 동작이 sm을 종료하는 이유 인 예외가 throw 될 때 상태 기계가 여전히 유효한 상태인지 알 수는 없습니다. 사용자 지정 처리기는 sm이 유효한 상태에 있는지 확인하고 다른 매너에 정보를 위쪽으로 전파하도록 정리/검사를 수행 할 수 있습니다.

는 개인적으로 나는 예외에 의해 SM에서 정보를 전파하는 좋은 이유를 본 적이 없다. 이것은 아마도 당신의 특정 영역에서 일한 적이 없기 때문에 가능합니다. 그러나 덜 합리적입니다.

이벤트가 관련이 없으면 무시하거나 기록하십시오.이 동일한 이벤트는 다른 상태와 관련이있을 수 있습니다. 현재의 것이 아닙니다. 이벤트가 유효하지 않은 경우, 즉이 발생하거나 중 잘못된 상태를 가지고 못했던이 중 하나입니다

  • 코드에 문제가 당신이 주장 즉시
  • 문제 이상에서 유효하지 않은 입력에 문제를 처리한다 SM을 포함하는 모듈 (하드웨어가 연속적으로 3 개의 연결이 끊긴 이벤트를 게시 한 경우 등) 이 경우에는 로컬 모듈에서 예외를 적절하게 처리 할 수 ​​없으며 가장 좋은 방법은 문제를 기록하고 CatastrophicErrorState 또는 EvReset 등으로 남겨 둘 수있는 항목으로 전환하는 것입니다.