Pau*_*ulH 5 c++ boost state-machine boost-msm
我正在使用新的Boost 1.44.0 MSM库来生成状态机.在这个状态机中有两类事件class1和class2.class1事件可以由任一状态进行处理S1或S2同时class2事件只能通过状态进行处理S2.
特殊class1事件upgrade_req请求从州S1到州的升级S2.
我在Boost :: MSM中实现了如下:
// State S1 and S2 allow any class1 events
struct class1 {};
// Only state S2 allows class2 events
struct class2 {};
// an upgrade request is a class1 event that requests an upgrade to state 2
struct upgrade_req : public class1 {};
struct MyFSM : public msm::front::state_machine_def< MyFSM >
{
/// State 1. Allows any class1 event
struct S1 : public msm::front::state<>
{
/// functor says "processing event in State 1"
struct ProcessEvent { /* ... */ };
struct internal_transition_table : mpl::vector<
// Event Action Guard
// +-------+-------------+------------+
Internal< class1, ProcessEvent, none >
> {};
}; // S1
/// State 2. Allows any class1 or class2 events
struct S2 : public msm::front::state<>
{
/// functor says "processing event in State 2"
struct ProcessEvent { /* ... */ };
struct internal_transition_table : mpl::vector<
// Event Action Guard
// +-------+-------------+------------+
Internal< class1, ProcessEvent, none >,
Internal< class2, ProcessEvent, none >
> {};
}; // S2
/// everybody starts in state 1
typedef S1 initial_state;
/// send an error if a class2 event was received for state1
struct SendError { /* ... */ };
/// Send a response to the upgrade request
struct SendUpgradeRsp { /* ... */ };
/// functor returns true if the request to upgrade to state 2 is OK.
struct VerifyUpgradeReq { /* ... */ };
struct transition_table : mpl::vector<
// Start Event Next Action Guard
// +------+-------------+------+----------------+------------------+
Row< S1, class1, none, none, none,
Row< S1, class2, S1, SendError, none >,
Row< S1, upgrade_req, S2, SendUpgradRsp, VerifyUpgradeReq >,
Row< S2, class1, none, none, none,
Row< S2, class2, none, none, none >
> {};
}; // MyFSM
Run Code Online (Sandbox Code Playgroud)
我的问题是,当我按原样使用它时,upgrade_req事件永远不会被主要处理MyFSM::transition_table.它只由处理S1::internal_transition_table.
例如:
int main( int argc, char* argv[] )
{
msm::back::state_machine< MyFSM > sm;
sm.start();
sm.process_event( class1() );
sm.process_event( upgrade_req() );
sm.process_event( class2() );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望这个输出是:
处理事件状态1.
升级请求确定.
在州2处理事件.
但是,我得到的是:
处理事件的状态1.
处理事件的状态1.
错误.在州1收到2级活动.
有人建议如何解决这个问题吗?
谢谢,PaulH
您的问题是内部转换的优先级高于转换表中定义的优先级.并且update_req是class1,内部转换器会触发.这实际上符合UML标准.MSM为您提供了第二个解决方案,您可以使用Row来定义S1的内部转换,其中none作为目标在transition_table内,而不是使用internal_transition_table.如果您在转换S1 + upgrade_reg - > S2之前定义它,它将具有较小的prio并且仅在不能考虑另一个时才会尝试.
如果你绝对需要internal_transition_table,那么你只能提供一个后卫来拒绝class1,如果它不是update_req.
HTH,Christophe Henry
PS:我只是靠运气找到这篇文章.发布到提升用户列表将保证您更快的答案.
| 归档时间: |
|
| 查看次数: |
1969 次 |
| 最近记录: |