2009-06-26 4 views
1

이 문제를 해결하는 방법에 대한 아이디어가 있으십니까? 다음에 상태 차트/g ++ 4.3.2Boost.Statechart 버그에 대한 도움말

와트 우분투 8.10 1.39_0를 사용

는 문구 "버" 세 번 출력된다. 이벤트가 단지 하나의 "BUGGY"를 유발할 것이라고 기대할 수 있습니다. 내가 작업하고있는 프로젝트의 경우 여러 개의 상태에 도달하기 위해 이벤트가 필요하므로 discard_event()를 반환 할 수 없습니다. 일반적으로 직각 좌표 집합의 입니다. 상태 차트를 수정하는 대신 을 적용 할 수있는 해결 방법이 있으면 알려드립니다.
BUGGY이
BUGGY

편집이 ::

이것은 $ 고양이 bug.cpp

#include <boost/intrusive_ptr.hpp> 
#include <boost/mpl/list.hpp> #include <boost/statechart/custom_reaction.hpp> 
#include <boost/statechart/event.hpp> 
#include <boost/statechart/simple_state.hpp> 
#include <boost/statechart/state.hpp> 
#include <boost/statechart/state_machine.hpp> 
#include <iostream> 

using namespace std; 
namespace sc = boost::statechart; 
namespace mpl = boost::mpl; 

struct evSay : sc::event<evSay>{ }; 
struct top; 
struct c1; 
struct c2; 
struct c3; 
struct sm : public sc::state_machine<sm,top> { }; 

struct top : sc::simple_state<top,sm,mpl::list<c1,c2,c3> > { 
     typedef sc::custom_reaction<evSay> reactions; 
     sc::result react(const evSay &) { 
       cout<<"BUGGY"<<endl; 
       return forward_event(); 
     } 
}; 

struct c1 : sc::simple_state <c1, top::orthogonal<0> > { }; 

struct c2 : sc::simple_state <c2, top::orthogonal<1> > { }; 

struct c3 : sc::state <c3, top::orthogonal<2> > { 
     c3(my_context ctx) : my_base(ctx) { 
       post_event(boost::intrusive_ptr<evSay> (
           new evSay())); 
     } 
}; 

int main() { 
     sm* fsm = new sm(); 
     fsm->initiate(); 
     delete fsm; 
     return 0; 
} 

$ g ++ bug.cpp & &
BUGGY ./a.out

내 문제가 더 커진 내 문제를 보여주는 예제 Statemachine 에. 나는 그 최고가 evSay를 전달할 것이라는 것을 안다. c1, c2, c3은 evSay에 반응하지 않습니다. 여기에 전달이 필요하므로 두 국가가 evSay에 반응 할 수있는 예가 있습니다.

#include <boost/intrusive_ptr.hpp>  
#include <boost/mpl/list.hpp>  
#include <boost/statechart/custom_reaction.hpp> 
#include <boost/statechart/event.hpp> 
#include <boost/statechart/simple_state.hpp> 
#include <boost/statechart/state.hpp> 
#include <boost/statechart/state_machine.hpp>  
#include <iostream> 
using namespace std; 
namespace sc = boost::statechart; 
namespace mpl = boost::mpl; 
namespace BUG { 
struct evSay : sc::event<evSay>{ }; 
struct top;struct c1;struct c2;struct c3;struct c2_1; 

struct sm : public sc::state_machine<sm,top> { }; 

struct top : sc::simple_state<top,sm,mpl::list<c1,c2,c3> > { 
    typedef sc::simple_state<top,sm,mpl::list<c1,c2,c3> > my_type; 
    typedef sc::custom_reaction<evSay> reactions; 
    sc::result react(const evSay &) { 
     cout<<"BUGGY"<<endl; 
     return forward_event(); 
    } 
}; 

struct c1 : sc::simple_state <c1, top::orthogonal<0> > { }; 
struct c2 : sc::simple_state <c2, top::orthogonal<1>, c2_1 > { }; 
struct c3 : sc::state <c3, top::orthogonal<2> > { 
    c3(my_context ctx) : my_base(ctx) { 
     post_event(boost::intrusive_ptr<evSay> (
       new evSay())); 
    } 
}; 

struct c2_1 : sc::simple_state<c2_1, c2 > { 
    typedef sc::custom_reaction<evSay> reactions; 
    sc::result react(const evSay &) { 
     cout<<"CHILD REACTION"<<endl; 
     return forward_event(); 
    } 
}; 
} 

int main() 
{ 
    BUG::sm* fsm = new BUG::sm(); 
    fsm->initiate(); 
    delete fsm; 
    return 0; 
} 

출력 : BUGGY
아동 REACTION
BUGGY
BUGGY 경우 것 만 트리거 한 "버기"기대

