2009-06-26 136 views
1

任何想法如何解决这个问题? ubuntu上8.10瓦特/克++ 4.3.2帮助Boost.Statechart错误

在下面的状态图用1.39_0

,短语 “BUGGY” 打印3 次。人们会期望这个事件只会触发一个“BUGGY”。在 我正在处理的项目的情况下,我不能返回 discard_event(),因为我需要事件达到多个状态(通常在正交状态集合中深度为 )。如果有一种解决方法可以应用 而不是修改状态图,我想知道。

$猫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 & & ./a.out
BUGGY
BUGGY
BUGGY

编辑::

这是一个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
CHILD反应
BUGGY
BUGGY

回答

1

移动你想要的反应直至top状态的子状态。这使其脱离forward_state事件的行。我没有实现它作为一个内部类型,但你可以。

#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; 
} 

~$g++ test.cpp -I Downloads/boost_1_45_0
~$./a.out
CHILD反应
家长反应

0

人们期望的事件只会触发 一个 “BUGGY”。

我不会说实话。您指定三个正交状态,在外部状态上定义一个react()。据我了解(*),你有三个最内在的状态,只要你继续前进,所有三个都将被处理。

那些每三个没有反应,所以它去寻找一个外状态的反应,并找到一个在top,并调用它,然后根据结果是forward任意选择下一个尚未访问最内层的状态,对此同样适用。

我无法回报discard_event()作为我 需要的情况下,达到多 状态(通常为深度在正交 组状态)。

但这正是你在这里实现的目标。你说你想要达到多个状态,但是你不想让这些状态的反应()发生?说实话没有多大意义。

很难提供建议,因为您显然不想尝试打印“越野车”一次,您究竟想要达到什么目的?

(*)备案,我只有与state_machine起到一点点,当它是新的,从未使用过它的生产代码,所以我不是在所有的专家

+0

我想TOP向evSay反应。我希望其他国家也能够对evSay做出反应。但我不希望每个孩子都继承Top对evSay的反应。你会注意到我的代码没有对c1,c2或c3中的evSay做出反应。 – KitsuneYMG 2009-06-26 14:53:54