gpt4 book ai didi

c++ - boost msm中的错误处理错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:32:31 26 4
gpt4 key购买 nike

我有一个简单的状态机,它接收 3 种类型的消息,并根据消息类型发送相应的响应。在正常情况下,当以正确的顺序收到正确的消息时,我的状态机工作完美。


但在收到意外消息的情况下,no_transition 被调用,它必须触发 error_detected 事件,该事件必须由 normal_workflow 状态处理.但是 no_transition 被调用了 2 次,因为有 2 个正交区域。但我只需要在 normal_workflow 状态下触发 error_detected 事件。那么如何确定no_trasition 中的当前事件状态呢?这是我的代码,

#include <iostream>

#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>

#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/euml/common.hpp>

#include <boost/msm/front/euml/operator.hpp>
#include <boost/msm/front/euml/state_grammar.hpp>

namespace msm = boost::msm;
namespace mpl = boost::mpl;

using namespace msm::front;
using namespace msm::front::euml;

namespace
{
// events
//
struct received_type_1_msg { received_type_1_msg(){ std::cout << "received_type_1_msg" << std::endl; } };

struct received_type_2_msg { received_type_2_msg(){ std::cout << "received_type_2_msg" << std::endl; } };

struct received_type_3_msg { received_type_3_msg(){ std::cout << "received_type_3_msg" << std::endl; } };

struct err_detected { err_detected(){ std::cout << "err_detected" << std::endl; } };

// front end
//
struct test_sm_ : public msm::front::state_machine_def<test_sm_>
{
// states
//
struct idle : public msm::front::state<>
{
template <class event,class fsm>
void on_entry(event const& evt,fsm& sm)
{
std::cout << "idle" << std::endl;
}
};

struct wait_type_2_msg : public msm::front::state<>
{
template <class event,class fsm>
void on_entry(event const& evt,fsm& sm)
{
std::cout << "wait_type_1_msg"<< std::endl;
}
};

struct wait_type_3_msg : public msm::front::state<>
{
template <class event,class fsm>
void on_entry(event const& evt,fsm& sm)
{
std::cout << "wait_type_3_msg"<< std::endl;
}
};

struct normal_workflow : public msm::front::state<>
{
template <class event,class fsm>
void on_entry(event const& evt,fsm& sm)
{
std::cout << "normal_workflow"<< std::endl;
}
};

// initial state
//
typedef mpl::vector2<idle, normal_workflow> initial_state;

// transition actions
//
struct send_type_1_rsp
{
template<class event, class fsm, class src_state, class dst_state>
void operator()(event const& evt, fsm&, src_state&, dst_state&)
{
std::cout << "send_type_1_rsp"<< std::endl;
}
};

struct send_type_2_rsp
{
template<class event, class fsm, class src_state, class dst_state>
void operator()(event const& evt, fsm&, src_state&, dst_state&)
{
std::cout << "send_type_2_rsp"<< std::endl;
}
};

struct send_type_3_rsp
{
template<class event, class fsm, class src_state, class dst_state>
void operator()(event const& evt, fsm&, src_state&, dst_state&)
{
std::cout << "send_type_3_rsp"<< std::endl;
}
};

struct send_error_rsp
{
template<class event, class fsm, class src_state, class dst_state>
void operator()(event const& evt, fsm&, src_state&, dst_state&)
{
std::cout << "send_error_rsp"<< std::endl;
}
};

struct transition_table : mpl::vector<

// Start Event Next Action Guard
// +---------------------------+-------------------------------+---------------------------+------------------------------+--------+
Row < idle , received_type_1_msg , wait_type_2_msg , send_type_1_rsp , none >,
Row < wait_type_2_msg , received_type_2_msg , wait_type_3_msg , send_type_2_rsp , none >,
Row < wait_type_3_msg , received_type_3_msg , idle , send_type_3_rsp , none >,
// +---------------------------+-------------------------------+---------------------------+------------------------------+--------+
Row < normal_workflow , err_detected , idle , send_error_rsp , none >
// +---------------------------+-------------------------------+---------------------------+------------------------------+--------+
>{};

// no transition
//
template <class fsm,class event>
void no_transition(event const& e, fsm& sm,int state)
{
std::cout << "no transition" << std::endl;
//sm.process_event(err_detected());
}
};

typedef msm::back::state_machine<test_sm_> test_sm;
}

int main(int argc, char** argv)
{
test_sm sm;
sm.start();

sm.process_event(received_type_1_msg());
sm.process_event(received_type_2_msg());

// wrong message received
//
sm.process_event(received_type_2_msg());

return 0;
}

一种解决方案是通过使用传递给 no_transition 的状态参数。还有其他解决办法吗?因为这样的东西看起来不太好:

template <class fsm,class event>
void no_transition(event const& e, fsm& sm,int state)
{
// without this condition err_detected event will fired twise, because sm have 2 regions
//
if(state == 3)
{
// call this event only in NORMAL_WORKFLOW state, because it handled within this state
//
sm.process_event(err_detected());
}
}

最佳答案

嗯,恕我直言,正交区域的使用很好。但是,错误处理事件仍然需要您自己触发。 no_transition是MSM出错时唯一的函数。所以,我正在按照与您相同的方式进行操作。

关于c++ - boost msm中的错误处理错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10349030/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com