답변

1

에서 아니에요 state_machine로 조금을했다 top 상태의 하위 상태가됩니다. 이 이벤트는 forward_state 이벤트의 행에서 제외됩니다. 나는 그것을 내부 형으로 구현하지는 않았지만, 가능했다.

~$g++ test.cpp -I Downloads/boost_1_45_0
~$./a.out

#include <boost/intrusive_ptr.hpp>  
#include <boost/mpl/list.hpp>  
#include <boost/statechart/custom_reaction.hpp> 
#include <boost/statechart/event.hpp> 
#include <boost/statechart/simple_state.hpp> 
#include <boost/statechart/state.hpp> 
#include <boost/statechart/state_machine.hpp>  
#include <iostream> 
using namespace std; 
namespace sc = boost::statechart; 
namespace mpl = boost::mpl; 


struct evSay : sc::event<evSay>{ }; 

struct top;struct c1;struct c2;struct c3;struct c2_1;struct sub_1; 

struct sm : public sc::state_machine<sm,top> { }; 

struct top : sc::simple_state<top,sm, mpl::list<c1,c2,c3, sub_1> > { }; 

struct sub_1 : sc::simple_state<sub_1, top::orthogonal<3> > { 
    typedef sc::custom_reaction<evSay> reactions; 
    sc::result react(const evSay &) { 
     cout<<"PARENT REACTION"<<endl; 
     return forward_event(); 
    } 
}; 

struct c1 : sc::simple_state <c1, top::orthogonal<0> > { }; 
struct c2 : sc::simple_state <c2, top::orthogonal<1>, c2_1 > { }; 
struct c3 : sc::simple_state <c3, top::orthogonal<2> > { }; 

struct c2_1 : sc::simple_state<c2_1, c2 > { 
    typedef sc::custom_reaction<evSay> reactions; 
    sc::result react(const evSay &) { 
     cout<<"CHILD REACTION"<<endl; 
     return forward_event(); 
    } 
}; 

int main() 
{ 
    sm* fsm = new sm(); 
    fsm->initiate(); 
    fsm->process_event( evSay() ); 
    delete fsm; 
    return 0; 
} 
아동 반응
부모의 반응은

0

하나.

나는 솔직하지 않습니다. 외부 상태로 정의 된 react()으로 3 개의 직교 상태를 지정합니다. 내가 이해하면 (*) 당신은 세 개의 가장 안쪽에있는 주를 가지고 있습니다, 당신이 그 사건을 계속 전진한다면, 세 가지 모두 처리 될 것입니다.

각각 3 개는 반응이 없으므로 외부 상태에서 반응을 찾고 top에서 반응을 찾고 결과를 호출하면 forward은 아직 방문하지 않은 다음을 선택합니다 가장 안쪽에있는 국가.

나는 (미국의 직교 세트에 일반적으로 깊이) 여러 상태에 도달하는 이벤트를 필요 로 discard_event()를 반환 할 수 없습니다.

하지만 여기서 정확히 달성 한 내용입니다. 당신은 여러 주에 도착하고 싶다고 말하고 있지만, 그 주들의 react()는 해고되기를 원하지 않습니까? 그것은 솔직히 말해서별로 의미가 없습니다.

"버기 (buggy)"를 한 번만 인쇄하려고하지 않으므로 조언을하기가 어렵습니다. 정확히 달성하려는 것은 무엇입니까?

이 새로운 때

(*)가 기록을 위해, 난 단지 당신이 원하는 반응을 이동 프로덕션 코드에 그것을 사용하지, 그래서 나는 모든 전문가

+0

나는 TOP이 evSay에 반응합니다. 나는 다른 주에서도 evSay에 반응하는 능력을 원한다. 그러나 나는 각 어린이가 진화에 대한 탑의 반응을 이어 받도록하고 싶지 않습니다. 내 코드가 c1, c2 또는 c3에서 evSay에 대한 반응이 없음을 알 수 있습니다. – KitsuneYMG

+0

그래서 당신은 기본적으로 당신이 evSay를 전달한다고 말하고 있지만 정말로 전달하지는 않습니까? 당신은 버리거나 그 포워드가 다음 라인으로 실제로 전달 될 것임을 받아들입니다. – Pieter

+0

편집을 참조하십시오. 이벤트 (evSay)를 반응하지 않는 상태 (c1, c2, c3)로 전달하면 부모의 반응이 발생해야하는 이유는 무엇이라고 생각하십니까? 응답을받지 못한 이벤트가 시스템을 백업하는 경우 BUGGY 인쇄를 4 번하지 않아야합니까? (상단에는 하나, 반응이없는 아이들은 각각 3 명씩) – KitsuneYMG

관련 문제