You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Boost.MSM子状态机中访问外层状态机的上下文?

Boost.MSM内部状态机访问外层上下文的实现方案

核心解决思路

Boost.MSM的内部状态机可以通过外层状态机的引用直接访问上下文,关键是利用状态回调(如on_entry/on_exit)或动作函数中的SM&参数——这个参数实际指向包含该内部状态机的外层状态机实例,通过它就能获取外层的上下文对象。

具体实现方式

1. 直接通过外层状态机引用访问上下文

在内部状态机的回调或动作中,使用传入的SM&参数直接访问外层状态机的m_component成员:

struct ComponentStateMachine_ : public msm::front::state_machine_def<ComponentStateMachine_>
{
 public:
  TrajectoryManagerComponent* m_component;

  void link_component(hyro::guidance::TrajectoryManagerComponent* component) { m_component = component; }

  struct Operating_ : public msm::front::state_machine_def<Operating_>
  {
     template <typename Event, typename SM>
     void on_entry(Event const&, SM& outer_fsm)
     {
       if (outer_fsm.m_component)
       {
           // 直接调用组件方法
           outer_fsm.m_component->invoke_your_method();
           m_logger->info("Accessing component, address: {}", outer_fsm.m_component);
       }
     }

     // 子状态中同样适用
     struct SubState1 : public msm::front::state<>
     {
         template <typename Event, typename SM>
         void on_entry(Event const&, SM& outer_fsm)
         {
             outer_fsm.m_component->another_method();
         }
     };
  };
};

2. 确保上下文提前初始化

外层状态机的link_component方法必须在状态机启动前调用,保证m_component不为空:

// 实例化外层状态机并绑定上下文
ComponentStateMachine outer_fsm;
outer_fsm.link_component(&your_trajectory_component_instance);
outer_fsm.start();

3. 可选:封装上下文访问接口(提升封装性)

如果不想直接暴露外层状态机的成员变量,可以在外层状态机中封装一个获取上下文的方法:

struct ComponentStateMachine_ : public msm::front::state_machine_def<ComponentStateMachine_>
{
 public:
  TrajectoryManagerComponent* m_component;

  void link_component(hyro::guidance::TrajectoryManagerComponent* component) { m_component = component; }

  // 封装上下文获取接口
  TrajectoryManagerComponent* get_component() const { return m_component; }

  struct Operating_ : public msm::front::state_machine_def<Operating_>
  {
     template <typename Event, typename SM>
     void on_entry(Event const&, SM& outer_fsm)
     {
         auto component = outer_fsm.get_component();
         if (component)
         {
             component->invoke_your_method();
         }
     }
  };
};

不推荐的替代方案

若上述方式不适用,也可以将TrajectoryManagerComponent设为全局变量或单例,但这种方式会大幅降低代码的可测试性和可维护性,仅适合极端场景使用。

内容的提问来源于stack exchange,提问作者Daniel Andrade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:11:13