【问题标题】:How to dynamically create state machine如何动态创建状态机
【发布时间】:2016-06-09 13:10:24
【问题描述】:

我还不知道如何使用 boost msm 动态创建 FSM,例如读取描述机器的模板 XML 文件。知道如何解决这个问题吗?我想在 boost msm 1.61 中使用仿函数方法。

我已经取得了一些进展,我可以用常见的方式为前端创建一个基类:

class SMBase : public msmf::state_machine_def<SMBase>
{
 ...
};
using SMBaseBackend = msm::back::state_machine<SMBase>;

class SMDerived : public SMBase
{
 ...
};
using SMDerivedBackend = msm::back::state_machine<SMDerived>;


class SMDerived2 : public SMBase
{
 ...
};
using SMDerived2Backend = msm::back::state_machine<SMDerived2>;

但是,状态机本身是由后端控制的,到目前为止,我看不到在运行时选择后者(例如使用

map<int, smart_pointer<SMBaseBackend> >

)。

【问题讨论】:

    标签: c++ dynamically-generated boost-msm


    【解决方案1】:

    Boost.MSM 不支持动态创建状态机结构。 MSM 是 Meta State Machine,而 Meta 在此上下文中表示编译时间。所以所有状态机结构都是在编译时构建的。您可以在以下文档中了解 Boost.MSM 采用这种方法的原因: http://www.boost.org/doc/libs/1_61_0/libs/msm/doc/HTML/pr01.html

    第二段“另一个状态机库?有什么用?”描述了动态状态机结构创建的缺点。

    您可能想知道替代方案。

    Boost.Statechart 都不支持。以下文档描述了原因:

    http://www.boost.org/doc/libs/1_61_0/libs/statechart/doc/rationale.html#DynamicConfigurability

    根据文档,Boost.Statechart 支持非常有限的动态配置。文档说“但是,这并不意味着不可能动态地塑造使用这个库实现的机器。例如,可以使用守卫来根据仅在运行时可用的输入进行不同的转换。”

    但是,有一个状态机库支持动态状态机创建。 Qt 的 QStateMachine 就是它。见http://doc.qt.io/qt-5/statemachine-api.html

    【讨论】:

    • 非常感谢您的回复——我担心 msm 可能不适合这项任务。但是,QT 不是一个选择(开销太大,尤其是在嵌入式系统方面)。
    • 基本上,在我的情况下,我可以减少使用某些预定义模板的灵活性(w.r.t 动态创建)。有鉴于此,我可以创建一个抽象的基本状态机类并从中派生模板,例如使用简单的映射来处理它们。这应该会很好。再次感谢,回答除外!
    • 是的,您可以使用 Boost.MSM 定义带有一些自定义点的预定义状态机。您可以将值传递给状态机,并且在事件处理期间,您可以动态评估警卫和操作中的值。它提供了某种灵活性。
    【解决方案2】:

    有一种解决方法,它适用于不需要在运行时从许多状态机中进行选择的设置:

    定义一个包含父状态机并在子机上实现其他状态机。然后在运行时级别上,可以通过使用父状态机的转换表并调用相应的 process_event (respective_event()),“跳入”相应的子机。

    效果很好,只有 current_state 现在才返回父级状态。

    【讨论】:

      猜你喜欢
      • 2022-08-14
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      • 1970-01-01
      • 2021-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多