gpt4 book ai didi

c++ - 在 boost::msm 中的子 SM 之间跳转

转载 作者:行者123 更新时间:2023-11-30 05:41:58 31 4
gpt4 key购买 nike

我的主 SM 中有两个子 SM。我希望能够从主 SM 跳入任何一个,但也可以从一个子 SM 跳入另一个 SM。但我不能。我可以从主 SM 跳转到子 SM,也可以从 一个 子 SM 跳到另一个,但是当我在子 SM 之间添加“相互”转换时,编译失败并显示 ~10错误提示不同的事情。我想那是因为编译器进入了递归循环。

我想我可以在主 SM 中添加一个虚拟状态,并匿名转换到目标子 SM。但随后我会丢失触发转换的真实事件,而我不希望这样(它包含数据)。

下面是一些测试代码,其中有问题的行被注释掉了

#include <iostream>

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

namespace {

using namespace boost::msm;
using namespace boost::msm::front;
namespace mpl = boost::mpl;

struct EvGotoSub1 {};
struct EvGotoSub2 {};

struct MainSM_;
using Main = back::state_machine<MainSM_>;
struct Sub1SM_;
using Sub1 = back::state_machine<Sub1SM_>;
struct Sub2SM_;
using Sub2 = back::state_machine<Sub2SM_>;

struct Sub1SM_ : state_machine_def<Sub1SM_> {
struct Started : state<> { };
using initial_state = mpl::vector<Started>;
struct transition_table:mpl::vector<
Row<Started, EvGotoSub2, Sub2, none, none>
> {};
};

struct Sub2SM_ : state_machine_def<Sub2SM_> {
struct Started : state<> { };
using initial_state = mpl::vector<Started>;
struct transition_table:mpl::vector<
// Uncomment line below to break things
//Row<Started, EvGotoSub1, Sub1, none, none>
> {};
};

struct MainSM_ : state_machine_def<MainSM_> {
struct Started : state<> { };
using initial_state = mpl::vector<Started>;
struct transition_table:mpl::vector<
Row<Started, EvGotoSub1, Sub1, none, none>,
Row<Started, EvGotoSub2, Sub2, none, none>
> {};
};
}

int main() {

Main main;
main.start();
main.process_event(EvGotoSub1());
main.process_event(EvGotoSub2());
main.process_event(EvGotoSub1());
}

最佳答案

我假设您不想将 Sub2 嵌套在 Sub1 中,反之亦然,但两者都是 Main 的子机器,无需任何嵌套。您可以使用 pseudo exit states 从一台子机退出并转到另一台.

这些退出状态只是转发传入的事件,然后您可以通过在 Main 的转换表中定义额外的转换将其传递给其他子机:

#include <iostream>

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

namespace {

using namespace boost::msm;
using namespace boost::msm::front;
namespace mpl = boost::mpl;

struct EvGotoSub1 { EvGotoSub1(int d1):d1(d1){} int d1;};
struct EvGotoSub2 { EvGotoSub2(int d2):d2(d2){} int d2;};

struct MainSM_;
using Main = back::state_machine<MainSM_>;
struct Sub1SM_;
using Sub1 = back::state_machine<Sub1SM_>;
struct Sub2SM_;
using Sub2 = back::state_machine<Sub2SM_>;

struct Sub1SM_ : state_machine_def<Sub1SM_> {
struct Started : state<> { template <class Event,class Fsm> void on_entry(const Event& e, Fsm&) const { std::cout << "SUB2SM_ Started::on_entry(): d1="<<e.d1 << std::endl; } };
struct Exit : exit_pseudo_state<EvGotoSub2> {};
using initial_state = mpl::vector<Started>;
struct transition_table:mpl::vector<
Row<Started, EvGotoSub2, Exit, none, none>
> {};
};

struct Sub2SM_ : state_machine_def<Sub2SM_> {
struct Started : state<> { template <class Event,class Fsm> void on_entry(const Event& e, Fsm&) const { std::cout << "SUB2SM_ Started::on_entry(): d2="<<e.d2 << std::endl; } };
struct Exit : exit_pseudo_state<EvGotoSub1> {};
using initial_state = mpl::vector<Started>;
struct transition_table:mpl::vector<
Row<Started, EvGotoSub1, Exit, none, none>
> {};
};

struct MainSM_ : state_machine_def<MainSM_> {
struct Started : state<> { };
using initial_state = mpl::vector<Started>;
struct transition_table:mpl::vector<
Row<Started, EvGotoSub1, Sub1, none, none>,
Row<Started, EvGotoSub2, Sub2, none, none>,
Row<Sub2::exit_pt<Sub2SM_::Exit>, EvGotoSub1, Sub1, none, none>,
Row<Sub1::exit_pt<Sub1SM_::Exit>, EvGotoSub2, Sub2, none, none>
> {};
};
}


int main() {

Main main;
main.start();
main.process_event(EvGotoSub1(0));
main.process_event(EvGotoSub2(1));
main.process_event(EvGotoSub1(2));
}

实例:http://coliru.stacked-crooked.com/a/d491442b38a24e82

可以看到,事件没有丢失而是转发了。

可以在 http://redboltz.wikidot.com/exit-point-pseudo-state 找到有关伪退出状态的良好资源。 .

关于c++ - 在 boost::msm 中的子 SM 之间跳转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30914719/

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